Что пишут в блогах

Подписаться

Что пишут в блогах (EN)

Разделы портала

Онлайн-тренинги

.
Опрокинутая тест-пирамида
25.02.2025 00:00

Автор: Ноэми Феррера (Noemi Ferrera)
Оригинал статьи
Перевод: Ольга Алифанова

Эта статья написана в ответ на вопрос Джулии Торрехон «Какие тесты должны прогоняться на каждом шаге пайплайна в ходе непрерывного тестирования?». Спасибо, Джулия, за вдохновение для этой статьи и за твою любовь к качеству!

Тест-пирамида – настолько устоявшееся понятие, что, думаю, все вы знаете о ней. В случае, если это не так, объясняю: это способ визуализации распределения различных типов тестов в приложении.

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

В базовом примере, смотрящем вверх равностороннем треугольнике, внизу находятся юнит-тесты, затем интеграционные тесты, а на вершине – end-to-end.

 

Базовая пирамида тестирования

Эти тесты категорически необходимы для гарантии минимального качества приложения, однако нам может понадобиться куда больше полезных тестов.

Для большей детализации и увеличения количества типов тестов можно превратить этот треугольник в настоящую пирамиду с потайными ходами. Не буду повторяться – если вы хотите узнать об этом больше, есть книга, где это подробно описано.

Тест-пирамида в CI/CD

Непрерывная интеграция и поставка (CI/CD) становятся устоявшимися практиками правильной разработки приложений, включая непрерывное тестирование и автоматизацию шагов, которые в противном случае могут повлечь человеческие ошибки.

К примеру, если приложение не CD, то разные версии фич нужно тщательно отбирать вручную, создавая сборку для деплоя. Это значит, что мы можем случайно выбрать что-то не то, что приведет к неожиданному поведению и проблемам в приложении для пользователя.

Приложения CI/CD, как правило, распределяются через «пайплайн» - название имеет отношение к водопроводным трубам, нечто попадает в них с одного конца и выходит из другого.

 

Пример пайплайна

В случае с CI/CD приложениями мы стремимся распределять все слева направо через пайплайн – слева находится то, что происходит раньше, а справа – то, что ближе к конечному пользователю. Пайплайн разделен на шаги, которые связаны с конкретным окружением, в которое деплоится код.

В этом контексте есть смысл повернуть пирамиду на бок.

Основание пирамиды будет повернуто влево (где все начинается), а вершина – вправо (где мы получаем результат). Юнит-тесты могут происходить до пайплайна, поэтому может получиться так, что база будет вне него.

 

Тест-пирамида на боку

На каком шаге запускать тесты?

Все приложения и команды уникальны, и у каждого пайплайна есть конкретная задача, поэтому довольно трудно сказать, на каком конкретно шаге какие конкретно тесты запускать.

Как правило, отдельные шаги связаны с различными окружениями, но общее количество окружений и шагов для каждого из них может сильно различаться.

В целом end-to-end тесты и тесты фронтенда должны начинаться, когда все уже создано и связано воедино, поэтому вряд ли мы их увидим до какого-то препрод-окружения. Оттуда и начнется вершина пирамиды.

С другой стороны, юнит-тесты должны запускаться в самом начале, как правило, еще до код-ревью, и это значит, что они могут находиться перед первым шагом пайплайна.

Опрокинутая пирамида может дать нам представление о количестве тестов в пайплайне – в смысле, большая часть тестов должна быть привязана к первому шагу, затем приличное количество – к последующим, и минимум – на финальном этапе. Она также дает представление о том, где эти тесты должны запускаться. Однако эти взаимоотношения относятся к «уникальным тестам», а в ходе пайплайна мы зачастую повторно прогоняем наборы тестов, валидируя разные окружения.

 

Пример соответствия тест-пирамиды пайплайну

Повторение тестов в пайплайне

Мы хотим по-максимуму валидировать окружения, но в то же время не желаем тратить лишнее время на тестирование, чтобы не замедлять деплой.

Параллельный запуск тестов помогает, но также важно сохранять баланс.

Наша цель – избежать запуска не нужных тестов, и не тестировать ничего дважды. Это значит, что в ходе интеграции не нужно запускать юнит-тесты – концентрируйтесь на интеграции. Я также неоднократно видела, как UI-тестами покрывают то, что уже в достаточной степени покрыто интеграционными тестами, вместо того, чтобы концентрироваться именно на UI.

Эта часть, возможно, прозвучит противоречиво – я назвала тесты на вершине UI, а не end-to-end, и да, вам также понадобятся тесты для покрытия end-to-end сценариев, включая пользовательские макеты, а это значит, что они будут запускаться в то же время, что и UI-тесты. И да, чем больше путей вы так протестируете, тем лучше, но повторюсь, надо тщательно подумать, что именно вы хотите протестировать, и не покрыто ли это уже предыдущими этапами.

Несмотря на это, даже если вы стараетесь как можете не тестировать то, что уже покрыто, некое повторение тестов все равно обязано присутствовать – мы деплоим в новые окружения и хотим убедиться, что в ходе деплоя ничего не сломалось.

Я рекомендую иметь тесты верификации билда, которые отрабатывают на разных шагах, а также прогонять большее количество интеграционных тестов в тот момент, когда это становится возможным.

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

Как насчет других тестов?

Как я упоминала в начале этой статьи, тест-пирамида – базовая концепция, другие тесты тоже надо учитывать. Уже упомянутый принцип тут тоже применим. Подумайте, что вам минимально необходимо для запуска этих тестов, и это даст вам представление об этапе, на котором эти тесты должны выполняться.

К примеру, тесты производительности относятся к ранним этапам пайплайна, но нам может понадобиться сдвинуть их вправо, так как начальные окружения, возможно, слабоваты для таких тестов. А для тестов доступности нужно готовое приложение и фронт, поэтому они пойдут правее, ближе к end-to-end.

На проде нам тоже могут понадобиться постоянно работающие тесты, чтобы убедиться, что серверы работают как должно, и через пайплайн не просочилось крупных проблем. Эти тесты не должны беспокоить пользователей (включая нагрузочные, которые могут вызвать большие задержки ответов), а также не должны влиять на метрики поведений прода.

Тесты обнаружения могут проводиться на любом этапе развития приложения, но скорее будут ближе к вершине пирамиды или правой стороне пайплайна. Они также могут проводиться на проде – зависит от того, что мы хотим обнаружить.

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

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

Примечание: если хотите увидеть реальный пример, посмотрите доклад @practicaltester.

Обсудить в форуме