Reputation: 3588
Recently I updated my django app, which was made with Python 2.7 and Django 1.11, to Python 3 and Django 3.1.
I had several testcases using django.test.TestCase. Several of these tests were made assuming the database would be completely reset between test executions and, among other things, it was expected that the last id for the models would be reset as well, such as that if I create an object on a test and save it to the database, the object would always receive the same id starting from 1.
This behaved exactly like this on Django 1.11, and I was able to use the --keepdb flag to avoid recreating the database everytime.
However after I upgraded to Python 3 and Django 3.1 I noticed this is no longer the case. I noticed that all objects are deleted from the database after the test execution, but on next test executions the new objects are created with pk starting from the last used pk, so I can no longer count with the fact that the created objects will have a predictable pk. This leads to a really annoying behavior that if I run my test just after recreating the db the test will pass, but if I run the test again keeping the db it will not pass because the pks will be different.
If I remove the --keepdb flag when running the tests the pks are all reset, but this makes test execution much slower as my database structure takes a couple of minutes to be created.
Is there an option to reset the pks on each test execution? Was there actually a change on this behavior on Django on a version after 1.11?
Upvotes: 2
Views: 1097
Reputation: 3588
I found an answer to my problem here on StackOverflow: Can Django flush its database(s) between every unit test?
The suggestion is to set:
reset_sequences = True
on the Test class.
On the documentation for reset_sequences there is a warning, though:
Unless you are explicitly testing primary keys sequence numbers, it is
recommended that you do not hard code primary key values in tests.
and also:
Using reset_sequences = True will slow down the test, since the primary key
reset is an relatively expensive database operation.
Upvotes: 4