Опрокинутая тест-пирамида |
25.02.2025 00:00 |
Эта статья написана в ответ на вопрос Джулии Торрехон «Какие тесты должны прогоняться на каждом шаге пайплайна в ходе непрерывного тестирования?». Спасибо, Джулия, за вдохновение для этой статьи и за твою любовь к качеству! Тест-пирамида – настолько устоявшееся понятие, что, думаю, все вы знаете о ней. В случае, если это не так, объясняю: это способ визуализации распределения различных типов тестов в приложении. Концепция проста: чем раньше вы найдете проблемы, тем дешевле с ними разобраться и исправить их. Пирамида тестирования делает на этом акцент, демонстрируя типы тестов, которые можно проводить раньше и в большем количестве по сравнению с тестами, которым для запуска требуется полностью готовое приложение. В базовом примере, смотрящем вверх равностороннем треугольнике, внизу находятся юнит-тесты, затем интеграционные тесты, а на вершине – 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. |