Как мы в Tutu.ru добиваемся эффективности каждого из 9000+ UI-тестов

в 7:06, , рубрики: automation testing, qa automation, ui testing, Блог компании Туту.ру, тестирование, Тестирование веб-сервисов

Любой проект в процессе своего развития и роста наполняется новыми функциональными возможностями. QA-процессы должны на это оперативно и адекватно реагировать, например, увеличением количества тестов всех видов. В этом докладе мы будем говорить про UI-тесты, которые играют важную роль в создании качественного продукта. Система автоматизации UI-тестирования не только в разы сокращает время на регрессионное тестирование, но и обеспечивает эффективную работу таких инструментов и процессов разработки, как Continuous Integration и релиз-инжиниринг.
Количество тестов постепенно растет от 1000 к 3000, от 6000 к 9000+ и т.д., и, чтобы эта «лавина» не накрыла наш QA-процесс, нужно с самого раннего этапа развития проекта автоматизации думать про эффективность всей системы и каждого теста в ней.
В этом докладе я расскажу, как сделать систему гибкой к запросам, поступающим от бизнеса, а также про эффективное использование каждого из тестов. Кроме того, мы поговорим про оценку и метрики не только процессов автоматизации, но и всего QA.

План доклада:

  1. Начнем с принципов «тестостроения», которые делают нашу систему максимально удобной для использования;
  2. Разберем способы интеграции системы UI-тестирования в процессы QA-команды;
  3. Посмотрим на конкретные приемы улучшения эффективности каждого теста;
  4. Поговорим про метрики системы UI-тестирования и про её взаимоотношения с проектами Continuous Integration и релиз-инжиниринга;

Требования к системе UI-тестирования и принципы «тестостроения»

К системе автоматизации UI-тестирования мы предъявляем следующие требования: системой должно быть легко пользоваться, она должна быть интуитивно понятна, поддержка тестового покрытия не должна отнимать много времени, система должна быть устойчива к ошибкам в коде тестов и, наконец, система должна быть очень производительна.
Исходя из этого, самый первый и самый важный принцип — максимальная простота восприятия тестов. Это нужно для того, чтобы каждый тест был понятен для любого сотрудника, который умеет читать по-английски.
Используйте высокий уровень абстракции и правильный нейминг функций, переменных и т.д, следите за этим во время проведения код-ревью.
Следующий принцип — каждый проект должен быть максимально независимым от других. Это нужно для того, чтобы каждый проект мог ставить для себя индивидуальные цели и задачи и во время работы над ними не мешал развиваться другим проектам.
Все ваши изменения в коде обязательно должны проходить код-ревью при помощи системы контроля кода. Советую пользоваться той системой, которой пользуются разработчики в вашей команде.
Используйте pre-push и post-commit хуки для защиты работоспособности «ядра» вашей системы. Как минимум, запускайте в них юнит-тесты.
Юнит-тесты — это тесты, которые позволяют проверить на корректность отдельные модули исходного кода программы. Важно не путать юнит-тесты и UI-тесты — они не взаимозаменяемы, они дополняют друг друга.
У нас вся core-часть проекта покрыта юнит-тестами, в данный момент их больше 500. Мы запускаем их при каждом пуше и коммите в репозитарий.

UI-тестирование в процессах QA-команды

Как мы проинтегрировали систему UI-тестирования в команды и в продуктовые процессы. Главная цель — любые тесты должны приносить пользу с самого раннего этапа разработки. Как только тест написан, он сразу же попадает в систему Continuous Integration. Поддержка тестового покрытия должна быть стандартной частью тестирования задачи. Поэтому в Туту.ру нет тестировщиков, которые занимаются только ручным тестированием. У нас каждый специалист занимается полным спектром тестирования.
Задача не должна «мерджиться» в master, если она ломает какие-либо тесты. Постоянно держим это в голове, даже если заказчик торопит.
Трудозатраты каждого этапа QA-процесса должны мониториться.
Несколько наших графиков: детализация трудозатрат на релизный цикл и на его ключевые этапы одной из команд в человеко-часах. Команды показывают разные результаты, но цель у них одна — уменьшить трудозатраты с сохранением заявленного уровня качества.

Детализация релизного цикла
Детализация релизного цикла одной из команд в человеко-часах

