
История о том, как можно делать автотесты без автотестеров (ну почти).
Дано:
-
Проект с небольшим бюджетом
-
Максимальное возможное количество тестировщиков на проекте = 2
-
Тим лид или автоматизатор, у которого есть еще несколько других проектов. Т.е. постоянно писать и обслуживать тесты не может
Найти:
-
Регрессионное тестирование за минимальное время
-
Потратить на это минимальное количество денег/времени/сил
По причине невысокого бюджета приходим к тому, что нет возможности нанять полноценных автотестировщиков
Тестирование без автотестов? А кто-нибудь может без них, если уже попробовал хотя бы раз?)
Пусть разработчики пишут автотесты? В целом да, но проект небольшой, разработчиков тоже немного и времени на тесты у разработчиков нет (Пилим фичи и правим баги, какие тесты)
Поиск решения:
-
Первое, что я начал искать — инструменты, которые записывают действия пользователя в автотест. Перепробовав несколько из них (Selenium IDE и др), я не смог ответить на вопросы: Вернувшись к тесту через полгода, ручной тестировщик сможет повторить его руками? Понятно, что происходит в тесте без запуска?
-
Учим тестировщиков автоматизации? Да, адекватный вариант решения, но он подходит далеко не всем. Во-первых время, это долго. Проект уже убежит вперед, нагонять поезд будет очень сложно. Во-вторых не все тестировщики готовы и могут обучиться полноценной работе с кодом
-
Отдаем на аутсорс автотесты? Отличный вариант, но дорого и нужно все равно сажать человека в проект. Т.к. он (проект) постоянно меняется, и поддерживать и расширять автотесты необходимо постоянно
-
А что, если посмотреть в сторону BDD/TDD фреймворков, под капотом переиспользовать современный playwright/cypress и использовать его в качестве автотестов? Почему нет? Тысячу раз да)
К чему пришли:
-
Разработали «универсальный» набор шагов и проверок для фронтовых действий пользователя. Универсальный набор шагов предполагает, что селекторы будут указаны прямо в тексте шага (да, я в курсе, что это плохо). В каждом шаге, где используется селекторы, присутствует обязательная переменная name. Она не используется непосредственно в действиях и нужна только для отчета и общего понимания теста без запуска, в ней можно писать любой текст, который сделает шаг теста более понятным. Например:
When Я нажимаю "Кнопку сохранить"/"[data-test-id="btn-save"]" Then Вижу в "Предупреждении для Email"/".email._error" текст ~ "Не может быть пустым" Then НЕ Вижу "Заявка успешно отправлена"/".request-complete._open" -
Разработали и подготовили набор предусловий для создания сущностей через API (авторизация и очистка данных тоже через API)
-
ЗаставилиПопросили разработчиков добавить атрибут data-test-id каждому элементу интерфейса, с которым можно взаимодействовать (что такое атрибут data-test-id не описано в статье, но легко гуглится. Пример статьи Ссылка) -
Написали пару тестов для примеров тестировщикам
-
Показали тестировщикам, как работать с git и pull request (можно и без этого, но так удобнее)
-
Показали тестировщикам, как искать и проверять CSS селекторы в DOM дереве (в особо сложных случаях можно просто помочь и показать)
-
Настроили сборки в Jenkins для удобного запуска
и … Завелось и поехало
Каждый из этапов можно описать подробно, но я не знаю на сколько это интересно (пишите в комментариях)
Важно. Мы не меняем методологию разработки внутри продукта. Т.е. мы не внедряем BDD/TDD подход полноценно
Мы просто используем существующий фреймворк этой методологии для разработки автотестов
Реализация
Чтобы долго не рассказывать как и почему — выложил рабочий пример в репозиторий simpleE2E
В публичный репозиторий вынесли несколько обрезанную версию нашей реализации. В ней убрано все, что касалось работы с api проекта (оставил только заготовки для примера) и шаги, включающие несколько действий внутри. Но в целом это полностью рабочий код с примерами тестов и универсальными шагами.
При необходимости можно брать и использовать: Клонируем репозиторий, выполняем инструкции из readme, пишем тесты и запускаем
В проекте используется python + playwright + gherkin + behave
Документация инструментов:
Пример готового теста
Примеры тестов в репозитории разработаны специально для демонстрации
Feature: Сайт.SaveLink Scenario: Большая форма. Проверка обязательности полей. Email Given Дефект "Неверный текст предупреждения"/"https://jira.example.com/" Given Я открываю сайт "https://save-link.ru/" When Я ввожу "Тест" в "Имя"/"#partner-name" When Я ввожу "9001001010" в "Телефон"/"#partner-phone" When Я нажимаю "Оставить заявку"/"[data-form="partnership-form"]" Then Вижу в "Предупреждении для Email"/".email._error" текст ~ "Не может быть пустым" Then НЕ Вижу "Заявка успешно отправлена"/".request-complete._open"
Другие примеры тестов см в /features/test в репозитории проекта
Доступные для использования шаги
Мы пишем тесты на русском языке, потому что команде проекта так удобнее. Технических проблем с запуском или поддержкой тестов из за русского языка замечено не было. При желании можно изменить текст шагов на английский язык
Шаги делятся на 3 типа:
Given — Предусловия. Например
Given Я открываю сайт "{url}" Given Я создаю сущность тест с именем "{entity_name}" ...
When — Действия. Например
When Я нажимаю "{name}"/"{selector}" When Я нажимаю "{button}" на клавиатуре When Я нажимаю ПКМ на текст "{text}" ...
Then — Проверки или ожидания. Например
Then Вижу текст "{text}" Then НЕ Вижу "{name}"/"{selector}" Then Жду исчезновения прелоадера "{selector}" Then Сравнить со скрином "{path_screen}" ...
Чтобы получить полный список доступных шагов. Выполнить:
python steps_bdd.py --output=available_steps
В результате работы скрипта будет создан файл index.html с перечнем всех доступных шагов. На момент написания статьи доступных шагов в публичном репозитории 41.
В нашем основном репозитории 114 шагов:
-
40 шагов это предусловия по созданию сущностей через API
-
10-14 шагов, которые группируют популярные действия
-
~20 шагов, выполняют действия в диалоговых окнах и iframe
Полный перечень доступных шагов из index.html (шаги публичного репозитория)
Дополнительные опции
-
Ключевые слова. В шагах для ввода текста (Я ввожу текст, я ввожу большой текст и т.д.) можно использовать ключевые слова:
-
random — слово будет заменено на сгенерированное: Autotest<метка времени><случайное число>
-
longName(N) — слово будет заменено на последовательность символов длинной N (последовательность статична)
-
-
Существует шаг сравнения скриншотов, с определенной точностью. В результате шага прикладывается скрин текущего состояния, скрин эталона и разница изображений
-
В коде приведены примеры вызовов api, но они представлены только для примера и неработоспособны. Желательно использовать предусловия для создания сущностей через api + удаление сущностей
-
После выполнения каждого действия теста выполняется скриншот состояния и прикладывается к отчету
-
Подключено аппаратное ускорение. Работает быстрее при наличии дискретной графики
Отчеты
Все результаты теста и прочие артефакты собираются в allure отчет (в публичном проекте все для этого подготовлено).
Allure Report существует в виде плагинов CI/CD и локального приложения. Allure отличный инструмент для визуализации результатов автотестов (если кто еще не знал)
Ещё скрины отчета


