I have a Django (v1.4, using Postgresql) project which I've written a bunch of working unittests for. These use FactoryBoy to generate most of their data.
I'm now starting to write some integration tests using LiveServerTestCase with Selenium. I've just realised that my tests and the live test server use different databases. Which means that data created by factories in my tests aren't available to Selenium.
I'm not sure of the best way to progress. I think I could use fixtures to supply data that would work, although this is a pain having got this far using factories instead.
Is there a way I can continue to use factories to generate data that will work for my Selenium tests? Really I'd like my tests and LiveServerTestCase to use the same database.
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 fromTransactionTestCase
instead ofTestCase
, 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 ofLiveServerTestCase
withTestCase
, 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 theLiveServerThread
because they're inside the same transaction. However this comes with some caveats: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 enteredTestCase
code that we shouldn't have done), we were able to fix the inheritance hierarchy to avoid pulling inTestCase
, 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.
Have you tried using sqlite as your database backend for tests?
from Django docs
If you're not using anything beyond regular ORM, you might benefit from test speedups as well.