Основные этапы релизного цикла
Трудозатраты на основные этапы релизного цикла одной из команд в человеко-часах

UI-тесты в релизном цикле

Самое важное — запуск тестов должен происходить как можно чаще, согласно этапам разработки задачи. Каждый этап должен проходить с максимально «зелеными» тестами, и за этим мы следим. Для некоторых этапов мы используем специально собранные для них комплекты тестов Стоит отметить, что каждый комплект — это выборка из общего пула тестов, соответственно, тесты из разных комплектов могут пересекаться.

Любая разработка начинается с этапа «story branch». На этом этапе мы запускаем комплект тестов, который формируется тестировщиками. Запускать его может кто угодно — разработчик, тестировщик или аналитик. Проводится актуализация тестового покрытия, и в этом участвует ответственный за тестирование данной задачи сотрудник QA-отдела.

Следующий этап — Pre-rc. Это «ночные сборки». Специальная ветка собирается на тестовом стенде каждый день. На ней происходит прогон всего пула тестов, которых у нас больше 9000. Каждая команда использует результаты этой работы. На этом этапе происходит финальная доработка тестового покрытия.

Следующий шаг — RC. Это наш релизный процесс, релизимся мы два раза в неделю. Используется для этого специальный релизный комплект тестов, и на этом шаге тесты должны быть практически все «зеленые», если что-то не так, это исправляется.

Финал — релиз (stable). На релизе также используется релизный комплект тестов.

Поддержка проекта

Отдельная роль — саппортер проекта, для оперативного решения проблем QA-команды. Для команды очень важна постоянная поддержка работоспособности инструмента. Мы пользуемся Service Desk для того, чтобы каждый сотрудник мог получить поддержку при использовании системы.

Улучшаем эффективность каждого теста

В этом разделе я расскажу про конкретные инструменты, которые шаг за шагом делали использование UI-тестов удобнее и, соответственно, повышали эффективность системы.

Проект контроля и управления тестовыми контейнерами

Тестов много. Система мультипоточного запуска состоит из более чем 150 тестовых контейнеров, за которыми нужно следить. Мы сделали инструмент, который позволяет управлять тестовыми потоками, предоставляет информацию о загруженности и дает наилучшую интеграцию с модулем Runner.

Servers_queue
Интерфейс системы управления контейнерами для UI-тестов

Свой Runner тестов

Мы написали Runner UI-тестов. Для нас первостепенным было низкое потребление ресурсов. Нам важна гибкость в развитии — нужно отвечать на требования бизнеса. Runner умеет балансировать загруженность своей системы с учетом приоритетов запусков. Запуски релизного цикла и циклов devel-окружения имеют разные приоритеты. Runner балансирует их, учитывая эти условия. А еще он обеспечивает лучшую интеграцию с другими модулями системы.

Внутреннее устройство

Специальный php-скрипт формирует из репозитария очередь тестов. Она попадает в наш модуль мультипоточного запуска, где он fork’ается на отдельные тесты (PHP-процессы). Каждый такой отдельный процесс имеет доступ к базе данных, где получает данные пользователя, под которым тест будет выполнен.

Core
Схематичное устройство модуля Runner

Тест-кейсы и управление тестовыми комплектами

Тестовую документацию мы храним рядом с кодом тестов, таким образом мы связываем UI-тесты и тест-кейсы в одно целое, особенно это удобно при формировании отчетов, у каждого теста есть описание, по которому можно быстро понять, какие именно риски он собой закрывает. Реализован данный функционал при помощи PHPDoc.

Для уже покрытых тест-кейсов используется тег case:
case

Для тест-кейсов, которые еще не реализованы в коде, — тег todocase:
todocase

Для тест-кейсов, которые нужно проводить только вручную, — тег manualcase:
manualcase

Расчет тестового покрытия

Также, при помощи механизма тегов мы автоматически считаем UI-покрытие каждого из проектов. Расчет по формуле:
Процент_покрытия = 100 — ((количество_todocase-тестов + количество_manual-тестов) / общее_количество_тестов_в_проекте * 100)

coverage
Вывод консоли с процентом покрытия UI-тестов для проекта «Автобусы»

Управление тестовыми комплектами

Тот же самый механизм мы используем для того, чтобы управлять тестовыми комплектами. К примеру, мы используем тестовые наборы для определенной функциональности, есть наборы для релизного, RC-циклов, и вообще, создание наборов ограничивается только фантазией QA-специалистов. Каждый тест может быть включен в несколько наборов, мы их обозначаем при помощи тега @labels.

