I started using the factory_boy
package so I've set up some factories and wanted to test that the objects created don't raise any validation errors.
Here's the mixin I'm using that basically takes every factory from a module, creates an instance, then tests that there are no errors from .full_clean()
. The user fixtures that are loaded are 10 instances with IDs 1 to 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))
The mixin would be used like this
from django.test import TestCase
from order import factories
class OrderFactoriesTestCase(FactoriesTestCaseMixin, TestCase):
module = factories
But I keep getting an IntegrityError
(traceback below) after the test successfully passes in regards to fixture teardown and I can't figure out how to get around it so my tests pass with no errors.
If I run the tests for each individual app there are no errors. I never get problems in any of my other model's fixtures that also have a created_by
field.
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".
What I think is happening is that a previous test is creating a new user and the factory boy Iterator
is picking one of the new user IDs.. still not sure why this would cause an error after successfully passing the test.
created_by = factory.Iterator(User.objects.all())
The modules that cause this problem always have a SubFactory
to the ProductFactory
product = factory.SubFactory(ProductFactory)
Any suggestions on how to solve this?
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".