Итоги
Плюсы
-
Каждый сценарий автотеста можно повторить руками (и не только тестировщику), т.к. он написан на человекочитаемом языке
-
Разработка автотестов выполняется силами ручных тестировщиков. Их понимание тестов и вовлеченность на высоте (т.к. это сокращает их время на регрессионное тестирование и просто интересно)
-
Автотесты выполняются ежедневно (в Jenkins), дефекты находятся на ранних этапах разработки и лечатся еще ДО старта регрессионного тестирования
-
Опционально. В будущем может облегчить переход на BDD/TDD методологию разработки внутри всей команды
-
Скорость разработки автотестов. 900+ стабильных e2e теста (реально стабильных) за 3 месяца (разработка только в свободное от задач время тестировщиков)
-
После разработки сценария теста тестировщик проходит ревью у своего коллеги
Возможные минусы
-
Дублирование последовательностей действий (у нас редкий кейс). Решение — Если последовательность действий часто дублируется, то ее можно объединить в единый шаг или параметризировать тест (в публичном проекте присутствуют примеры параметризированных тестов)
-
Использование селекторов внутри шагов. Да, это плохо. Нет pageObject со всеми вытекающими. Но мы осознанно идем на этот шаг, т.к. у каждого элемента должен быть атрибут data-test-id. Если он «пропал» — дефект в разработку и тест снова работает (не всегда через 5 минут, но все же довольно быстро)
-
Использование разных селекторов для одного и тоже элемента. С наличием атрибута data-test-id у каждого элемента не проявляется
Если вы столкнулись или можете столкнуться с перечисленными минусами (а все остальное нравится) — это не повод отказываться от этой идеи. Один из вариантов решения — записывать селекторы в один/несколько json файлов и обращаться к элементам по именам, а не по селекторам.
ссылка на оригинал статьи https://habr.com/ru/articles/816597/
Добавить комментарий