Паттерны и антипаттеры автоматизации тестирования
@notes_about_QAКогда только начинаешь заниматься автотестированием, организация фреймворка автотестов может быть сложной задачей. Важно создать структуру, которая будет удобной для расширения и поддержки в будущем (ладно, даже через год не всегда удается сделать это идеально).
Однако знание паттернов, шаблонов и антипаттернов автоматизации может помочь нам в этом процессе (а также знание шаблонов проектирования в общем, прочитать про них можно тут).
Паттерны — это повторяющиеся решения проблем, которые могут возникать в процессе разработки программного обеспечения.
Давайте начнем с того, какие вообще существуют способы организации автотестов:
- всем известная пирамида тестирования: позволяет структурировать и организовать автотестирование на проекте. Она помогает распределить количество юнит-тестов, интеграционных тестов и тестов на конечных пользовательских сценариях (e2e) таким образом, чтобы достичь оптимальной эффективности и охвата тестирования.
- ААА (Arrange-Act-Assert): этот шаблон помогает структурировать и организовать сами тесты
Он состоит из трех блоков:
⚡Arrange - секция подготовки. Она может состоять из нескольких строк. В этой секции мы определяем все необходимые элементы для начала тестирования: создаем объекты, стабы, моки и тд
⚡Act - Секция действия. Она всегда состоит из одной строки. Собственно это то самое выражение, которое мы хотим проверить. Если это выражение занимает несколько строк, это может указывать на то, что тест содержит слишком много деталей реализации, что может сделать его ненадежным и сложным в поддержке.
⚡Assert - Секция проверки. Эта секция может состоять из нескольких утверждений. Однако если они разноплановые, то стоит задуматься о хорошем дизайне метода или системы под тестированием, возможно разбить большой тест, на более мелкие.
Паттерны
Теперь рассмотрим некоторые паттерны автоматизации:
- Page object: этот паттерн используется для упрощения тестирования пользовательского интерфейса (UI). Он позволяет логически разделить приложение на страницы и работать с каждой из них отдельно. Таким образом, всегда известно, на какой странице мы находимся в данный момент.
- Page Factory: иногда нам требуется дополнительная настройка Page Object при его инициализации. Для этого используется паттерн Page Factory, который позволяет скрыть эти дополнительные действия при создании страницы.
- Page Element/Component: данный паттерн используется для работы с повторяющимися элементами на странице. Он позволяет нам удобно переиспользовать логику элементов, которая формируется только один раз.
- Data Provider: Загрузка данных для тестов из внешних источников (простыми словами, использование параметризации в тестах)
Еще больше паттернов для автоматизации можно почитать тут, я выделила любимые и чаще всего используемые.
Также стоит обратить внимание на улучшение читаемости и понятности кода. Здесь можно найти полезные советы и рекомендации для создания более понятного кода.
Антипаттерны
Я начинала писать эту статью именно ради этого раздела! Потому что паттернов я нашла много, а вот антипаттерны где-то прятались как алмазы. Пора их собрать вместе.
Рекомендую прочитать статью на эту тему: тут разбирают антипаттерны автоматизации в целом (а не только во фреймворке тестировщика), например, почему юнит-тесты без интеграционных не должны существовать (и интеграционные без юнит). Тут же упомяну про антипаттерн перевернутой пирамиды тестирования (дискуссионная тема): просто прочтите статью про пирамиду в целом и окунетесь в мир интересного и захватывающего.
А теперь поговорим про конкретные антипаттерны для наших фреймворков:
- Наличие условных операторов в тестах: использование условий в тестах указывает на то, что мы проверяем несколько вещей одновременно. Чтобы сделать тест более понятным и легко читаемым, рекомендуется создать отдельные тесты с понятными названиями для каждого варианта проверки.
- Тесты, которые трудно понять при чтении: иногда открывая тест, мы можем не понять, что происходит из-за сложных действий, которые выполняются. Чтобы улучшить читаемость, можно вынести повторяющиеся действия в отдельные функции с ясными и понятными названиями.
* аккуратнее, это может привести к тому, что вы будете выносить все подряд, и все станет еще непонятнее. - Неправильное управление тестовыми данными: когда тесты используют жестко закодированные данные внутри самих сценариев, это затрудняет поддержку и изменение данных. Лучше использовать отдельный источник данных, такой как файлы конфигурации или база данных, чтобы управлять тестовыми данными.
- Недостаточное логирование и отчетность: если автотесты не предоставляют достаточную информацию о прохождении или неудаче тестов, это затрудняет их отладку и анализ результатов. Важно включать логирование и генерацию отчетов, чтобы иметь полную информацию о выполнении автотестов. И логи писать понятные и читаемые, ведь тогда не нужно будет идти в тест и пытаться понять, а что там происходит.
- Проверка без описания, что же мы проверяем: сделали assert, но не описали, что же он проверяет? Иногда из этого не возникнет проблемы, но часто оказывается, что читаемость теста ухудшается, а при падении теста совсем непонятно, что же произошло (и надо уходить внутрь теста и разбираться в происходящем).
Антипаттернов тоже очень много! Поэтому советую интересное видео про них, чтобы подробно увидеть их на примерах.
А еще из полезного рекомендую почитать про вредные советы для автоматизаторов часть 1 и часть 2
От автора канала "Заметки о QA"