Автотесты — это важная часть нашей работы, именно они помогают в ее ускорении и снимают рутинную работу с наших тестировщиков. Быстрее проверки, меньше зависимости от человеческого фактора, меньше риск ошибок. А еще (хоть это и не доказано), думаю, автотесты положительно влияют на наш сон. Спится спокойнее, когда покрыты все важные сценарии. Для всех этих плюсов необходимо не только наличие автотестов, но и возможность добавлять новые, обновлять их и регулярно запускать.

Привет! Меня зовут Александра Смирнова, я старший фронтенд-разработчик в команде Календаря, VK WorkSpace в компании VK Tech. На момент начала работы нашей команды в B2B-Календаре для нашего окружения не было отдельных тестов. Мы прошли непростой путь, перед тем как начать писать тесты для B2B-окружения. Хотим рассказать, как встроили наши тесты в существующую инфраструктуру и наладили процессы для их стабильного прохождения. Для краткости я буду называть их «автотесты» или просто «тесты», имея в виду именно интеграционный вид тестирования.

Краткое введение

Как быть, если вы перешли в новый проект, над которым работают несколько команд, а под ваше окружение нет тестов? Как писать новые фичи и быть уверенными, что они не сломали что-то в чужом окружении? Именно этими вопросами задавалась наша команда в начале работы над B2B-Календарем. 

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

У ребят уже был набор интеграционных тестов, заточенных под B2C-окружение. Тесты хранились в отдельном репозитории вместе с тестами других проектов. Нам в B2B предстояло решить, как подружить наши новые тесты Календаря с уже существующими, избежать сильного разделения между окружениями и вписать автоматизированное тестирование в процесс команд, работающих над проектом. 

Сначала мы думали хранить свои тесты отдельно, но постепенно склонялись к идее хранить их там же, где уже были тесты проекта, пусть и для другого окружения. Тогда не пришлось бы создавать инфраструктуру с нуля — ведь там уже есть тесты многих проектов и много общих утилит. С помощью ранера удобно запускать тесты для любых проектов, настроен CI, подключены боты и другое. В итоге решили сделать именно так.

C:\bd9b17b8706b5e5bb82dc719e8d8c5bd

Шаг 1: запуск и документация

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

Итак, тесты запустились в нашем окружении! Это был маленький шаг для человека, но большой для всей команды. Поскольку тесты проверяли набор фичей для другого окружения, было ожидаемо, что много из них упадет. Была и хорошая новость: упавших тестов было меньше половины, и это вселяло надежду.

C:\465a554f9b9cf244686c2967698d2ea5

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

C:\8f904de80dc8a070a0ad96fdcd2da86a

Шаг 2: единое тестирование общей функциональности

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

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

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

C:\fa5c7077f03bb26ded272886cb4b40c3

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

Мы сравнили два подхода к написанию тестов: разделение тестов по окружению и общие тесты по фичам. У общих тестов получились такие плюсы:

  • Переиспользование. В первом варианте мы бы дублировали тесты, проверяющие ту же функциональность, которая нам нужна, а во втором просто переиспользовали существующие.

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

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

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

  • Поддержка тестов. Поправить один тест проще, чем несколько.

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

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

Подход разделения тестов по окружению

Подход с общими тестами по фичам

Переиспользование тестов с одинаковой функциональностью

➖Нужно писать дополнительные тесты с учетом окружения

➕Можно использовать старые тесты другой команды и не тратить время на написание новых для той же функциональности

Запуск тестов под разные окружения

➖Каждый тест только под одно окружение

➕Тест можно запускать на разных окружениях, где присутствует функциональность

Количество тестов на одну фичу

❗️Умножаем на количество окружений

➕ Минимально необходимое

Зависимость от другой команды

❗️Нужно следить за обновлениями в тестах другой команды и в случае обновления заносить их к себе

➕Нет необходимости следить за обновлениями в тестах другой команды

Простота тестирования и надежность

➖При запуске теста на какой-то функциональности нет уверенности, что он не сломал что-то в чужом окружении

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

Простота поддержки, исправление багов

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

❗️Достаточно поправить один тест. Главное — не поддаться соблазну заскипать по окружению, когда он ломается в одном и не ломается в другом

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

Шаг 3: выстраивание процессов создания и запуска тестов

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

В итоге у нас получился следующий флоу: 

  1. При разработке новых фичей создаем задачу на написание к ним автотестов и совместно с тестированием придумываем тест-кейсы.

  2. В ревью кода у нас всегда участвуют разработчики от B2B и B2C. Перед отправкой на ревью тестов мы запускаем прогоны на разных окружениях. 

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

  4. Каждый день бот автоматически запускает тесты на нашем основном стенде, и мы сразу узнаем, если со стендом что-то не так. Если тесты упали, то дежурный разработчик выясняет причину падения и это исправляет. При разработке новых фич также создаем подзадачу на написание к ней автотестов и совместно с тестированием придумываем тест-кейсы.

C:\85d2c996782328d2ffc965f9c4ebc2b8

Вот как выглядит сообщение бота об успешном прохождении тестов ежедневного запуска:

C:\686a506463b0b7af6c744d7684686078

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

Комментарии (0)