В нашей компании десятки продуктовых команд с решениями разного уровня сложности. На определённом этапе зрелости продукта у каждой из команд возникает потребность в автоматизации тестирования. Тестировщики проделывают большой объём работ по написанию и актуализации тест-кейсов, углублению в бизнес логику продукта, тестированию новых фич и исправленных дефектов, а потом и регресса. А ещё тестировщиков в продуктовой команде заведомо больше чем специалистов по автоматизации, а значит автоматизаторы не всегда успевают за тестировщиками, не говоря уже о том, что тесты, особенно UI, работают не всегда стабильно, а инфраструктура преподносит свои сюрпризы. В результате, на большом проекте вовлечённость специалистов по автоматизации во внутренние процессы продуктовой команды и бизнес логику продукта постепенно снижается, а  их задачи сводятся к поддержке написанных ранее тестов. Тестировщики же изо всех сил бьются, чтобы выйти из порочного круга постоянных регрессов — фич нужно больше, багов меньше, а релизы чаще. Как мы можем решить эти проблемы? Нам пришла в голову идея: Мы выделили два возможных пути: Научить команду тестирования писать автотесты в коде. Упростить процесс написания тестов, позволив тестировщикам создавать сценарии      автоматизации, без необходимости изучения сложных технологий. Мы решили пойти по второму пути. Для этого нам был необходим инструмент с которым тестировщик может справиться без особого труда и/или с минимальным обучением. При этом мы ожидали, что перераспределив обязанности, мы сможем высвободить ресурсы автоматизаторов и направить их на развитие имеющихся инструментов автоматизации и обеспечение удобства работы с ними. После непродолжительного обсуждения с командой пилотного проекта по внедрению такого подхода мы выяснили, что тестировщики будут рады попробовать себя в написании автотестов, а специалисты по автоматизации, в свою очередь, приветствуют появление новых сложных технических задач — звучит как неплохая отправная точка для поиска решения для нашего уравнения. Так как мы хотели снизить порог входа для написания автотестов,  мы начали смотреть в сторону BDD (англ. Behaviour Driven Development) и KDT (англ. Keyword Driven Testing) фреймворков тестирования. Гипотеза была в том, что есть стабильное, зрелое решение с большим активным коммьюнити и возможностью писать тесты на нативном пользователю языке. Да, смелая гипотеза, но, в принципе, не ошиблись. Далее предстоял анализ имеющихся на рынке фреймворков, первичный отбор шёл по следующим критериям: ●   Число звёзд на GitHub: 1k+ Нужно было зрелое, поддерживаемое решение с коммьюнити ●   Язык программирования Java, Python или JavaScript Получился вот такой список кандидатов: Cucumber Behave Robot Framework Gauge Jasmine  Выделили следующие критерии для детальной оценки: ЯзыкВ идеале, Java. т.к. используем его, но были готовы рассмотреть Python и JavaScript ОтчётыПоддержка Allure или наличие своего отчёта “из коробки” ДокументацияПодробная документация, позволяющая быстро начать работать и решать типовые задачи КоммьюнитиВостребованный фреймворк с активным комьюнити с большей вероятностью будет жить и развиваться ЛицензияВ идеале, свободное ПО СтабильностьХотелось быстрее внедрить решение и меньше заниматься его отладкой и поиском багов ПараллелизмВозможность параллельного запуска тестов Плагины для IDEДля удобства работы По итогу, получилась вот такая табличка: Фреймворк    Язык    Отчеты Документация    Комьюнити    Лицензия    Стабильность    Параллельный запуск тестов    Плагины для IDE    Cucumber    Any + + 4.7к    MIT    + + + Behave    Python    + можно Allure    + 2.7k    2-Clause BSD License    ? + + Robot Framework    Python    + + 7.4k    Apache 2.0    + ? - Gauge    Any + + 2.8k    Apache 2.0    ? + + Jasmine    JS + + 15.5k    MIT    + - + Попробовав всё, мы приняли решение остановиться на фреймворке Gauge (гейдж, а не гауге ;-) ) — по совокупности критериев он был признан лучшим для наших целей и задач. Начали внедрение на одном продукте и для этого было две причины: продукт — одностраничный конструктор форм, по своей сути, он больше всего подходит для BDD/KDT, т.к. там можно реализовать максимальный уровень переиспользования, а значит написав метод один раз и отдав его тестировщикам мы с бо́льшей долей вероятности никогда к нему не вернёмся. надо было собрать все грабли на одном проекте, чтобы на других проектах внедрение шло лучше. Gauge оперирует следующими понятиями: Specification (спецификация) — описание тестируемого функционала; может содержать один или несколько сценариев Scenario (сценарий) — конкретный тестовый случай в рамках сценария. Step (шаг) — текстовое описание совершаемого действия. Parameters (параметры) — область шага, служащая для передачи значений из шага в код реализации шага на ЯП; код реализации шага должен содержать столько же параметров, сколько и Gauge шаг. Concept (концепт) — группа шагов, объединённых в один для улучшения читаемости и переиспользования. Tags (теги) — ключевые слова для фильтрации и поиска сценариев/спецификаций. При запуске тестов мы можем указать один или несколько тегов, которые должны содержать сценарии/спецификации для запуск. Также мы используем дополнительную сущность, служащую для объединения отдельных шагов в бизнес-действия — keywords (кейворды). Для удобства навигации структура кейвордов максимально приближена к структуре PO/PE классов. Структура maven проекта практически не меняется — лишь добавляются пакеты, где будут храниться спецификации,концепты и property файлы самого Gauge.   По сути, Gauge это обёртка над кодом, позволяющая писать тесты на русском языке. Это позволяет добиться максимальной наглядности тестов, а также отделить их от реализации Выглядит это примерно так: пишем Java методы в наших Page Object / Page Element классах. в аналогичных Page Object / Page Element кейвордах создаём методы с аннотацией Gauge, которые будут переиспользовать наши Java методы. в спецификацию (тест) пишем текст аннотации Gauge метода и передаём параметр(ы), если это необходимо. При запуске теста Gauge выполнит Java код методов, на которые ссылается Gauge метод. Для локального запуска всё готово, для CI/CD потребуется пробрасывать номер теста при помощи Tags. В property файлах Gauge можно настроить параллельный запуск, директорию хранения отчёта, директорию хранения спецификаций, добавит JVM аргументы и т.д.  Тут всё на ваше усмотрение. Упомяну лишь, что мы используем Selenide для описания Page Object / Page Element, поэтому в JVM аргументы добавили таймаут для Selenide: Далее, до передачи автотестов тестировщикам были написаны:    базовые методы взаимодействия с элементами; базовые проверки; порядка 50 тестов, задействующих реализованные методы. Методы и проверки писались таким образом, чтобы максимизировать переиспользование и в дальнейшем максимально снизить вовлечение автотестера, оставив тестерам методы на все случаи жизни, из которых они уже могут сами собирать любые Gauge шаги для тестов. Также ручных тестировщиков было проведено дополнительное обучение по основам работы с: Git IDE отчётами о прогоне тестов, т.к. каждую ночь запускается прогон с актуальной dev версией приложения, по итогам которого на разработчиков заводятся задачи/актуализируются автотесты. После чего на проекте последовал процесс постепенной передачи автотестов от автотестеров к ручным тестировщикам. В процессе передачи с каждой неделей вовлечённость автотестеровщиков снижалась, а ручных тестировщиков — росла. Автотестеры периодически подключались для реализации новых методов и части сложных тестов. Как итог, мы пришли к тому, что автоматизаторы реализовали все необходимые методы и смогли переключиться на работы по доработке/улучшению имеющихся инструментов автоматизации, а тестировщики сами продолжили покрывать проект автотестами, доведя их число до 2000+. Само собой, не всё шло гладко и мы столкнулись с рядом проблем, а именно: Кодировка в аннотации Gauge — только UTF-8. Каждая аннотация @Step от Gauge должна содержать своё уникальное описание. В переменных окружения не меняйте версию Java на отличную от версии проекта Во всех перечисленных случаях, при попытке запуска тестов вы просто      получите неинформативное сообщение об ошибке и будете гадать в чём же      проблема. Сложности в написании Gauge шагов, когда тесты пишут несколько автотестеров, а в последствии и вся команда тестирования. Над последним пунктом хочется остановиться особенно подробно, т.к. этот пункт не только попил много нашей крови, но также стал системообразующим при распространении практики Gauge тестов на другие проекты. В чём суть: когда ты работаешь на проекте один, то все решения принимаешь только ты и тебе не надо ни с кем их согласовывать; когда на проекте больше одного автоматизатора и вы, например, переводите проект с Java + JUnit + Selenide на Gauge, то рано или поздно столкнётесь с тем, что нужна какая-то логика наименования Gauge шагов, в противном случае, готовьтесь решать конфликты при каждом коммите. Мы пробовали разные подходы, обсуждали их плюсы и минусы и, спустя некоторое количество итераций, мы пришли к следующей логике наименований шагов: <Где> <Действие> В модальном окне подтверждения удаления нажать на кнопку “Да”. В списке пользователей, в строке пользователя “Евгений Морозов” нажать кнопку “Удалить”. Элементом <Где> мы последовательно конкретизируем область действия подобно тому, как мы делаем это глазами, заодно тестировщикам проще ориентироваться в тесте. Также в Gauge есть автодополнение шагов, которое подскажет варианты шагов по уже введённому тексту — так мы сужаем число подсказок с каждым новым введённым словом: Как не надо: Вводим: “Нажать кнопку “ Получаем в автодополнении все шаги, которые начинаются с “Нажать кнопку “, без учёта контекста текущего шага Как правильно: Вводим: “В модальном окне подтверждения удаления “ Получаем в автодополнении только те шаги, которые относятся к контексту текущего шага Содержимое элементов <Где> и <Действие> может отличаться по детализации и порядку слов в предложении для грамотного написания/удобочитаемости, но общая схема остаётся неизменной. <Где> <Утверждение>  <Объект> <Где> <Утверждение> <Объект> <Значение> В модальном окне “Редактирование уровня доступа”, в поле “Наименование” отображается знак ошибки В модальном окне “Уровни доступа”, в списке уровней доступа не отображается уровень доступа “Администратор” Для поддержания выбранного стиля описания шагов мы договорились проводить ревью (как это делают например в программировании). При реализации шагов, автоматизатор проверяет стиль на соответствии описанному синтаксису. Имея чёткие правила, этот процесс проходит достаточно гладко - без конфликтов и выявляет скорее опечатки, нежели чем грубые несоответствия с изначально выбранным стилем.  Подобное ревью не требует больших трудозатрат и мы рекомендуем выполнять его вне зависимости от стадии внедрения технологии и опытности QA команды, ведь как говорится : “Одна голова хорошо, а две - лучше”.  Так же, однажды проверенные шаги, в дальнейшем переипсользуются и ошибиться просто нет возможности, так как тест просто не запустится. В некоторых случаях может возникнуть необходимость передачи информации между тестовыми наборами/сценариями/спецификациями — в Gauge для этого используются DataStore (хранилище данных): SuiteStore — хранит значения, добавляемые в память при выполнения тестового набора ScenarioStore — хранит значения, добавляемые в память при выполнения сценария SpecStore — хранит значения, добавляемые в память при выполнения спецификации DataStore это, по-сути, HashMap, к которой мы сможем обращаться для записи и получения сохранённого ранее значения и оборачивать это в Gauge шаги. В приведённом ниже примере мы записываем в ScenarioStore число пользователей в списке, чтобы потом проверить, изменилось оно или нет.    Команда тестирования сама пишет Gauge шаги, собирает из них тесты, публикует в Git, разбирает результаты регулярных ночных прогонов и использует тесты в регрессе.  Зависимость от специалиста по автоматизации тестирования на таком проекте стремится к 0 — практически нет необходимости подключаться к разборам регулярных ночных прогонов тестов, т.к. базовые вещи описаны, максимально переиспользуются, а ручные тестировщики сами могут разобраться с подавляющим числом возникающих проблем. В итоге команда тестирования продолжила покрывать проект автотестами, доведя их число до  более чем 2000. Специалисты по автоматизации тестирования смогли переключится на реализацию инструментов синхронизации конфигурации автотестов и TMS системы, о которых мы расскажем вам в следующих статьях. Данная статья поможет вам ознакомиться с Gauge тестами и, возможно, принять решение об использовании этого фреймворка в вашей компании. Но, тут описаны только самые основы и проблемы, с которыми нам пришлось столкнуться. Если у вас есть подобный опыт перевода автотестов на Gauge, будем рады если вы им тоже поделитесь. Мы не сделали всё идеально и нам предстоит ещё детальнее изучить возможности Gauge, задействовать их в нашей работе и распространить полученный опыт на другие проекты. Ссылка на официальную документацию Gauge GitHub с примерами применения Gauge с разными стеками/ЯП Автор: Вячеслав Власов