Как с помощью автотестов не сойти с ума, поддерживая молодой быстрорастущий веб-сервис: подробная инструкция

На связи команда Айтигро. В статье подробно расскажем, что такое автотесты, когда и как их нужно и не нужно использовать, а также на конкретном примере разберем опыт внедрения автотестов в проекте «Наигру».

Автотесты в веб-сервисы Наигру: сценарии
Автотесты в веб-сервисы Наигру: сценарии

Что такое автотесты простым языком?

Если совсем просто, то это когда вместо человека тестирование производит программа. Первые автотесты появились в эпоху бородатых систем DOS. В общем технология не новая и человечество в этом вопросе набило немало шишек.

В интернете встретили хорошую аналогию: представьте что мост — это программа (или в нашем случае веб-сервис). По мосту запускаем полностью нагруженный товарный состав (виртуальный трафик). Когда поезд едет по мосту, на котором установлены датчики, мы получаем информацию о трещинах, деформации балок, разрушении железнодорожного полотна. Это есть end-to-end тестирование (подробнее описано ниже). А вот если добавить, что после каждого изменения моста (добавление балки, изменение геометрии опор и т.д.) поезд запускается автоматически, а датчики, улавливая ошибку, не пропускают его дальше – то это уже автоматическое end-to-end тестирование.

Простое тестирование – это когда после изменения конструкции моста мы запускаем поезд вручную и смотрим, оцениваем, выдержит ли мост поезд или нет (и ставим под мост тестировщиков и разработчиков, ха-ха).

С определениями разобрались. Поехали дальше.

Что и как можно автоматически тестировать?

Автоматически можно тестировать программный код или пользовательский интерфейс. В статье мы будем говорить про автотесты через пользовательский интерфейс.

Если говорить совсем точно, статья будет про автоматическое end-to-end (E2E, сквозное) тестирование, имитирующее пользовательскую среду и поэтапно моделирующие действия пользователей.

Автоматическое end-to-end (E2E) тестирование — это процесс автоматического тестирования с подробной эмуляцией действий пользователя: кликаньем мышки, переходами по страницам, заполнения форм и так далее. Цель E2E тестирования — удостовериться, что программа работает именно так, как задумано для конечного пользователя.

E2E тестирования обычно проводится в самом конце перед «выкаткой» изменений или доработок на рабочие версии продуктов. Поэтому ошибки, возникающие при некачественном E2E тестировании, могут быть очень дорогими.

Пример. Мы «выкатываем» приложение с потенциалом 10 000 регистраций в месяц. Предположим, мы не заметили, что после изменения одной из функций пользователи не видят модальное окно об успешной регистрации и это снижает общую конверсию на 5%. Стоимость одной регистрации составляет 15 долларов. За первый месяц мы потеряем 7 500 долларов.

Типы E2E тестирования: черный и белый ящик

Метод черного ящика — метод тестирования, при котором проверяется только интерфейс. Ошибки в логике не отслеживаются.

Метод белого ящика — метод тестирования, при котором проверяется сопоставление работы программы с эталоном.

Мы в проекте использовали метод белого ящика и проверяем правильность работы не только блоков интерфейса, но и логики.

Как мы пришли к автотестам в проекте Наигру

Наигру – это веб-сервис для организации спортивных игр, помогающий организаторам создавать тренировки, а участникам записываться на них.

Когда в проект добавилось множество механик, из-за которых структура проекта стала разрастаться, на проекте стали возникать ошибки там, где мы их совсем не ожидали. Возникла классическая проблема: дорабатывая дополнительный функционал начал ломаться базовый.

Например, перестала работать кнопка «Записаться на игру» после доработки механизма перехода игроков из резерва в основной состав. Или при создании регулярных игр возникали баги в обычных разовых играх – например, при записи на игру не показывалось модальное окно об успешном действии и пользователь не мог понять, записан ли он.

Наигру: Ошибка "Не показывается модальное окно"

Эти функции не являются взаимосвязанными, поэтому отследить такие ошибки ручным тестированием было сложно и удавалось не сразу.

Ручное тестирование

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

Регрессионное тестирование делится на 3 уровня: проверка нового блока, проверка ранее добавленных блоков, а также проверка связанных и не связанных сторонних блоков после добавления или изменения блока. В среднем одно такое тестирование занимало два рабочих дня.

Стало понятно, что с течением времени такое тестирование станет сильно тормозить ход развития проекта, а именно добавление новых функций.

