[Django] обновление базы данных перед тестированием

Коллеги,

На новом проекте столкнулся с проблемой. Как апдейтить базу из snapshot перед прогоном тестов? Сейчас будет немного конкретики.

  1. Уровень Unit Tests. Здесь всё просто. Используем fixtures или factory-boy, последнее категорически удобнее. Для каждого теста создаётся новая запись в базе или используются ранее созданные в setUp. Всё красиво и замечательно.
  2. Уровень Integration Tests. В целом никто не запрещает factory-boy подход.
  3. Уровень Functional Tests. Вот здесь похоже нужна база для определённых кейсов.
  4. Уровень Performance Tests. Здесь точно не обойтись без DB snapshot потому как создавать н-е количество записей с помощью стандартных возможностей Django - грустно.

Собственно в чём проблема со snapshot базой - есть зависимость от date-time полей, то есть и для некоторых функциональных тестов и нагрузочных необходимо обновлять эти поля. Может кто-нибудь имеет опыт в этом деле? У меня есть мысли сделать это используя стандартные методы Django, но я не уверен, что это правильный подход. Поделитесь опытом, пожалуйста.

Артём

Позволю немного критики

Зачем тестировать данные в юнит тестах? Юнит тесты должны тестировать логику, все взаимодействия с базой и внешними сервисами мокаются на уровне самого теста. Данные будут тестироваться в функциональных и-или интегрейшн тестах, не больше и не меньше.

Насчет базы, реализовывал подобное для пары проектов. Суть в том, что перед каждым запуском теста развертывается локальное окружение (в моем случае это был postgres), где вайпилась база и накатывалась из дампа новая, на которой все тесты и проходили. В принципе подход опрадывает себя, пока у вас достаточно небольшое кол-во функционала и тестов, в дальнейшем же ваши тесты перестанут проверять реальные кейсы. Поясню - часто бывает что ошибка определяется не на первом логине пользователя, а на втором, третьем и тд, т.к. как вы сказали - обновляется много различных полей. Тестированием с снепшотами вы много не добьетесь, это как идеальный сферический тест кейс в вакууме.

Если уж вам надо какие-то специфические данные в базе перед тестом, меняйте их прямо в бд, в которой будете тестировать. Сделайте подобие qa api, которое будет делать все нужные вам вещи. На моем прошлом месте работы было сделано что-то подобное, с принципами можно ознакоиться http://sqadays.com/ru/talk/28689

данные для юнит тестов нужны для тестирования view-х Django в целом тут спорно, на сколько в Django это юнит тесты, наверное ближе к Integration, но в временами их почему-то зовут unit.

qa_api интересный подход, спасибо за ссылку. единственное, что писать этот api похоже буду я :smile:
с восстановлением из снепшота буду буду думать ещё. Похоже иметь обёртку из api запросов будет интересней.

Не обязательно делать именно http api. Можно сделать это внутри самого питона, ведь скорее всего все функции уже доступны из кода приложения и их просто прийдется вызывать с нужными параметрами.

Да, Django в этом плане гибкий, в основном функциональные тесты люди пишут на Selenium. Так что основное покрытие конечно внутренними средствами делается.

Всё равно спасибо за идею, доклад интересный.

Я позволю себе ссылку на подобное обсуждение, которое устроил Алексей Лянгузов http://sqadays.com/ru/talk/34880

“Серебрянной пули нет”. Но подход с созданием фейковых данных по рестам засел у меня в голове.

Что собираюсь делать:
Unit Testing (девелоперы согласились писать их более активно)
Functional Testing, близкое к Integration, будет основано на инструментарии Django и Factory Boy.
Ручное тестирование и дальнейший переход на Selenium будет пользовать подход QA REST.

Нужно время, но план есть, а это уже кое-что. :smile: