Reputation: 590
What I am trying to achieve.
I am testing rest API in Django project. I want to create test class with test functions that are related (each following test function relies on previous one) - first fail means all failed. In first test function I crete an object with 'post' request. In next test case I want to check that this object actually exists using 'get' request.
How it works
It looks like Django-pytest cleans the database from all records after each test.
It is mentioned in pytest documention: https://pytest-django.readthedocs.io/en/latest/helpers.html#pytest-mark-django-db-request-database-access
Is there any way to change this?
My code:
My conftest.py
:
import pytest
@pytest.fixture(scope='session')
def django_db_setup():
from django.conf import settings
settings.DATABASES['default'] = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db_name.sqlite3',
}
@pytest.fixture
def object_data():
return {"some keys": "some values"}
@pytest.fixture
def object_name():
return "some name"
My tests.py
:
import pytest
from rest_framework.test import APIClient
from rest_framework import status
@pytest.mark.django_db
class TestAPI:
def setup(self):
self.client = APIClient()
def test_create_object(self, object_data, object_name):
post_response = self.client.post("/api/object/", data=object_data, format="json")
assert status.is_success(post_response.status_code)
# make sure that report was created
get_response = self.client.get(f"/api/object/{object_name}/")
assert status.is_success(get_response.status_code)
# object exists here (test passes)
def test_get_object(self, object_name):
get_response = self.client.get(f"/api/object/{object_name}/")
assert status.is_success(get_response.status_code)
# object does not exists here (test failes)
Upvotes: 3
Views: 9346
Reputation: 1
Your test case structure seems wrong. Test cases should never depend on each other. There can be resources such as Model objects common among test cases (for eg. by initialising them in setUpClass) but a resource created in one test case should not be usable in another test case
Instead of the way you've set your test cases, you could do it as:
To test your POST endpoint:
1.1. Make the POST request, as you have in test_create_object
and assert the response info
1.2. Assert that the object actually exists, preferably by checking if it exists in the DB else by making a GET request
To test your GET endpoint:
2.1. Create the object preferably directly in the DB or by making a POST request
2.2. Make a GET request, as you have in test_get_object
and assert the response info
Upvotes: 0
Reputation: 2361
You probably don't want to persist data between test cases. You should strive to have test cases that can run in an arbitrary order. If you want data to be shared between test cases, either initialize it in a fixture and reuse that across test cases or combine your test cases into one to ensure everything in that one test case runs sequentially.
Upvotes: 7
Reputation: 425
Yes, pytest-django does clear your DB after each test run.
In order to solve this, add a pytest configuration file named pytest.ini
on your root directory and add as following
[pytest]
addopts = --reuse-db
As this config file suggests, it reuses the current DB without creating a new DB.
So if you need to create a DB for your test, you will have to specify it on command by pytest --create-db
Upvotes: 6