- Что это
- Правильный end-to-end
- Подходы: горизонтальный и вертикальный
- Типы сквозного тестирования
- Отличия между сквозным и системным
- Челенджи
- Советы
Описание
Сквозное тестирование — это проверка (валидация) приложения полностью, от начала до конца, вместе со всеми зависимостями.
Для такого тестирования создается тестовое окружение (среда), идентичное окружению, в котором работают реальные пользователи. Тестируются все действия, которые пользователи могут выполнять в приложении.
Тестируется весь user flow (путь пользователя). Например, при разработке онлайн-магазина тестировщик «идет по пути пользователя» от входа посетителя на сайт и регистрации до завершения покупки.
Правильное сквозное тестирование
Если сквозному тестированию уделяется чрезмерное время/ресурсы, а другие виды/уровни тестирования выполнены менее тщательно «в надежде на потом», это называется «переворачиванием тестовой пирамиды».
Хаотически выполненные быстрые ручные e2e-тесты могут выглядеть приемлемо для менеджмента, но принесут проблемы в будущем.
Рутинные операции e2e-тестов автоматизируются, чтобы сэкономить время. Современные приложения часто и регулярно обновляются — поэтому необходимостью становится автоматизированное непрерывное тестирование. Трудно выполнять все e2e-тесты вручную каждый раз при обновлении кода. Если есть возможность написать один тест-сьют и запускать его всякий раз когда нужно сквозное, что многие и делают, время действительно экономится.
Но каждый уровень и тип тестирования имеет свои ограничения. Если пытаться «выйти за рамки» каждого типа/уровня, такие тесты могут создавать проблемы. Может возникнуть ситуация, когда больше времени уходит на написание кода автотестов и его обслуживание, чем на продвижение с кодом собственно самого приложения. Иными словами, может потеряться крупнейший плюс автоматизации — ускорение всех процессов.
Поэтому, выполняя e2e-тестирование, нельзя забывать о тестовой пирамиде, о том что e2e-тесты находятся на ее вершине. Пирамида точнее всего отображает правильный баланс уровней и типов тестирования. Этот стандарт устоялся в ИТ-индустрии уже очень давно, около 20 лет назад, и продолжает быть вполне применимым и в 2023.
Если разработчики и тестировщики не будут соблюдать «правило пирамиды», то пирамида может превратиться в «перевернутую» — в которой большинство тестов, как по количеству так и по объему операций, будут составлять сквозные тесты. Или как вариант, пирамида будет похожа скорее на песочные часы: много юнит-тестов и сквозных, но почти нет интеграционных.
Уровни пирамиды
Пирамида тестирования имеет три «слоя»: юнит-тесты, интеграционные тесты и сквозные.
Далее, на самой верхушке, располагаются приемочные (для простоты примем, что они пока исключены из пирамиды; также примем, что функцию системных тестов у нас выполняют сквозные; о разнице между сквозными и системными — далее).
Юнит-тесты
Обычно «юниты» — это функции или классы. Они как правило небольшие, и не имеют внешних зависимостей. А если имеют, то вместо зависимостей «вставлены» моки.
Когда юнит-тест падает, определить причину достаточно просто. Очень маленькая область тестирования определяет то, что юнит-тесты просто писать, быстро выполнять, и очень легко обслуживать.
Интеграционные тесты
Касаются взаимодействий между несколькими подсистемами в приложении; такие тесты создавать сложнее и медленнее. Если интеграционный тест падает, найти причину сложнее чем в юнит-тесте, из-за большой области тестирования. Интеграционные тесты сложно писать и обслуживать, бывает нужно много моков и т.п.
Сквозные тесты
Как мы уже знаем, сквозные тесты фокусируются на user flow, от самых простых к сложным и негативным. Сквозные тесты с какой-то точки зрения можно рассматривать как «многоэтапные сложные интеграционные». Сквозные тесты самые медленные, потому что время уходит на билд, деплой, запуск приложения, и выполнение (очень) большого количества действий.
Если сквозной тест падает, найти причину как правило сложно, поскольку область тестирования теперь распространяется на все приложение, и на каждом этапе пользовательского пути может случаться ошибка.
Понятно, почему соблюдение тестовой пирамиды так важно — на каждом этапе тестирования уменьшается скорость и увеличивается область тестирования, а значит сложность создания и обслуживания автотестов. Сквозное тестирование не может заменить другие методы, а может только их «расширять». В идеале тестирование должно находить баги как можно ниже в пирамиде, не пропуская их на верхние уровни.
Сквозное тестирование в идеале должно валидировать в основном интерфейс — кнопки, формы, ссылки, и отрабатывать другие высокоуровневые операции, в том числе обслуживающие, типа обновления приложения и т.п.
Стратегии сквозного тестирования
Вертикальное e2e-тестирование
«Вертикальный подход» проверяет, как бы подытоживая, все уровни пирамиды, начиная с выборочных юнит-тестов, продолжая интеграционными, и заканчивая проверкой интерфейса. Стандартно применяется в CI/CD-пайплайне для автоматизированного запуска тестов при новых коммитах/pull-реквестах.
Горизонтальное e2e-тестирование
Обычно предполагает полную поэтапную проверку пользовательских путей, каждого взаимодействия на этом пути; а также и верификацию взаимосвязей с другими приложениями/интерфейсами. Из-за большого объема таких задач применяется в большинстве случаев лишь для основных, критически важных сценариев.
Типы сквозного тестирования
В данное время автоматизированные e2e-тесты применяются более широко чем ручные (по крайней мере если брать по количеству выполняемых операций). Автоматизация возможна двух видов: codeless и стандартная общепринятая (с написанием тестов на ЯП).
Стандартное e2e-тестирование
Если речь идет о e2e-тестировании веб-приложений, подразумевается применение фреймворков автоматизации браузеров. Самый популярный инструмент, разумеется, Selenium, но многие предпочитают Cypress (по крайней мере для JavaScript). В принципе, оба фреймворка работают более-менее похожим образом. (Подробный материал об инструментах — по ссылке).
В фреймворках создаются моки браузеров, которым передаются инструкции, какие действия выполнять; после этого запускаются тесты, проверяющие, как приложение реагирует на эти действия.
Ниже пример [мока из документации Cypress], можно видеть, как работает этот е2е-инструмент:
Выполняются действия:
- Пользователь заходит на сайт https://example.cypress.io.
- Если пользователь кликает на линк включающий слово “type”, то URL должен содержать “/commands/actions”.
- Если в поле имейла “.action-email” введено значение “fake@email.com”, проверяется, что оно теперь содержит это значение.
Codeless e2e
Под этим подразумевается применение фреймворков с некими функциями искусственного интеллекта, записывающих действия тестировщика. Добавляя некие дополнительные данные, фреймворк тестирует реакцию приложения.
Внешне это выглядит как lowcode-платформа, с перетаскиванием и вставкой блоков. Ниже гифка — как это делается (на примере TestCraft):
Как видим, крайне удобные функции, не требующие глубокого знания языков программирования (что актуально для выпускников базовых курсов QA), такие инструменты тем не менее обходятся компании дороже чем обычные. Но если остро стоит вопрос времени, подобные codeless-решения могут выручить. Разумеется, эти фреймворки еще слишком сырые в целом, они не могут полностью заменить всю сложность и функциональность существующих фреймворков, и тем более ручного тестирования которое остается по очевидным причинам. Если приложение имеет очень сложные пользовательские пути, если эти пути часто меняются, то конечно классическое e2e-тестирование незаменимо. Если приложение более-менее простое, и вопрос времени основной, то codeless-решения помогут.
Инструменты
Puppetry
Существует также бесплатный Puppetry с открытым кодом (!_не_путать_с_Puppeteer_!):
Как он работает:
TestProject
Бесплатная платформа сквозного тестирования, работающая в связке с Selenium и Appium.
Пример (можно включить русские субтитры):
Разница между сквозным и системным тестированием
Системное тестирование сосредоточено на полной валидации функциональных и нефункциональных требований. То есть, системное тестирование предполагает еще больше действий, чем сквозное. В системное тестирование включает такие подвиды тестирования, как тестирование масштабируемости, производительности, или надежности. Иногда задачи системного тестирования могут передавать внешней QA-команде, которая работает с приложением в режиме черного ящика.
В то время как сквозное тестирование фокусируется, грубо говоря, «на правильности прохода пользовательских путей».
Сложности
- Сквозные тесты не обязаны «тестировать как можно больше за один раз», то есть одним тестовым набором всю функциональность. Часто тестировщики пишут огромные сквозные тесты, верифицирующие буквально каждый аспект пользовательского пути, вдаваясь в ненужную детализацию там, где это не так уж обязательно. Например, для проверки пути логина в большинстве случаев будет достаточно верифицировать перенаправление пользователя на главную страницу после успешного логина.
- При падении сквозного теста бывает довольно-таки сложно определить «место падения», то есть его причину. Можно уменьшить время на дебаг автотестов, более внимательно отрабатывая бизнес-логику в юнит-тестах и интеграционных. Также существуют неплохие инструменты, дающие анализ причин, со скриншотами и логами этапов.
- На сквозные тесты требуется большое время в CI-пайплайне, что может тормозить или даже блокировать разработку.
- Сквозные тесты имеют «непрерывную» природу: каждая новая функциональность или изменения существующей приводят к необходимости обновлять сквозные тесты. Этот фактор можно смягчить, создавая реюзабельные компоненты, абстрагирующие детали имплементации. Опять же, в современных инструментах есть подсказки и автокоррекции, адаптирующие сквозные тесты к изменениям кода приложения.
Советы
- Реюзабельные тесты
Первый совет — делать сравнительно небольшие, по возможности независимые, и реюзабельные e2e-тесты (или делать реюзабельными хотя бы их компоненты). Это позволит «нанизывать цепочку» тестовых компонентов на полный end-to-end пользовательский путь. Вместо написания множества изолированных, нигде больше не задействованных тестовых компонентов. Что позволит снизить время на поиск проблемных мест в автотестах и быстрее обновлять тест-сьют.
- Покрывать e2e лишь критическую функциональность
И не тратить время на отработку сообщений об ошибках во второстепенных пользовательских путях — они как правило достаточно просты и не требуют внимания на таком высоком уровне как e2e; и вообще, они должны были исчезнуть на первом уровне модульного тестирования. Следует сосредоточиться на valuable flows, то есть лишь тех которые влияют на пользователей.
- Сквозные тесты не должны слишком зависеть от деталей имплементации
Вовсе не обязательно обновлять e2e-тесты при каждом изменении деталей имплементации в каждом конкретном пользовательском пути. Как говорилось выше, желательно «абстрагировать» отдельные компоненты. Тогда тесты будет проще писать, а далее обслуживать.
***