Django testing: How to get a database with ONLY fixture data and no IntegrityErrors (by diagnosing the source of errors)?
-
29-10-2019 - |
Question
I'm trying to run tests with fixture data, and getting the infamous IntegrityError: column user_id is not unique
error.
Now, looking at my fixtures, I can see that the ids of my User models in my fixture are unique between each other. I infer that the clash is with existing data in (non-test) database. Is this correct? (Edit: This appears to be incorrect - see below)
I want to be able to control exactly what data are available to my tests. Is there a way to prevent the django testrunner from loading data from my live database, as well as my fixture data? (Edit: Yes - see Thibaut's answer).
Edit: Switching to using a clean, in memory database, as per Thibaut's answer does not fix the problem. Accordingly, I infer that my existing dev database is not the problem.
So, I have a third question: How do I diagnose the cause of an IntegrityError when loading fixtures during testing? (And, how do I fix it?)
Edit 2: The solution for my problem, in addition to starting with a clean database (per Thibault J) was also to eliminate models from installed apps referring to User, until the error no longer occurs.
DrTyrsa's other suggestion (than looking at the data), was to use natural keys, which for User would no doubt have required a certain amount of monkey-patching or other hackery (edit the code for User?).
Solution
Use a different database for prod and tests (good practice). In settings.py
:
if 'test' in sys.argv:
try:
from test_settings import *
except ImportError:
pass
In test_settings.py
:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'memory://testdb',
}
}