How to preserve django test database after running test cases
Asked Answered
P

6

10

When I run test cases by typing

python manage.py test myapp

After test cases completed, test databases deleted by default by django test runner. I don't want it to be deleted.

I can use any database!

I want to preserve my database because there are bugs in database that I wanted to see in database that created. So that I can pinpoint them!

Pecker answered 6/1, 2011 at 8:38 Comment(4)
Are you using SQLite? Can you switch to MySQL?Micamicaela
possible duplicate: #4607256Shut
Maybe you could elaborate on the reason why you want to preserve the database? It's always possible this isn't your real problem but for example bad test code is.Demurrage
can MySQL solve this problem. so that my test database remainsPecker
C
-5

According to docs:

Regardless of whether the tests pass or fail, the test databases are destroyed when all the tests have been executed.

Although, fixtures might be a help in your situation. Just create initial data, you want to be there when test starts, as texture, and make test load it.

Cardin answered 6/1, 2011 at 14:37 Comment(1)
This answer is outdated. Please update it with new and relevant information.Gerlach
T
16

You can prevent the test databases from being destroyed by using the test --keepdb option.

https://docs.djangoproject.com/en/dev/topics/testing/overview/#the-test-database

Tuesday answered 3/10, 2016 at 1:36 Comment(0)
A
12

While passing -k to manage.py test will retain the test database, it will still delete the records that was created in your test cases. This is because Django's TestCase classes will still reset your database after every test case (django.test.TransactionTestCase will do a flush, while django.test.TestCase will wrap each of your test case in a transaction and do a rollback when the test case is done).

The only real solution to making Django retain test data is to extend the TestCase class and override the code that resets your database.

However, if you do not have the time to do this, you can also make your test case pause execution before it finishes, giving you the time to inspect your database before it gets reset. There are several ways of achieving this, but, now, THIS IS A HACK, asking for user input in your Python code will make Python pause execution and wait for user input.

from django.test import TestCase


class MyTestCase(TestCase):
    def test_something_does_something(self):
        result = do_something_with_the_database()
        self.assertTrue(result)

        # Ask for `input` so execution will pause and wait for input.
        input(
            'Execution is paused and you can now inspect the database.\n'
            'Press return/enter key to continue:')

Alternatively, you can also use pdb's set_trace function, which will also make the execution pause and wait for input, and at the same time lets you debug the environment in that point of code execution.

Just make sure that you remove the input() (or pdb.set_trace()) call before you send your code to your automated build system or else it will wait for user input and time out.

Automatic answered 24/3, 2020 at 6:0 Comment(0)
F
8

According to the docs, you can preserve the database after running tests by:

$ python manage.py test -k

or

$ python manage.py test --keepdb
Flavorsome answered 17/3, 2017 at 20:45 Comment(0)
N
8

To preserve whole database state after test execution (not only tables structure)

  1. Make sure your test class is based on django.test.SimpleTestCase (not TestCase or TransactionTestCase)
  2. Take one of your tests for which you want to preserve database state
  3. Add the following code to your test class to prevent database tables cleaning after the test execution
    def tearDown(self) -> None:
        pass

    @classmethod
    def tearDownClass(cls):
        pass
  1. Run the test with --keepdb parameter, like ./manage.py test app.test --keepdb - to prevent whole DB cleaning after test execution
  2. Wait for the test to finish
  3. Profit! Take snapshot/discover your test_database [do not forget that Django by default will add prefix test_ to your default database name]

Example of command for test test_copy

./manage.py test --noinput --keepdb api.tests.SomeTests.test_copy

class SomeTests(SimpleTestCase):
    allow_database_queries = True

    def setUp(self):
        super(SomeTests, self).setUp()
        self.huge_set_up_operations()

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.huge_init_database()

    def tearDown(self):
        pass

    @classmethod
    def tearDownClass(cls):
        pass

    def test_copy(self):
        SubscriptionFactory()
Nosedive answered 11/5, 2020 at 18:31 Comment(2)
Another note, you also may need to add allow_database_queries = True attribute to the SomeTests class if there are any queries.Woodsman
Using allow_database_queries = True is deprecated since django 2.2 use databases = "__all__" instead! see also https://mcmap.net/q/1160576/-assertion-error-while-testing-django-viewsIstanbul
C
0

For anyone in a Pytest environment I use the following pytest.ini for testing

[pytest]
DJANGO_SETTINGS_MODULE=myapp.settings.test
python_files = tests.py test_*.py *_tests.py
addopts =
    --ds=myapp.settings.test
    --reuse-db
    --nomigrations

note the "--resuse-db" command argument/addpots

Cerargyrite answered 29/4, 2021 at 23:51 Comment(0)
C
-5

According to docs:

Regardless of whether the tests pass or fail, the test databases are destroyed when all the tests have been executed.

Although, fixtures might be a help in your situation. Just create initial data, you want to be there when test starts, as texture, and make test load it.

Cardin answered 6/1, 2011 at 14:37 Comment(1)
This answer is outdated. Please update it with new and relevant information.Gerlach

© 2022 - 2024 — McMap. All rights reserved.