2013-01-31 10 views
1

我最近修改了我的Django項目的設置,因爲當我運行測試代替PostgreSQL時,它使用SQLite3,以便我的測試運行得更快。但是,一旦我這樣做了,我的一個負面單元測試將檢查以驗證Django將在我嘗試創建用戶名超過30個字符的用戶開始失敗時發出錯誤。直到這個時候,測試總是通過。SQLite3沒有捕捉太長的用戶名

如果我使用PostgreSQL運行以下測試,會引發異常(特別是DatabaseError)並通過測試。但是,如果我使用SQLite3,則不會引發異常,並且測試失敗。我仔細檢查了SQLite3 auth_user模式並確認用戶名是varchar(30)字段。有沒有其他人經歷過這個?謝謝。

from django.test import TestCase 
from django.contrib.auth.models import User 

class SimpleTest(TestCase): 
    def test_simple(self): 
     exception_raised = True # Exception should be raised since username > 30 chars 
     try: 
      user = User.objects.create_user(username='testusertestusertestusertestuser') 
     except Exception as e: 
      exception_raised = False 
     assert not exception_raised, "Exception wasn't raised" 

回答

0

我相信這樣做的原因是sqlite3將所有varchar數據類型轉換爲引擎蓋下的文本數據類型。這就是爲什麼DBMS不會捕獲任何超出限制的值。這方面的文檔有點不清楚,但是我在文檔之前和之後遇到了這個問題,這是我能想到的最好的答案。所以基本上,

CREATE TABLE A(name varchar(30)) 

最終會被等同於:

CREATE TABLE A(name text) 

入住在這裏的文件(2.2節):http://www.sqlite.org/datatype3.html

一個測試,你可以做一看就知道這只是DBMS的功能:

sqlite> create table A(name varchar(2)); 
sqlite> insert into A values("hello world"); 
sqlite> select * from A; 
hello world 

正如你所看到的,沒有錯誤, nd沒有截斷。

希望幫助,

1

除了Zuko的答案,我會質疑你的單元測試也不會做正確的事情。

模型驗證發生在保存之前似乎是一種常見的誤解。請參閱Model validation的文檔。

您正在做的事是期待max_length參數到您的模型領域被尊重而不通過驗證功能。當您使用ModelForms時,表單將確保調用模型驗證,您將獲得ValidationError

同樣適用於其他約束,例如is_blank選項到CharField類型。據我所知,這種驗證只能發生在Python領域,因爲沒有可用的約束條件,您可以在數據庫級應用來檢查字段是否爲空。

有許多的StackOverflow上有關這個這個問題的其他問題,其中解釋了你怎麼可能強制驗證在任何情況下,如this answer

Alternativly,有單元測試調用full_clean()實例方法來檢查所有驗證約束已經滿足。