I have a django app and I am running some unit tests on it. So the problem I am having is not when one test inserts into the test db. It is the tests that come after. Since each test is not saving the transaction, the entry from a previous test is not there which is fine, although the auto increment id's are increasing as if there are still entries into the database. Which I need to fix because I am inserting more data where I cannot control the id's given to it and need to be able to grab this specific data for the test. If I hard code the code to grab the objects I will have to change the code for every time I add a new test, which is not ideal.
I have multiple tests running, but for simplicity sake, I will show two.
from django.test import TestCase
from app.models import Model
class VersionMerge(TestCase):
fixtures = ['initial_test_data.json']
def test_model_test1(self):
*Insert new data*
*grab new data in*
*Check data*
def test_model_test2(self):
*Insert new data*
*grab new data*
*Check data*
The problem arises in test_model_test2 where when I try to grab the new data, I have to print the object out to see the id's to be able to grab it.
I have a solution on how I can fix this on the actual database but not the test one. For mine I need to be able to connect to a docker container and run a psql command to reset the table_id_seq.
docker exec -t $CONTAINER_ID psql --dbname=test_database_name -username=user -c "SELECT setval('modelName_appName_id_seq', 2, true)"
This will go to the table and set the last id value used to be 2 to make the next id 3. However whenever I try to run the command from inside python using
cmd = "command above"
os.system(cmd)
and when I run this I get the following error.
sh: 1: docker: not found
sh: 1: docker: not found
Looking for any help on this, either a new solution to the problem or improvements on mine.
TLDR; I need to be able to modify data in the database that the django unit tests create.
If you need a test to reset the primary key sequence, you can issue a RawSQL query doing that. How to do that exactly is answered in this StackOverflow question.
An easier option is available if you're using pytest. We're using pytest and pytest-django in all our Django projects and it makes testing a breeze. pytest-django provdes a database fixture that can take a boolean parameter to reset the sequences. Use it like so:
@pytest.mark.django_db(transaction=True, reset_sequences=True)
def mytest():
[...]
I got this to work by replacing TestCase
with TransactionTestCase and set reset_sequences=True
. However the tests are running slower.
from django.test import TransactionTestCase
class ViewTest(TransactionTestCase):
reset_sequences = True
def test_view_redirects(self):
...
Here's the doc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With