Django testing with django-pytest

Pfff. Just finished writing mere 3 tests, and took me a long time. As usual, it’s probably a good idea to read the docs carefully. I didn’t and it bit my shiny hiny badly.

This is about “Testing Transaction” of Django pytest. Quote “Django itself has the TransactionTestCase which allows you to test transactions and will flush the database between tests to isolate them.”

I wrote a small test fixture that creates a few records. However, as each test runs within single transaction, subsequent query against database does not return the records created by the fixture function. For example, as you create a user, and the post-save creates one-to-one user profile, quering the user against database in normal operation does work but not for the test, as the User records have not been commited to the database yet. This puzzled me like a day. First, I checked that the database connection is right, the database is working, etc. After checking this, it became clear that the test is running in a transaction, and I had to commit for the fixtures to be on the database so my tests can query.

As a Django and pytest noob, this took me a day to get to a meaningful google question, and I hit this blog titled “Transaction tests in Pytest”. I finally saw a magic keyword “transaction=True” in the db test marker, and went back to the doc.

“Testing Transactions” is right under “Enabling Database Access in Tests so I should not have missed, but I glanced over and didn’t realize what it meant.

My excuse was that, when I was writing the test, I did something funky and the fixture setup was running before the test transaction in place. After I refactored the test files around, the feature kicked in, and made me really confused. So, this was my stupidity, and this is what I learned today.