Pytest использует django_db с каркасом отдыха - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь заставить простой тест работать с реальной django_db, а не с тестовой базой данных, использующей django rest framework.

Базовая настройка теста:

import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient

@pytest.mark.django_db
def test_airport_list_real():
    client = APIClient()
    response = client.get(reverse('query_flight:airports-list'))
    assert response.status_code == 200
    assert len(response.json()) > 0

Запустив этот тест, я получаю:

___________________________ test_airport_list_real ____________________________

    @pytest.mark.django_db
    def test_airport_list_real():
        client = APIClient()
        response = client.get(reverse('query_flight:airports-list'))
        assert response.status_code == 200
>       assert len(response.json()) > 0
E       assert 0 > 0
E        +  where 0 = len([])
E        +    where [] = functools.partial(<bound method Client._parse_json of <rest_framework.test.APIClient object at 0x000001A0AB793908>>, <Response status_code=200, "application/json">)()
E        +      where functools.partial(<bound method Client._parse_json of <rest_framework.test.APIClient object at 0x000001A0AB793908>>, <Response status_code=200, "application/json">) = <Response status_code=200, "application/json">.json

query_flight\tests\query_flight\test_api.py:60: AssertionError

При простом запуске в оболочке с использованием pipenv run python manage.py shell я получаю ожидаемые результаты:В [1]: из django.urls импорт в обратном порядке

In [2]: from rest_framework.test import APIClient

In [3]: client = APIClient()

In [4]: response = client.get(reverse('query_flight:airports-list'))

In [5]: len(response.json())
Out[5]: 100

Использование следующих пакетов:

pytest-django==3.2.1
pytest [required: >=2.9, installed: 3.5.1]
djangorestframework==3.8.2
django [required: >=1.8, installed: 2.0.5]

Есть ли способ получить pytest для доступа к реальной базе данных таким способом?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Маркер django_db отвечает только за подключение к тестовой базе данных для помеченного теста. Параметры django, переданные pytest-django, несут полную ответственность за выбор базы данных, используемой в тестовом прогоне.

Вы можете переопределить использование базы данных в pytest-django, определив приспособление django_db_setup. Создайте файл conftest.py в корневом каталоге проекта, если у вас его еще нет, и переопределите конфигурацию базы данных:

# conftest.py
import pytest

@pytest.fixture(scope='session')
def django_db_setup():
    settings.DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'path/to/dbfile.sqlite3',
    }

Однако вы не должны использовать реальную базу данных в тестах. Создайте дамп текущей базы данных, чтобы получить снимок тестовых данных (python manage.py dumpdata > testdata.json) и загрузите его в пустую тестовую базу данных, чтобы заполнить ее перед запуском теста:

# conftest.py
import pytest
from django.core.management import call_command

@pytest.fixture(scope='session')
def django_db_setup(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        call_command('loaddata', 'testdata.json')

Теперь вы не можете испортить свой реальный БД при запуске тестов; любые будущие изменения в реальной базе данных не приведут к сбою тестов (например, когда некоторые данные были удалены), и у вас всегда будет детерминированное состояние при каждом запуске теста. Если вам нужны дополнительные тестовые данные, добавьте их в формате JSON в testdata.json, и ваши тесты хороши.

Источник: Примеры в pytest-django документах .

0 голосов
/ 17 мая 2018

У вас есть пара вариантов.При использовании Django TestClient или DRF APIClient по умолчанию будут использоваться тестовая база данных и локальная версия вашего приложения.Чтобы подключиться к своему действующему API, вы можете использовать библиотеку типа Запросы для выполнения HTTP-запросов, а затем использовать эти ответы в своих тестах:

import requests

@pytest.mark.django_db
def test_airport_list_real():
    response = requests.get('https://yourliveapi.biz')
    assert response.status_code == 200
    assert len(response.json()) > 0

Просто будьте предельно осторожны, чтобы выполнять исключительно чтениетолько тесты в этой действующей базе данных.

...