我最近修改了我的Django项目的设置,因为它在我运行测试而不是PostgreSQL时使用SQLite3,这样我的测试运行得更快。但是,一旦我这样做,我的一个负面单元测试检查验证Django如果我尝试创建一个用户名超过30个字符的用户就会失败。直到这个时候,测试一直都过去了。
如果我使用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 :(得分:1)
除了Zuko的答案之外,我还会质疑你的单元测试可能没有做正确的事情。
模型验证在保存之前发生似乎是一种常见的误解。请参阅Model validation的文档。
您正在做的是期望您的模型字段的max_length
参数得到兑现,而无需通过验证功能。当您使用ModelForms
时,表单将确保调用模型验证,您将获得ValidationError
。
这同样适用于其他约束,例如is_blank
类型的CharField
选项。据我所知,此验证只能在Python域中进行,因为没有可用的约束,您可以在数据库级别应用以检查字段是否为空。
StackOverflow上有很多其他问题与此问题相关,这将解释您如何在所有情况下强制进行验证,例如this answer
另外,让您的单元测试调用full_clean()
实例方法来检查是否已满足所有验证约束。
答案 1 :(得分: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
如您所见,没有错误,也没有截断。
希望有所帮助,