labels
Тест относится к релизному комплекту тестов

runByLabels
Пример запуска комплекта тестов на функциональность success-страницы

HTML-репорт

Репорт формируется индивидуально для каждого запуска. Каждый запуск тестировщик может сделать руками и получить в виде отчета HTML-страницу, тем самым QA-специалист получает возможность быстрой оценки качества продукта. HTML-репорт уменьшает время актуализации тестов. Отчеты есть в инструменте CI, но тестировщику иногда полезно увидеть отчет именно в своей рабочей копии.

«Soft asserts»

PHPUnit, как и любая другая система unit-тестирования с ассертами работает так: если ассерт сталкивается с несовпадением данных, то выполнение теста не продолжается. Мы изменили эту парадигму. «Мягкие» ассерты, как мы их называем, когда сталкиваются с проблемой, не прерывают выполнение теста, а продолжают его выполнение со всеми другими ассертами, и, в конечном счете, тест завершает свое выполнение ошибкой на teardown-этапе. Таким образом, мягкие ассерты позволяют дать информацию о качестве целого блока в рамках одного теста, даже если в данном блоке есть какие-то проблемы. Такие ассерты более безопасны в сложной тестовой логике. Для примера: у нас есть тест, который делает заказ с банковской карты на реальные деньги, и мы не хотим, чтобы этот тест «упал» где-нибудь после оформления заказа и не успел его отменить.

Гибкая система настроек запуска

Она была создана, чтобы отвечать потребностям QA-специалистов, а именно — обеспечивать наилучшую интеграцию с CI. Написана она при помощи Symfony Console и на данный момент имеет более 30 параметров.
Несколько из них:
On-demand. У нас есть тесты, которые имеют высокую рискованность и не запускаются автоматически. Они запускаются, если тестировщик указывает в параметрах запуска «on-demand».
Bug-skipped-тесты. Тесты, которые заблокированы какой-либо проблемой в продукте, можно пометить специальным лейблом, и эти тесты не будут запускаться в системе CI. Чтобы поймать ситуацию, что продукт исправил что-то, и тест уже можно обратно выключать, у нас есть специальный план, который запускается раз в неделю, и он запускает только те тесты, которые сейчас деактивированы.
Js-error-seeker. Этот тест особенно полезен для фронтендеров. Фронтендеры и тестировщики используют эту возможность для того, чтобы во время прохождения теста делать проверки на js-ошибки. При помощи данного механизма мы можем отловить js-ошибку на всем пути работы теста.
Notify-maintainers. У каждого теста может быть майнтейнер. Это сотрудник, который несет ответственность за этот тест и хочет получить уведомление, если данный тест упадет. Вышеуказанный флаг включает это уведомление.

Метрики

Проект контроля и управления тестовыми контейнерами умеет мониторить загруженность системы, тем самым показывая точки роста системы.
Графики прохождения тестов на разных стендах по времени. У нас установлен лимит в 60 минут, если какой-либо проект выходит за это время, то это повод пойти в проект и разбираться, почему комплект тестов так долго проходит.

testsTime
Время прохождения тестов по проектам на Production

Релиз-инжиниринг

Здесь мы поговорим про то, как инструмент UI-тестирования должен взаимодействовать с проектом релиз-инжиниринга.
Что умеет связка системы UI-тестирования и Bamboo: запускать билды, формировать отчетность, поддерживать релизный процесс, автоматически запускать билды по расписанию. Также есть возможность автоматического «отката» релиза, если smoke-набор тестов показал, что что-то пошло не так.
В системе CI может быть большое количество различных планов, и это абсолютно нормально, не стоит этого опасаться.

Выводы

  1. Каждый тест должен запускаться как можно чаще;
  2. Взаимная интеграция модулей системы UI-тестирования очень важна, ради этого стоит писать свою реализацию;
  3. Система должна быть гибкой и поддерживаемой, готовые инструменты не всегда отвечают этим запросам;
  4. Следите за показателями QA-процессов и улучшайте их, как только видите, что что-то идет не так;
  5. QA должно быть частью процесса разработки, наши инструменты должны это поддерживать.

Автор: Максим Сахаров

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js