我已经用一个自定义用户模型替换了我的auth.user模型,该模型的用户名是公司的unique_together。为了实现这一点,我手动(通过迁移)从用户表中删除了唯一约束。我想写一个测试来验证它是否按预期工作(在适当的时候返回错误消息等),但我很难理解为什么测试框架的行为不像我预期的那样。以下是我在测试中所做的:
class UserTests(TestCase):
def setUp(self):
self.client = Client()
# Setup: Create users, companies, etc. to use in the test
def test_create_dup_staffuser(self):
cursor = connection.cursor()
try:
cursor.execute("alter table config_user drop index `username`;")
finally:
cursor.close()
# Test code: Create some data, pass it to my 'create user' view,
# verify the results
def test_user_something_else(self):
# Test other things
测试本身是有效的。正如预期的那样,约束被删除了,我的测试通过了,允许我在公司内创建具有重复用户名的用户。问题是,删除约束会阻止我的数据库在下一次测试之前进行刷新,而test_user_something_else一开始就使用test_create_dup_staffuser中剩余的所有数据(我通过注释掉alter表来验证这一点,这使所有内容都可以刷新)。
从进入TestCase开始,我怀疑我的更改以某种方式阻止了测试结束时的事务回滚,但我真的不确定该怎么做或该怎么办。我试图在测试结束时重新设置约束,但得到了相同的结果。我还尝试手动添加tearDown并从数据库中删除所有数据,但这也不起作用。当我在下一次测试的setUp开始时遇到断点时,数据又回来了。
有人能解释一下这里发生了什么,并建议我如何合理地测试这个功能吗?我的下一步可能是打开数据库日志记录,试图弄清楚发生了什么,但除此之外,我没有任何想法。
我已经考虑过的解决方法:
- 使用迁移:我们的迁移很复杂,并且有一些错误。修复/挤压它们在清单上,但还没有
- 返工类:我(现在)可以想出各种方法来更改我的自定义用户类,使其不那么复杂,但这些代码已经在生产和工作中了,所以我现在也不能真正做到这一点
- 升级到django 1.7:它已经在列表中了,但不会进入这个开发周期
- 暂时跳过测试:这是我目前的备份计划
使用django 1.5.8/python 2.7/mysql 5.5
从进入TestCase开始,我怀疑我的更改以某种方式阻止了测试结束时的事务回滚,但我真的不确定如何或该怎么办。
我想就是这样。我建议转到TransactionTestCase
,它不使用事务来重置数据库。
为什么在你的情况下交易会被搞砸?请记住,这些事情一直在变化,这个答案(由用户joefoker给出)表明,您使用的MySQL将更改模式的指令视为"导致隐式提交",这肯定会打乱TestCase
的预期。因此,你的alter table
命令会从TestCase
的脚下"拉开地毯"(可以这么说)。