Подготовка к автоматическому тестированию

Пришли к выводу, что рациональнее будет автоматизировать проверку всех основных сценариев. В описываемом проекте примерами таких сценариев являются:

  • Регистрация/авторизация пользователей

  • Создание и редактирование игры
  • Запись на игру
  • Отписка игрока от тренировки
  • Запись в резерв, переход в основной состав

Сформировали алгоритмы поведения пользователей

Например, проверка регистрации: сайт открывается → выбор чекбокса города Москва → нажатие "Сохранить" → нажатие на "Войти или создать аккаунт" → проверка ошибки неправильно заполненного телефона → ввод сгенерированного номера → нажатие "Войти" → проверка наличия авторизации после регистрации и выход из профиля.

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

Затем подготовленные тесты разбили так, чтобы разные алгоритмы можно было проверять независимо друг от друга. Таким образом, мы создали систему автотестов, которую легко поддерживать – при добавлении функционала достаточно добавить новые файлы спецификаций в готовую структуру.

Наигру: проверка алгоритма действий организатора
Наигру: проверка алгоритма действий игрока

Что получили в итоге?

После сборки проекта любые изменения при переносе кода на последний шаг перед публикацией автоматически запускают автотест, а результат отправляется на почту ответственным за проект сотрудникам – в том числе разработчикам проекта.

То есть новые функции или изменения в принципе не могут быть запущены на рабочем сайте без прохождения автотестов. Это последний рубеж защиты от программных ошибок и экономических потерь бизнеса.

Отчет об автоматическом тестировании (пайплайн)
Отчет об автоматическом тестировании (пайплайн)
Email с отчетом по итогу автотестирования
Email с отчетом по итогу автотестирования

Дополнительно настроено регулярное тестирование базовых функций сайта: регистрации, ввод телефонов и так далее. Проверка запускается по таймеру независимо от внесения изменений в проект.

Было/стало

Ручное тестирование:

  • Тестировали только функционал, который дорабатываем – пропускали непрогнозируемые ошибки базового функционала
  • Узнавали о проблемах по факту – тратили много времени на поиск причины и на ее устранение

Автотесты:

  • Без полной проверки базового функционала на рабочий сайт не попадает ни одна доработка
  • Узнаем о проблеме заблаговременно и затрачиваем меньше ресурсов на устранение

В итоге мы создали инструмент помощи разработчикам — теперь мы находим баги на раннем этапе разработки и устраняем их раньше, чем их найдет тестировщик или пользователь.

Про инструментарий (Внимание! Начинается техническая часть)

Опробовав сначала сервис Селениум для написания автотестов, остановились на Сайпрес – он имеет подробнейшую документацию и оказался для наших тестировщиков более удобным для написания тестов и отладки.

Селениум:

  • Не user-friendly
  • Сложнее отследить, на каком моменте тест провален – отсутствует система репортов

Сайпрес:

  • Удобен для написания тестов и отладки – продуманный интерфейс
  • Наглядно показано (информация и скриншот), на каком моменте и по какой причине тест провален

У каждого инструмента есть свои нюансы

Например, Cypress, на котором остановились мы, не сохраняет Cookie и LocalStorage между тестами. В нашем случае это влияет на сохранение данных о пользователе между тестами (данные об авторизации), чтобы алгоритм работал так, будто действия создает один и тот же пользователей. Для устранения этой проблемы мы подобрали плагин (cypress-localstorage-commands), который сохраняет необходимые данные между тестами, а также настраивали файл конфигурации, чтобы сохранялись Cookie.

Файл конфигурации: сохранение Cookie
Файл конфигурации: сохранение Cookie

Но если вы выбираете развивающийся инструмент, такой как Cypress, то часть подобных проблем может быть закрыта в следующих обновлениях ПО (так было и в нашем случае – после обновления мы стали использовать экспериментальные функции сессий).

Экспериментальные функции сессий: сохранение Cookie
Экспериментальные функции сессий: сохранение Cookie

Отдельные элементы кода

Капча (CAPTCHA) тоже может мешать запуску автотестов – в рамках тестов настроили авторизацию по POST-GET запросу к API, минуя интерфейс авторизации.

Авторизация по POST-GET запросу к API
Авторизация по POST-GET запросу к API

Разновидность сайта

