How to transfer data to a database between tests with pytest-django?

How can I save data in DB when using pytest / pytest-django in a test run of a Django application?

I run pytest with py.test --nomigrations --reuse-db -s , and Postgres DB test_<configued_db_name> is created as expected, but nothing is stored in the DB between tests and at the end of the test run DB is empty.

 import pytest from django.contrib.auth.models import User @pytest.mark.django_db(transaction=False) def test_insert_user(): user = User.objects.create_user(username="test_user", email=" test_user@test.com ", password="test") users = User.objects.all() assert len(users) > 0 @pytest.mark.django_db(transaction=False) def test_check_user(): users = User.objects.all() assert len(users) > 0 

The first test passes, the second does not make me wonder if anything is stored in the database at all. According to the documentation, pystest-django @pytest.mark.django_db(transaction=False) will not roll back from what the decorated test influenced.

Thanks,

/ David

+5
source share
2 answers

Another way to preload the database with data for each function is as follows:

 import pytest from django.contrib.auth.models import User @pytest.fixture(scope='module') def django_db_setup(django_db_setup, django_db_blocker): print('setup') with django_db_blocker.unblock(): User.objects.create(username='a') assert set(u.username for u in User.objects.all()) == {'a'} @pytest.mark.django_db def test1(): print('test1') User.objects.create(username='b') assert set(u.username for u in User.objects.all()) == {'a', 'b'} @pytest.mark.django_db def test2(): print('test2') User.objects.create(username='c') assert set(u.username for u in User.objects.all()) == {'a', 'c'} 

The good thing about this method is that the configuration function is called only once:

 plugins: django-3.1.2 collected 2 items mytest.py setup test1 .test2 . =================== 2 passed in 1.38 seconds ==================== 

The bad news is that 1.38 seconds is too long for such a simple test. --reuse-db is a faster way to do this.

+2
source

I solved this problem - pre-populate the database for each function - by defining a device with a function scope (i.e. model and session will not work).

Here is the code for checking submissions in Django.

 # This is used to fill the database more easily from mixer.backend.django import mixer import pytest from django.test import RequestFactory from inventory import views from inventory import services pytestmark = pytest.mark.django_db @pytest.fixture(scope="function") def fill_db(): """ Just filling the DB with my data """ for elem in services.Search().get_lookup_data(): mixer.blend('inventory.Enumeration', **elem) def test_grid_anonymous(fill_db): request = RequestFactory().get('/grid/') response = views.items_grid(request) assert response.status_code == 200, \ "Should be callable by anyone" def test_list_anonymous(fill_db): request = RequestFactory().get('/') response = views.items_list(request) assert response.status_code == 200, \ "Should be callable by anyone" 
+1
source

Source: https://habr.com/ru/post/1236862/


All Articles