Тестовый клиент Django против Django-Pytest

Я использую django-pytest для тестирования API Django Rest Framework. У меня есть тестовый модуль, который выглядит примерно так:

class TestClass:

    def test_station_is_created(self, db, api_client):
        StationFactory(name='foo')
        response = api_client.get(reverse('api:stations'))
        assert response.status_code == 200
        ...

    def test_no_stations(self, db, api_client):
        response = api_client.get(reverse('api:stations'))
        assert response.data['data'] == []

Когда я запускаю тесты, я получаю:

________________________________ TestClass.test_no_stations________________________________
path/to/test/module.py:11: in test_no_stations

E   assert [OrderedDict(...01251d92f')])] == []
E     Left contains more items, first extra item: OrderedDict([...])

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

ipdb> response.data['data'][0]['attributes']['name']
foo
ipdb> len(Station.objects.all())
0

Я не знаю, очищает ли pytest базу данных или нет между тестами. Я подозревал, что используются несколько баз данных, но у меня только одна настроена в моих настройках. Хотя, возможно, есть какое-то кеширование, но я прочитал документацию по тестовому клиенту Django и не нашел много. Чего мне не хватать?

2 ответа

Выяснил в чем проблема. Мы также использовали django-cacheops и ответ попал в кеш вместо того, чтобы снова выполнить запрос. Ирония в том, что я уже думал, что проблема может быть связана с кешем, но моя попытка отключить его не удалась и ввела меня в заблуждение, чтобы я исключил ее как причину проблемы. В конце концов мы выяснили, как правильно его отключить.

Вот способ, которым вы можете отключить кэширование для тестов, если вы используете cacheops и py.test:

from cacheops import invalidate_all

@pytest.fixture(scope='function', autouse=True)
def invalidate_cache():
    invalidate_all()

pytest-django действительно изолирует тесты друг от друга, возвращая транзакцию в конце каждого теста.

Если вы хотите убедиться, что в вашей базе данных нет станций, перед тестом добавьте в начале test_no_stations:

assert not Station.objects.all().exist()

Если это окажется неверным, либо вы что-то упустили в своей конфигурации pytest, либо проблема в вашем коде.

Другие вопросы по тегам