Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django unittest read-only test databases

I must be missing the obvious here. I am using django 1.5.x and am creating unittests, based on djangos TestCase class. I have a bunch of DBs defined in settings as i am pulling (read-only) from alot of different source. When running test i only want to create a test version of my default db the rest i want to flag as read-only and not try to recreate as test_db_name (the user defined won't (can't) have the permissions to create these dbs anyway).

Surely this is possible - as i say i must be missing the obvious?

Grateful for any help.

Mathew

like image 770
Mathew Avatar asked Jun 05 '14 09:06

Mathew


People also ask

Is Pytest better than Unittest?

Which is better – pytest or unittest? Although both the frameworks are great for performing testing in python, pytest is easier to work with. The code in pytest is simple, compact, and efficient. For unittest, we will have to import modules, create a class and define the testing functions within that class.

What is RequestFactory in Django?

The request factory The RequestFactory shares the same API as the test client. However, instead of behaving like a browser, the RequestFactory provides a way to generate a request instance that can be used as the first argument to any view.

How do you write unit test cases in Django?

To write a test you derive from any of the Django (or unittest) test base classes (SimpleTestCase, TransactionTestCase, TestCase, LiveServerTestCase) and then write separate methods to check that specific functionality works as expected (tests use "assert" methods to test that expressions result in True or False values ...

What is self client in Django?

self. client , is the built-in Django test client. This isn't a real browser, and doesn't even make real requests. It just constructs a Django HttpRequest object and passes it through the request/response process - middleware, URL resolver, view, template - and returns whatever Django produces.


2 Answers

Not obvious, no. Sort-of documented, you can set the database name to use whilst testing:

settings.py

DATABASES = {
  'default': {
    'ENGINE': 'django.contrib.gis.db.backends.spatialite',
    'NAME': 'db.sqlite3',
    'TEST_NAME': '/tmp/test.sqlite3',
  },
}

If you want to then not build (or rebuild) the test database, you'll need to duplicate the database name into TEST_NAME and use the new python manage.py test --keepdb command to leave the database intact, rather than having Django try to delete it between runs. As of June 2014 you have to upgrade to the development version of Django to access this; eventually this will be in the stable release. The downside of this is, as I understand it, it applies to all databases, not just your read-only ones.

like image 151
Josh Avatar answered Oct 06 '22 17:10

Josh


I had the same problem and managed to solve it like this:

settings.py

DATABASES = {
    'default': {...},
    'other': {...}
}

DATABASE_ROUTERS = ['routers.MyRouter']

...

TESTING = 'test' in sys.argv

if TESTING:
    DATABASE_ROUTERS = []
    DATABASES.pop('other')    

If you don't use hard coded db routing such as with 'using' and only use the 'DATABASE_ROUTERS', then this solution should be good enough for you.

Of course, if you want to actually test the connection to the remote DB and the data stored there then this would not be the way to go.

like image 26
odedfos Avatar answered Oct 06 '22 17:10

odedfos