Всем привет! Меня зовут Сергей, и сегодня я расскажу о том, как я искал носки мы выстраивали процессы тестирования в команде.

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

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

Дисклеймер:

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

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

Как всё начиналось

Порой легче взять снежный ком, бросить в бесконечное бытие и начать всё сначала.

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

  1. 40% тестов deprecated.

  2. Стек технологий отличается от всей компании.

  3. Покрытие — менее 30%.

  4. Огромный бэклог.

  5. Нехватка ресурсов на поддержку Java-фреймворка.

Мы попытались исправить ситуацию, но тщетно, так как получился огромный снежный ком, который было легче выбросить и начать с чистого листа.

Смена стека

Изначально мы писали тесты на Java, но, поскольку мы решили начать с чистого листа, почему было не пересмотреть язык? И мы сделали выбор в пользу Go. Соседние команды аж в 2019 году начали писать тесты на Go — и у них это неплохо получается до сих пор. 

Спустя полгода наша команда уже выделила несколько плюсов этого решения:

  1. Разработчики и тестировщики используют один язык.
    В нашей компании создан единый CI/CD и настроены одни линтеры, поэтому тесты и код имеют один стиль.

  2. Взаимопроверка разработчиков.
    У нас всего два тестировщика, и порой разработчик имеет большую экспертизу в той или иной фиче. Поэтому по флоу разработчик смотрит код тестировщиков, чтобы дать свой “Approve” на тест-кейсы.

  3. Разработчики могут редактировать тесты.
    У меня и у моих сокомандников нет опыта в разработке на Python и Java, поэтому если бы мы перешли на другой язык, то нам было бы тяжелее погружаться в тесты для исправления чего-либо.

Но смена стека была ознаменована и проблемами.

Разработка инструмента

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

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

Проанализировали опыт соседних команд, но их экспертиза нам помогла лишь отчасти, так как наш бэкенд создаётся для мобильного приложения и между нашим сервером и телефонами клиентов летают JSON, а в других командах в 90% случаев в качестве протокола используется gRPC.

Так как я человек простой, пошёл гуглить инструменты, которые используются для тестирования HTTP-сервисов на Go. Из популярных выделил несколько фаворитов:

  1. httpexpect

  2. apitest

  3. Baloo

Они достаточно мощные для работы в REST API, и мы их все попробовали. Но поняли, что нам они не подходят, так как нам требовались:

  1. Allure-отчёты.

  2. Табличные тесты.

  3. Возможность добавлять свои ассерты.

  4. Коробочные JSON-ассерты.

  5. Multi-step тесты.

Поэтому мы решились на разработку своего инструмента — так появилась библиотека CUTE.

Написание было сопряжено со стандартными проблемами:

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

  2. С функциональностью.
    В самом начале пути наша библиотека не могла конкурировать с аналогичными инструментами, и иногда нам не хватало функциональности.

  3. С наймом.
    В будущем нам предстоит искать тестировщиков, которые будут готовы писать тесты на Go.

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

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

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

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

Обучение и привыкание к языку, или Как мы подружили разработчика и тестировщика

Своя библиотека для тестирования и Go — это хорошо, но наши тестировщики раньше писали на Java. Поэтому встали вопросы обучения и найма специалистов.

Как я писал выше, это наш риск и, возможно, самый высоковероятный риск, поэтому мы прибегли к следующим действиям:

  1. Пишем документацию по использованию внутренних и внешних библиотек. 

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

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

  4. Проводим внутреннее и внешнее обучение использованию Go в тестировании.

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

Процесс

Процесс — это привычка, причём привычка не одного человека, а целой команды.

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

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

Но всё изменилось, когда мы — тестировщики, разработчики и менеджеры — решили объединить усилия. Мы начали переговоры за круглым столом, чтобы договориться со всеми и никого не обидеть.

Из круглого стола мы вынесли несколько хороших идей:

  1. Взаимодействие тестировщиков и разработчиков должно происходить по схеме win-win. Благодаря тому, что мы начали писать тесты на Go, разработчики подключились к code review, к проработке сложных тест-кейсов и другим мелочам, а главное — стали понимать, как написан тест, что он проверяет и как его починить в случае необходимости.

  2. Мы готовы потратить больше времени на тестирование, чтобы увеличить покрытие тестами (а следовательно, и повысить качество нашего продукта) и в будущем уменьшить время на регрессионное тестирование.

  3. Если появляется баг на продакшене, то мы приоритетно пишем автотесты для этого бага.  

  4. Мы разрабатываем автотесты для новых задач сразу, а для старых фич — в «технический день».

В результате всех обсуждений у нас получился следующий процесс:

  1. Аналитика задачи.

  2. Планирование задачи.

  3. Реализация задачи.

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

  5. Написание автоматизированных тестов.

  6. Проверка задачи на общем ручном регрессе.

  7. Релиз задачи.

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

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

Итог

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

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

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

Что можно посмотреть на досуге

  • Выступление руководителя моего направления Антона Макаренко, где он делится опытом работы в нашей команде и не только, но уже с менеджерской точки зрения:

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


  1. kingarold
    18.10.2022 12:56
    +1

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


    1. dskonev
      18.10.2022 15:37

      Согласен, не хватает каких-то метрик, по которым можно было бы оценить, что и насколько в итоге улучшилось.

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


      1. siller174 Автор
        18.10.2022 18:06
        +1

        Привет. Спасибо за комментарии.

        Началось с того, что я решил попробовать написать тест на голом Go, то есть без использования каких-либо библиотек, связанных с созданием e2e тестов. Потом я то же самое проделал с использованием и сравнил. Во втором случае время на разработку уменьшилось, но оно и понятно, так как много логики спрятано внутри библиотеки. (p.s. до принятия решения по разработке CUTE).

        На счет замеров: такого не было, да и провести было бы трудно, так как сейчас мы максимально сделали всё, чтобы старт был простым. Мы написали полностью инструкцию, как освоить библиотеку и как писать тесты, да и примеров тестов создалось немало за прошедший год.

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


  1. dph
    19.10.2022 01:20

    А сравнивали стоимость разработки своего фреймворка с выигрышем от использования go?
    С учетом стоимости переобучения, сложностей найма новых тестировщиков (тестирование на go - не самый популярный подход), стоимостью поддержки своего инструментария?

    Вообще не очень понятна польза от перехода в написании тестов на go.


    1. siller174 Автор
      19.10.2022 16:28

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

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

      Поэтому мой подход отчасти прыжок веры: условно говоря, мои 3 часа разработки CUTE потенциально сокращают работу тестировщика на 10 минут, но таких сокращений может быть сотни, так как тестов создается много. Мне хочется верить, что в этом случае мы всё же наточили пилу, чтобы потом ей быстрее пилить)

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

      Отдельно замечу, что CUTE изначально была небольшой утилитой для нашей команды, но сейчас она применяется и другими командами по их собственному желанию, а некоторые идут дальше и переходят с Python на Go, посмотрев на наш пример.


  1. dph
    19.10.2022 01:22

    И почему у вас тесты начинают писать после реализации задачи, а не после планирования? По идее уже все необходимые API должны быть к этому времени согласованы, зачем тогда ждать? Глядишь, в этом случае и времени на автотесты хватило бы.


    1. siller174 Автор
      19.10.2022 16:28

      Пока не все процессы идеальны, но мы думаем, как к этому стремиться и периодически что-то пересматриваем. Думали об этом тоже, спасибо за совет!