7👍
Have you tried using sqlite as your database backend for tests?
When using an in-memory SQLite database to run the tests, the same
database connection will be shared by two threads in parallel: the
thread in which the live server is run and the thread in which the
test case is run.
from Django docs
If you’re not using anything beyond regular ORM, you might benefit from test speedups as well.
13👍
I found out why this happened to me, and some possible workarounds, including Ilya Baryshev’s answer above.
If your test descends from Django’s TestCase
, and if your database supports transactions, then each test runs in its own transaction, and nobody outside (no other thread, external process, or other test) can see the objects created in the database by your test.
LiveServerTestCase
uses threads, so it would suffer from this problem. So the designers made it inherit from TransactionTestCase
instead of TestCase
, which disables these transactions, so that changes are globally visible.
What happened to me was that I added some mixins to my test class, and one of them pulled in TestCase
. This doesn’t cause an error, but it silently replaces the base class of LiveServerTestCase
with TestCase
, which enables transactions again, causing the problem that you describe.
Ilya’s SQLite memory database workaround works because Django contains code that detects when using a SQLite :memory:
database that actually shares the same connection between threads, so you see your test’s objects in the LiveServerThread
because they’re inside the same transaction. However this comes with some caveats:
It’s important to prevent simultaneous database queries via this shared connection by the two threads, as that may sometimes randomly cause the tests to fail. So you need to ensure that the two threads don’t access the database at the same time. In particular, this means that in some cases (for example, just after clicking a link or submitting a form), you might need to check that a response is received by Selenium and that the next page is loaded before proceeding with further test execution. Do this, for example, by making Selenium wait until the HTML tag is found in the response (requires Selenium > 2.13)…
https://docs.djangoproject.com/en/1.4/topics/testing/#live-test-server
In my case, once we identifier that autocommit
was being turned off when the test started, and tracked down why (because we had entered TestCase
code that we shouldn’t have done), we were able to fix the inheritance hierarchy to avoid pulling in TestCase
, and then the same database was visible from both the live server thread and the test.
This also works with Postgres databases, so it would provide a solution for velotron.
- Annotate QuerySet with first value of ordered related model
- Why are my environment variables not detected when starting up celery?
- Psycopg2.errors.InsufficientPrivilege: permission denied for relation django_migrations