Есть и свои нюансы автотестов для разных типов сайтов. Наигру реализован как Single Page Application – для такого рода сайтов “скриптовые” ошибки, которые не являются критичными для работы сервиса, мешают работе теста. Их приходилось отключать, чтобы предотвращать провалы теста, так как инструмент не пропускал алгоритм дальше.

Скриптовая ошибка
Скриптовая ошибка

Структура кода

Когда код писался без оглядки на то, что будут настраиваться автотесты, может возникнуть несогласованность архитектуры необходимым требованиям для построения механизма теста.

В проекте Наигру подобной проблемой стало расположение селекторов в структуре HTML-древа. Как итог – невозможно настроить тест таким образом, чтобы он понимал, какому конкретному организатору принадлежит игра. Этот момент необходимо учитывать при построении алгоритма тестирования

Необходимые навыки для создания автотестов

С автоматизаций тестирования вполне справится опытный тестировщик.

Для этого специалисту необходимо:

  • базовые навыки программирования и знание JavaScript (преимущественно автотесты пишутся именно на нем)
  • знание Node.js – помогут при установке плагинов и настройке связей между спецификациями
  • понимание особенностей построения архитектуры HTML-древа и работы селекторов
  • знание Git – для более эффективного взаимодействия с командой разработки, поможет создавать “коммиты” и загружать их в проект

Чтобы специалисту за довольно короткое время освоить автотестирование понадобится документация выбранного инструмента автоматизации и парочка роликов на youtube. Наш тестировщик вдохновлялся каналом Глеба Бахмутова.

Со сложными для понимания вопросами можно обратиться к коллеге-программисту уровня мидл и выше.

Важно: для корректной работы автотестов их нужно включить в общий процесс разработки. Для этого потребуется пара часов времени программиста проекта.

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

Золотое соотношение в видах тестирований

В отрасли применяют разные соотношения между ручными и автотестами. Например, в Google автотесты занимают около 10% от всего вида тестирования, а остальные тесты выполняются специалистами вручную.

Главное правило звучит так: автотестов должно быть существенно меньше, чем обычных – иначе это приведет к существенному удорожанию поддержки проекта.

Мы не советуем покрывать автотестами более 10-15% функционала.

Заключение

С точки зрения реализации – автоматическое тестирование можно сделать под любой проект.

Преимущества автотестов:

  • Быстро находят критичные ошибки
  • Нет человеческого фактора – непредвзятые
  • Накапливают сценарии для регресс-тестирования

Слабые места:

  • Требуют постоянной доработки
  • Могут возникнуть сложности при разработке теста, если изначально на проекте не предполагалось использовать автоматическую проверку
  • Польза от автотестов не всегда окупает затраты на их подготовку (если базовый функционал проекта постоянно изменяется, то и автотесты придется менять каждый раз вместе с ним – в таком случае это будет занимать больше времени и сил, чем ручное тестирование)

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

Довольно сложно создать и поддерживать сценарий, который покроет весь функционал и будет корректно проверять максимально много. Но это и не нужно. Цель автотестов – быстро проверять работу основных механизмов, ошибки в которых являются критичными и могут повлечь за собой снижение производительности.

Если вы запускаете крупный проект либо активно развиваете уже существующий, и хотите избежать критичных ошибок, рекомендуем рассмотреть к внедрению автотесты.

Пожалуйста, поставьте статье upvote (стрелочка вверх), мы старались :)

1111
5 комментариев

Интересный и очень познавательный опыт автоматизации.
Пару замечаний, что сразу бросается в глаза:

"Необходимые навыки для создания автотестов:
базовые навыки программирования и знание JavaScript (преимущественно автотесты пишутся именно на нем)".

Сейчас автотесты можно писать на любом высокоуровневом языке программирования. И я бы даже сказал, исходя из своего опыта, что наиболее часто выбор падает на Java либо Python. Но всё зависит от технологий, которые используются на проекте.

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

2

Очень полезная статья! Подскажите, какой пайплайн использовали для оповещения о результатах тестирования?

Благодарим за вашу оценку нашей работы!

Пайплайны Gitlab мы используем только для автоматического развертывания всех изменений кода в тестовой среде и непосредственно для запуска автотестов.

Оповещение о результатах тестирования на email реализовано с помощью плагина для Cypress (Email Cypress Test Report)
и с помощью стандартных возможностей Gitlab (присылает уведомления о провале операции - то есть хотя бы 1 из тестов).

1