Виктория Исаева
Старший специалист по тестированию ГК Юзтех
Всем привет! Меня зовут Виктория Исаева, я старший специалист по тестированию ГК Юзтех. В этой статье я хочу поделиться нашим опытом внедрения фреймворка Karate для автоматизации ручного тестирования на проекте.
В статье вы узнаете:
Почему мы выбрали фреймворк Karate;
Сколько времени понадобилось на то, чтобы вникнуть в работу с этим фреймворком;
С какими трудностями мы столкнулись;
Советы для начинающих и не только по работе с Karate.
На нашем проекте существовал ряд автоматизированных сценариев по основному функционалу системы, написанных на ЯП Python разработчиками когда-то очень давно. К сожалению, из-за большой загрузки разработчиков заниматься автоматизацией стало некогда и некому, из-за чего мы с командой приняли решение внедрить фреймворк Karate.
Минусы такого перехода мы понимали и осознавали: потребность переписать уже написанные на питоне тесты, необходимость прибегать к Java при недостаточности синтаксиса Gherkin (а у нас в команде только питонисты). Но плюсов оказалось гораздо больше: сценарии пишутся на человеко-читаемом языке, что особенно полезно в командах, где отсутствуют знания языков программирования. Для тестировщиков мотивацией стало то, что они смогут повысить свои знания, научиться чему-то новому и полезному. Чтобы вы понимали, теперь мы не дергаем каждый раз разработчиков с вопросами: «А почему тест упал?», «А когда почините?» и не просто следим за результатами е2е-тестов (как раньше). В настоящее время написанием сценариев заняты только тестировщики: также мы фиксим нестабильные тесты, актуализируем сценарии после доработок разработчиков. Ребятам нравится удобство работы с тестами (при локальной разработке), а также простота дебага — можно увидеть, в чем проблема, не смотря в код. Еще из плюсов: можно автоматизировать как проверки API, так и функциональные кейсы; есть возможность использовать фича-файлы из содержания другого фича-файла; по итогу имеем подробную отчетность по каждому сценарию. На будущее фреймворк мы рассматривали как прекрасный вариант для интеграции с Gatling (для нагрузочного тестирования), и в конце 2023 года успешно проделали нагрузочное тестирование ни один раз в рамках срочных задач.
В самом начале пути мы с лидом разработки сделали небольшой ресерч и провели ряд расчетов: вычислили, сколько времени понадобится на интеграцию фреймворка в проект плюс приблизительную стоимость одного теста, написанного на Karate. Развертыванием фреймворка занимался младший разработчик — спасибо ему за вклад в развитие е2е-тестов на проекте. Настроив окружение и получив пару мастер-классов от разработчиков по работе с Karate и Git, мы принялись за освоение синтаксиса по имеющейся в открытом доступе документации (к слову, она очень неплохая и ее вполне достаточно для работы). Спустя несколько месяцев мы проанализировали работу и выяснили, что нам:
Удалось написать порядка 30 сценариев по интеграции с соцсетями — таких сценариев не было ранее реализовано в Python-тестах;
Удалось погрузить всю команду тестирования в новый фреймворк и обучить их базовым навыкам по работе с Git и Gitlab;
Ранние данные оценки по трудозатратам на написание одного е2е-теста совпали, что не могло не радовать.
По итогам анализа была поставлена новая цель — автоматизировать 50% регресса (основную функциональность системы, которой пользуются все пользователи и заказчики) для ускорения ручных проверок. Выбрали именно такую цель опять проделав ресерч: расписали плюсы и минусы от автоматизации «старых» пунктов регресса (основной функциональности, которой пользуются все) и от автоматизации новых фичей. Но совсем скоро наши планы рухнули, а автоматизация встала на несколько месяцев из-за сложностей согласования работ с заказчиком. Позабыв, что и как мы автоматизировали, просидев ни один месяц без автоматизации, мы наконец-то смогли вернуться к написанию сценариев, но с одним условием: старую функциональность не автоматизируем, пишем тесты только по свежеиспеченным фичам после релиза. Эта новость воодушевила всю команду.
Отдельно отмечу временные интервалы: с появления разговоров о внедрении фреймворка до постановки автоматизации на «паузу» прошло около 8 месяцев, из них команда тестирования была погружена в автоматизацию не так много (больше этим занималась я), так как нагрузки по иным активностям на проекте было достаточно: каждый тестировщик попробовал себя в написании е2е-тестов и понял, хочет ли продолжать заниматься ими в дальнейшем.
С возвращения на путь автоматизации после затяжной паузы в 5 месяцев до текущего момента прошло уже четыре месяца и вот, что мы имеем на данный момент: 120 автоматизированных сценариев, которые помогают нам не только во время регрессионного тестирования, но и обнаруживают баги сразу после влития доработок по новым фичам разработчиками. Некоторым тестам также был проставлен полезный тег «@smoke», что помогает запускать лишь порядка 20 сценариев по особо важному функционалу в нужные минуты. На данный момент релиз-инженер занимается передачей таких тестов на продуктивные стенды для сокращения ручных проверок во время дежурств на релизах.
С какими трудностями мы столкнулись при выборе Karate:
В отчетности доступен только последний прогон тестов — предыдущие отчеты «теряются», из-за чего невозможно вести статистику по ломающимся тестам (планировали отправлять после каждого прогона архив с отчетностью в Телеграм, чтобы можно было анализировать результаты, но задача пока не согласована);
Тесты по интеграции с социальной сетью «ВКонтакте» ломали отправку отчетов (и до сих пор иногда ломают): было принято решение вынести эти тесты в отдельную папку, чтобы отчетность по всем остальным тестам успешно отправлялась по завершении прогона;
Непонятны трудозатраты на поддержку е2е-тестов (изменение верстки внутри нашей системы, изменение архитектуры, изменение верстки внешних сервисов). Вероятно, это общая проблема всех е2е-тестов.
А теперь несколько советов для тех, кто захочет также интегрировать фреймворк Karate на свои проекты:
Добавляйте больше retry’ев в свои сценарии, желательно с указанием дополнительных параметров в скобках (к примеру, «retry(5, 5000)» говорит нам, что 5 раз (по 5 секунд каждый) будет проверяться/ожидаться что-либо — это особенно актуально для наших е2е-тестов, так как иногда необходимо дождаться получения сообщения из соцсетей, прогрузку панели фильтров и тому подобное);
When retry(5, 5000).waitForUrl(host + "#/settings/hooks")
Избегайте конструкции с locate() по возможности: это очень опасная вещь, которая может ломать отправку отчетов по итогам прогона тестов, а также одно из самых частых мест падения тестов (если что-то не прогрузилось на странице, сразу падаем на строчке с «locate()»). Имейте в виду, что иногда без этой конструкции не обойтись — нужно просто предусмотреть прогрузку необходимых данных до указания локейта;
* def filterTheme = function(x){ return x.script("_.textContent").contains(nameOfTheme) }
* def listTheme = locateAll(".table__line", filterTheme)
* listTheme[0].click()
Можно прибегать к использованию функций, написанных на Java: не всегда синтаксиса Karate хватает для написания сценариев, из-за чего мы выделили целый ряд полезных функций, написанных на Java, к примеру: генерация рандомного набора символов; получение текущих даты и времени (важный нюанс: если решение не взлетало, мы обращались за помощью к разработке);
* def todayDate =
"""
function() {
var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
var sdf = new SimpleDateFormat('yyyy-MM-dd');
return sdf.format(new java.util.Date());}
"""
Не расстраиваться, если тест падает при написании казалось бы «рабочего» кода. Попробуйте поискать альтернативы в документации: мы несколько раз пытались прописать ожидание элемента и клик по нему/ввод текста самым распространенным способом «waitFor('#id_елемента).click()» или «waitFor('#id_элемента').input(‘Текст’)», которые ни к чему не приводили. Но помогли следующие варианты (второй более сложный, добрались до кликабельного поля с типом «Дата» через инпут, а выбор текущей даты прекрасно работает через клик):
1. value('#id_элемента’, ‘Текст’)
When value('#id_ALLOWED_FILE_TYPES', '[]')
2. locate('#id_элемента’).input('')
locate(".класс_элемента").click()
* def calendar = locate('p-calendar')
* calendar.locate('.ui-inputtext').input('')
* def today = locate(".ui-datepicker-today")
* today.locate('a').click()
А с чего вообще начать? Начинайте с написания сценариев по CRUD-проверкам, это прекрасная разминка перед началом большого забега в мир автоматизации!