我开始使用factory_boy
包,因此我建立了一些工厂,并希望测试创建的对象不会引发任何验证错误。
这是我正在使用的mixin,它基本上从模块中获取每个工厂,创建一个实例,然后测试.full_clean()
中是否没有错误。已加载的用户夹具是10个实例,其ID为1到10。
class FactoriesTestCaseMixin:
fixtures = [
'user/tests/fixtures/user.json',
]
module = None
def test_factories(self):
err_msg = '{name} caused errors:\n{errors}'
factories = [
(name, obj) for name, obj in inspect.getmembers(self.module, inspect.isclass)
if obj.__module__ == self.module.__name__
and not obj._meta.abstract
]
for factory in factories:
name = factory[0]
instance = factory[1]()
errors = None
try:
instance.full_clean()
except ValidationError as e:
errors = e
self.assertTrue(errors is None, err_msg.format(name=name, errors=errors))
mixin会这样使用
from django.test import TestCase
from order import factories
class OrderFactoriesTestCase(FactoriesTestCaseMixin, TestCase):
module = factories
但是在测试成功通过后,我仍然遇到IntegrityError
(下面的回溯),涉及夹具拆卸问题,我不知道如何解决它,因此我的测试没有错误通过。
如果我为每个单独的应用程序运行测试,则没有错误。我的其他模型的灯具也都存在created_by
字段,我从来没有遇到问题。
django.db.utils.IntegrityError: insert or update on table "product_product" violates foreign key constraint "product_product_created_by_id_96713f93_fk_user_user_id"
DETAIL: Key (created_by_id)=(13) is not present in table "user_user".
我认为正在发生的事情是,先前的测试正在创建一个新用户,而工厂男孩Iterator
正在选择一个新用户ID。.仍然不确定为什么成功通过测试后会导致错误测试。
created_by = factory.Iterator(User.objects.all())
导致此问题的模块始终对ProductFactory
具有SubFactory
product = factory.SubFactory(ProductFactory)
关于如何解决此问题的任何建议?
Traceback (most recent call last):
File "/home/Development/project/venv/lib/python3.7/site-packages/django/test/testcases.py", line 274, in __call__
self._post_teardown()
File "/home/Development/project/venv/lib/python3.7/site-packages/django/test/testcases.py", line 1009, in _post_teardown
self._fixture_teardown()
File "/home/Development/project/venv/lib/python3.7/site-packages/django/test/testcases.py", line 1177, in _fixture_teardown
connections[db_name].check_constraints()
File "/home/Development/project/venv/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 246, in check_constraints
self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
File "/home/Development/project/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/Development/project/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/Development/project/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/Development/project/venv/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/Development/project/venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 82, in _execute
return self.cursor.execute(sql)
django.db.utils.IntegrityError: insert or update on table "product_product" violates foreign key constraint "product_product_created_by_id_96713f93_fk_user_user_id"
DETAIL: Key (created_by_id)=(12) is not present in table "user_user".
答案 0 :(得分:1)
我有一个相关的问题,我通过在我的测试用例类中专门化 _fixture_teardown
解决了这个问题。
_fixture_teardown
在 django.test.testcases
中实现以调用 django 命令“flush”,该命令试图从数据库中删除所有数据。我不知道这对你是否有用。在我保留测试数据库并使用 --keepdb
的场景中,它导致了问题。
因为我不需要(或不想)刷新测试数据库,所以我只是将方法专门化为什么都不做。这解决了我的问题,也可能有助于解决您的问题。