Комментарии 17
Спасибо за статью! Подскажите, пожалуйста, как быть в случае варианта «Использовать транзакции БД при применении фикстур», когда я тестирую эндпоинт, внутри которого есть свои транзакции? Ну, скажем, у меня есть эндпоинт регистрации пользователя. Там я открываю транзакцию, внутри которой делаю запись в несколько таблиц. Я так понимаю, что в таком случае вариант использования транзакций при применении фикстур уже не прокатит?
0
Да, это может быть проблемно, т.к., насколько я знаю, практически никакая СУБД не поддерживает вложенные транзакции.
У нас используется ORM Doctrine, который реализует вложенность на своей стороне, используя механизм SAVEPOINT.
У нас используется ORM Doctrine, который реализует вложенность на своей стороне, используя механизм SAVEPOINT.
0
НЛО прилетело и опубликовало эту надпись здесь
Ещё можно писать не изолированные, а реалистичные тесты, когда нужное состояние создаётся не фикстурами, а пользовательскими действиями прямо на грязной базе. Тут, правда, добавляется требование запуска тестов в правильном порядке. Я рассказывал об этом подходе тут: https://m.habr.com/ru/post/510824/
0
Не совсем понял, ваш подход предлагает тестировать компонент начиная от дочерних к компонентам более высокого уровня в строгом порядке?
0
Мне больше всего помогла сборка контейнеров БД с данными внутри. Дропнуть и поднять контейнер- это очень быстро. Есть рецепты для MariaDB и PostgreSQL.
Но на редактирующих методах были грабли с 1С. Её я не допинал до докера. И в планах было писать моки на такие интеграции.
0
Хорошая статья, достаточно объемлющая. Подтвержу полезность следующих (и многизх других методов):
-Несколько джоб с тестами в CI
-Фикстуры
-Контейнеризация
Хочу заметить, что в статье перечислены методы стабилизации и оптимизации сетапа и самих тестов, но не сказано о том, что в первую очередь надо понять, что именно больше всего затягивает выполнение тестов. Может замена создания тестового пользователя на инсерт фикстуры в бд и сократит время процента на 2-3%, а работу с какой-либо внешней монструозной системой оставили без внимания, хотя ее оптимизация (или изоляция) позволила бы сократить время вдвое.
-Несколько джоб с тестами в CI
-Фикстуры
-Контейнеризация
Хочу заметить, что в статье перечислены методы стабилизации и оптимизации сетапа и самих тестов, но не сказано о том, что в первую очередь надо понять, что именно больше всего затягивает выполнение тестов. Может замена создания тестового пользователя на инсерт фикстуры в бд и сократит время процента на 2-3%, а работу с какой-либо внешней монструозной системой оставили без внимания, хотя ее оптимизация (или изоляция) позволила бы сократить время вдвое.
0
Спасибо за комментарий )
В целом, да, согласен )
Замечу, что «замена создания тестового пользователя на инсерт фикстуры в бд» сделано не из-за увеличения производительности, но для того, чтобы тестировать функционал более изолировано (например, чтобы легче было локализовать ошибку: в функции создания или в функции чтения она происходит; также если тестов на чтение достаточно много, то соответственно изменение логики в создании ресурса может потребовать изменений во всех этих тестах)
Нужно также понимать, что приемы описанные в статье являются результатом нашего опыта, поэтому не могут быть универсально применены для любого приложения. Интеграция с какой-либо системой уже скорее является частью предметной области конкретной компании и как оптимизировать работу с ней могут знать только ее работники (со своей стороны я мог бы предложить только, например, переопределить компонент в DI-контейнере/сервис-локаторе (мок))
В целом, да, согласен )
Замечу, что «замена создания тестового пользователя на инсерт фикстуры в бд» сделано не из-за увеличения производительности, но для того, чтобы тестировать функционал более изолировано (например, чтобы легче было локализовать ошибку: в функции создания или в функции чтения она происходит; также если тестов на чтение достаточно много, то соответственно изменение логики в создании ресурса может потребовать изменений во всех этих тестах)
Нужно также понимать, что приемы описанные в статье являются результатом нашего опыта, поэтому не могут быть универсально применены для любого приложения. Интеграция с какой-либо системой уже скорее является частью предметной области конкретной компании и как оптимизировать работу с ней могут знать только ее работники (со своей стороны я мог бы предложить только, например, переопределить компонент в DI-контейнере/сервис-локаторе (мок))
0
Получается, что у вас идет только проверка ответа, но то, что записалось в БД, например, никак не проверить? Раз все только в json и yml.
Я не считаю, что у меня очень сложный проект (CRM для школ), но и то, отправляя запрос на создание записи человека на обученике, мне нужно проверить не только, что запись создалась, но и что деньги списались, баланс у ученика обновился, уведомления ученику и менеджеру отправились и т.д.
Вообще, я вынашиваю идею не накатывать и не откатывать изменения после каждого теста/блоков тестов, а работать с одной базой, просто подготавливать каждый раз нужные данные и считать относительные значения. Например, есть у нас созданный юзер с id 1, мы тестируем ему добавление денег на баланс. Перед выполнением теста мы взяли из БД, сколько у него сейчас на балансе, сделали свой запрос (например, внесли 100 рублей), и после этого проверили, что баланс увеличился на эти 100 рублей. В итоге нам не интересно, что там сделали с этим юзеры другие тесты, главное, чтобы не удалили.
А если нам нужен особенный объект (удаленный юзер, или, наоборот, юзер для удаления), то мы создаем его внутри самого теста в БД.
Такой вариант рабты тестов не рассматривали?
Я не считаю, что у меня очень сложный проект (CRM для школ), но и то, отправляя запрос на создание записи человека на обученике, мне нужно проверить не только, что запись создалась, но и что деньги списались, баланс у ученика обновился, уведомления ученику и менеджеру отправились и т.д.
Вообще, я вынашиваю идею не накатывать и не откатывать изменения после каждого теста/блоков тестов, а работать с одной базой, просто подготавливать каждый раз нужные данные и считать относительные значения. Например, есть у нас созданный юзер с id 1, мы тестируем ему добавление денег на баланс. Перед выполнением теста мы взяли из БД, сколько у него сейчас на балансе, сделали свой запрос (например, внесли 100 рублей), и после этого проверили, что баланс увеличился на эти 100 рублей. В итоге нам не интересно, что там сделали с этим юзеры другие тесты, главное, чтобы не удалили.
А если нам нужен особенный объект (удаленный юзер, или, наоборот, юзер для удаления), то мы создаем его внутри самого теста в БД.
Такой вариант рабты тестов не рассматривали?
0
Состояние БД после тестов у нас также проверяется. Для этого в папке с классом теста есть отдельная директория, в которой можно описать yml с ожидаемыми значениями для интересующей таблицы.
При вашем подходе не получится так, что тесты будут дублировать правила бизнес логики?
При вашем подходе не получится так, что тесты будут дублировать правила бизнес логики?
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Так как же не страдать от функциональных тестов?