How to run unit test against a production database?

How to run unit test instead of production database instead of test database?

I have an error that appears on my production server, but not on my development computer.

I don't care if the database is erased.

+4
django unit-testing
source share
8 answers

Is it possible to make a copy of the database or part of the database that causes the problem? If you are holding a backup server, you can copy the data instead (make sure you have another backup if you have mixed up the backup database).

Basically, you don’t want to communicate with data in real time, and you don’t want to be left without backup if you ruined something (and you will!).

+3
source share

Short answer: you do not.

Long answer: you do not, you make a copy of the production database and run it there

+1
source share

Use manage.py dumpdata > mydata.json to get a copy of the data from your database.

Go to your local computer, copy mydata.json to a subdirectory of your application called fixtures , for example. myapp/fixtures/mydata.json and execute:

 manage.py syncdb # Set up an empty database manage.py loaddata mydata.json 

Your local database will be populated with data, and you can check it.

+1
source share

Make a copy of the database ... This is a really good practice!

Just do the test, instead commit, rollback the call at the end.

0
source share

The first thing to try is to manually execute the test code on the shell on the production server.

 python manage.py shell 

If this does not work, you may need to upload the production data, copy it locally and use it as a tool for the test used.

If there is a way to ask django to use a standard database without creating a new one, I think instead of creating a fixture, you can do sqldump, which will usually be a much smaller file.

0
source share

If you really don't care about destroying db, then Marco's answer about transaction rollback is also my preferred choice. You can also try NdbUnit , but I personally do not think that the extra baggage that it brings deserves success.

How are you testing test db now? By db testing, do you mean SQLite?

NTN
Berryl

0
source share

I have a full-on-slow django-test-db kit and a crazy test run against production test suite created from a common test module. I use the production package to test the health of my changes during development and as a step of checking commit on my development machine. The django suite module is as follows:

 import django.test import my_test_module ... class MyTests(django.test.TestCase): def test_XXX(self): my_test_module.XXX(self) 

The test suite module uses the bare unittest and looks like this:

 import unittest import my_test_module class MyTests(unittest.TestCase): def test_XXX(self): my_test_module.XXX(self) suite = unittest.TestLoader().loadTestsFromTestCase(MyTests) unittest.TextTestRunner(verbosity=2).run(suite) 

The testing module is as follows:

 def XXX(testcase): testcase.assertEquals('foo', 'bar') 

I run a bare version of unittest similar to this one, so my tests anyway have ORM django available to them:

 % python manage.py shell < run_unit_tests 

where run_unit_tests consists of:

 import path.to.production_module 

The production module needs slightly different setUp () and tearDown () settings from the django version, and you can put any necessary table cleanup there. I also use the django client test in a common test module, simulating a test client class:

 class FakeDict(dict): """ class that wraps dict and provides a getlist member used by the django view request unpacking code, used when passing in a FakeRequest (see below), only needed for those api entrypoints that have list parameters """ def getlist(self, name): return [x for x in self.get(name)] class FakeRequest(object): """ an object mimicing the django request object passed in to views so we can test the api entrypoints from the developer unit test framework """ user = get_test_user() GET={} POST={} 

Here is an example of a test module function that the client checks:

 def XXX(testcase): if getattr(testcase, 'client', None) is None: req_dict = FakeDict() else: req_dict = {} req_dict['param'] = 'value' if getattr(testcase, 'client', None) is None: fake_req = FakeRequest() fake_req.POST = req_dict resp = view_function_to_test(fake_req) else: resp = testcase.client.post('/path/to/function_to_test/', req_dict) ... 

I found that this structure works very well, and the super-fast production version of the package is an important time saver.

0
source share

If the database supports template databases, use the production database as the template database. Make sure the Django database user has sufficient permissions.

If you use PostgreSQL, you can easily do this by specifying the name of your production database as POSTGIS_TEMPLATE (and use the PostGIS backend).

0
source share

All Articles