Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Тестировщики нужны, чтобы не было багов. Тестировщик спасает софт от погружения в пучину безумия, без него не построить качественный продукт. Без тестировщика команда обречена постоянно тушить пожары на проде, софт будет глючным. Один человек спасает команде много времени и нервов, а компании экономит кучу денег.
Ведь так?
Мы провели эксперимент и проверили это на практике. Больше полугода мы проработали без тестировщика в команде, и сейчас пора посмотреть, что из этого получилось.
Кто мы такие? Мы - команда в крупной финтех-компании, отвечаем за небольшую часть сервисов, на которых работают продукты с миллиардным оборотом. Из фронтенда у нас только админка, остальные фронты живут в других командах и вызывают наши сервисы через REST API или асинхронно. Я - не очень опытный тимлид команды.
Это лонгрид, время чтения ~15 минут, часть подробностей убрал под спойлеры, чтобы сэкономить время тем, кому захочется побыстрее добраться до комментов :)
TL;DR
Были длинные проблемные релизы, раз в 1–2 месяца, Continuous Delivery и не пахло. Было больно. Убрали тестировщика вообще, регресс заменили тестами: Unit + Integration и end‑to‑end автотестами. Теперь регресс делается быстро, код всегда готов к релизу, релизы соседних сервисов теперь независимы друг от друга, а все изменения между релизами обратно совместимы. Релизим часто, качество не просело, команда в целом довольна. Есть и неудобства, поэтому сейчас хотим себе фуллстек‑QA с упором на автотесты.
Как мы жили, от чего страдали
Давайте сначала расскажу, чего нам спокойно не сиделось и зачем мы вообще затеяли наш эксперимент.
Как мы релизили
До начала эксперимента мы релизили софт так, как в 2010-е было мейнстримом в средних и крупных компаниях. Опишу в двух словах для понимания.
Релиз планируем заранее, составляем список задач на релиз, и по мере выполнения задач тестировщик проверяет их на тестовом стенде.
Когда сделали все задачи, входящие в релиз, делаем код фриз - например, в виде релизной ветки. В неё перестаёт попадать код по более новым задачам.
Чтобы выкатить релиз, тестировщик делает регресс, фиксятся найденные баги.
После выкатки тестировщик делает смоук тесты, а остальные сидят наготове, чтобы фиксить проблемы, возникающие после релиза.
Релиз у нас был каждые 1-2 месяца.
Что с этим было не так
Узнаёте ли вы проблемы своих прошлых или текущих проектов в этих мини-историях, состоящих из потока мысли разработчика?
пара зарисовок из нашей жизни тогда
История 1:
Релиз застревает в тестировании, в итоге дата релиза сдвигается на неделю-две
После релиза вы находите баг на проде
И надо снова делать релиз
И опять надо нести его в тестирование
…
А тут ещё из другого сервиса срочно просят докинуть фичу в API, там делов на 2 часа
И опять на регресс
История 2:
Сделал задачу, залил код
Взял в работу следующую
Через 3 дня приходит тестировщик - в задаче баг
Пофиксил баг
Через день приходит тестировщик с другим багом
Пофиксил и его
Через день снова приходит
Смотришь постановку – ничего не понятно
Идёшь разбираться - выясняется, что это и не баг вовсе, или баг, но не в той задаче
…
И через 2 недели снова приходит – завтра релиз, делали регресс, нашли на препроде баг...
В каждый релиз входит много изменений, поэтому релиз надо тщательно проверить. А после релиза часто находятся баги, которые надо пофиксить и… выпустить ещё один релиз с фиксами.
Выпуск релиза - это танцы с бубнами на несколько дней, в которых участвует вся команда. Кто-то второпях доделывает последние задачи релиза, кто-то спешно фиксит баги по сделанным задачам, тестировщик оперативно всё это успевает проверять и после этого уходит делать регресс всей системы.
Релизиться часто не хочется - много накладных расходов. Поэтому заказчик задачи частенько ждёт несколько недель релиза, вместо того, чтобы пользоваться фичой, которая уже готова.
Код может висеть месяцами, не добираясь до прода. Висят как не очень востребованные фичи, так и некритичные фиксы. Например, один раз я разбирал проблему на проде и увидел, что в логах не хватает информации, чтобы понять, что происходит. Добавил логов, залил. Через месяц делаю разбор похожей проблемы - а нужных логов до сих пор нет.
Часто релизы задерживаются. Сначала определяют дату релиза, но по мере её приближения релиз несколько раз сдвигается - на день, потом ещё на 2, потом ещё…
Просто кто-то не успел сделать свою задачу в срок, заболел или взял отгул на пару дней. А кто-то никак не может перекинуть свою задачу через тестирование, потому что она постоянно возвращается с новыми и новыми багами.
Релизы задач, затрагивающих несколько сервисов сразу
Если в релиз вошла задача, где есть изменения сразу по нескольким сервисам, то тут вообще пиши пропало. Чаще всего изменения по таким задачам не обратно совместимы - новая версия одного сервиса не будет работать со старой версией другого. Поэтому требуется релизить несколько сервисов одновременно. Чаще всего для этого сервисы гасят, обновляют и синхронно стартуют на обновлённой версии. То есть появляется даунтайм, и это нифига не круто.
Если перед релизом такой задачи во время регресса в одном (или не одном) из сервисов нашли баг, то блокируются релизы всех этих сервисов.
Если мы находим баг в одном из сервисов уже после релиза, то откатить мы можем либо все сервисы сразу, либо никого. Часто остаётся только героически фиксить проблему за минимально возможный срок, оставаясь после работы. И каждую минуту, пока баг не исправлен, растёт ущерб пользователям и компании, а давление на команду ощущается прямо физически. Команда, понятно дело, стрессует, и это негативно влияет на мораль и производительность как на ближайшие дни, так и в долгосрок.
А давайте как в гугле
Говорят, в гугле большинство команд работают без тестировщиков. Сервисы проверяются автоматическими тестами, а если баг проскакивает на прод, то его просто исправляют и дописывают тесты. Релизы делают чуть ли не на каждую задачу, и выпуск релиза не требует участия человека, всё делается в пайплайне.
Получается, если у вас нет тестировщика, то вы не обязательно отсталая компания с ужасным качеством и плохими процессами. Может быть наоборот - вы передовая компания с самыми современными подходами :)
Мы подумали: “А чем мы хуже гугла?” И решили тоже так попробовать.
Мы сделали так:
Тестировщик
Отдали тестировщика в другую команду
Регресс
Взяли план регресса, который делал тестировщик, и реализовали end-to-end автотесты на большинство кейсов. То есть регресс из ручного стал автоматическим.
Тесты
Дописали интеграционных тестов, чтобы в рамках каждого сервиса была надёжно покрыта вся основная функциональность. В этом нам помогли testcontainers.
Плюс мы договорились, что теперь, делая задачу, разработчик покрывает её тестами, проверяя весь свой код. Ведь теперь между его задачей и продом не будет ничего, кроме тестов, которые написал он сам и другие разработчики.
Релизы
Решили, что релизить можно каждый день, каждый релиз обратно-совместим с предыдущим, и релизы сервисов не зависят друг от друга.
Пайплайны
И конечно же наш SRE-инженер собрал нам CI/CD пайплайны, которые воплотили всё это в жизнь. Автотесты стали запускаться после каждой сделанной задачи и проверять, что всё работает. Релизы мы стали выпускать на основе тега в гите в любое время дня и ночи, и разрешили делать это всем в команде.
Страховочка
Мы представляли, что заменить на автомат хочется главным образом регресс.
Но тестировщик делает не только регресс!
Иногда потестировать что-то руками – это лучшее решение:
одноразовые вещи;
задачи с очень большими изменениями, например новые продукты;
фичи с UI;
фичи на несколько систем, включая сторонние.
На такие случаи, и вообще для подстраховки, договорились, что тестировщика сможем иногда призывать к себе в команду, чтоб потестировать что-то конкретное.
Ну вы ребята крейзи
У вас, наверное, сразу возникли возражения и вопросы, примерно такие:
Писать тесты - это не задача разработчика! Разработчик должен код писать, а сидеть и проверять, как он работает, порочит честь и славу мундира!
Разработчик же всё равно не протестирует сам свой код нормально, проверит только happy path, и всё равно будет куча багов!
А кто будет баги заводить? Тоже разработчики? За зарплату 300к/наносек сидеть и формочки заполнять?
Автотесты писать долго и дорого, будете постоянно тратить на них кучу времени.
Да у вас каждую неделю релизы будут валить прод! Инцидентов не разгребёте!
Короче код в итоге будет писаться еще дольше, а работать будет некачественно!
У нас у самих возникали все эти мысли. Нам как раз было интересно проверить, оправданы ли эти опасения на самом деле, или это всё шаблоны и обычный страх неизвестного.
В противовес у нас были и положительные гипотезы:
может быть разработчики станут больше уделять внимания качеству, раз за ними – только релиз;
станет больше тестовое покрытие, и это повысит общую устойчивость кода к изменениям;
может быть без ручного тестирования мы по крайней мере сможем быстро катить изменения от кода до прода, а снижение накладных расходов и рост скорости поставки уже дадут ценность;
разработчиков не будет вырывать из потока тестировщик, и им не придётся постоянно возвращаться к задачам, которые они уже отпустили несколько дней или недель назад, будет лучше фокус на текущей задаче;
и просто, это офигенно!
В общем, мы были готовы к разному эффекту.
Мы договорились об изменениях и попробовали. Что у нас получилось на самом деле?
Результаты
Мнение команды
Давайте сначала послушаем, как это пережили в команде и какие у ребят впечатления.
Я задал команде 4 вопроса:
Как оно вам, понравилось ли без тестировщика (чисто на уровне восприятия и эмоций)?
Какие изменения заметили, что стало лучше-хуже в плане работы?
Как вам кажется, поменялось ли качество продукта, стало ли оно лучше/хуже?
Хотели бы жить так и дальше и рекомендовать другим?
И получил вот такие ответы:
развёрнутые ответы для любопытных
Разработчик:
По ощущению процесс стал проще и стал сжигать меньше ресурсов.
Кажется, что разработчики стали ответственней относиться к реализации задач, стали продумываться негативные сценарии - что делать, если твой код что-то поломает после релиза.
Отсутствие тестировщика никак не понизило качество продукта, зато увеличило скорость прохождения pipeline, что позитивно сказывается на разработке.
Практика однозначно хорошая, но для идеала нужен еще ручной тестировщик, который будет искать неавтоматизированные сценарии и баги на постоянной основе, не вмешиваясь при этом в прохождение pipeline.
Ещё разработчик:
Прикольно было попробовать, раньше не думал, что такое может быть ок.
На первых порах ручное тестирование поразмазалось по команде, сейчас как будто такого стало меньше. Иногда параноить начинает, что заливаешь опасный функционал.
Тут трудно. Как-то странно мало багов выскакивает по ощущениям. Надеюсь, что это действительно так.
Хотел бы работающую (!) систему с призывным тестировщиком.
Свеже-нанятый разработчик:
Не привычно, требует больше внимания от разработчика, задачи тестировщика ложатся на плечи разработчика.
Пока не могу сказать, единственно, что заметил, это большие временные затраты по проверке написанного/измененного кода.
Увеличилось время прохождения пайплайна.
Мне все равно не хватает ручного тестировщика на некоторые кейсы.
Ещё свеже-нанятый разработчик:
Есть некая прозрачность в том, что должно быть на выходе, и нет постоянных синков, что и как работает и почему.
Тяжело сказать только придя, но в сравнении с предыдущим опытом явно большее погружение в требования к коду, что должно при написании его обогащать качеством. Обычно идет условная конфронтация между qa и разработкой. Тут больше чувствуешь ответственности за продукт.
Пока не могу ничего сказать.
Ручная тестировка всё равно кажется необходима, но для исключительных кейсов.
Аналитик:
По тривиальным задачам, регрессу и т.п. - жить стало приятнее.
По сложным задачам с множеством кейсов хотелось бы, чтобы кто-то проверил не только, соответствует ли реализация требованиям, но и насколько полны требования (но этого не было и при наличии тестировщика).Процесс доставки явно ускорился.
Судя по отсутствию негатива и метрикам - хуже точно не стало.
Я плюсану за то, что хочется иметь "своего" погруженного тестировщика с творческим мышлением для нестандартных кейсов. Возможно, на парт-тайм.
В среднем получается:
Как минимум опыт для команды был прикольным.
Процесс поставки кода стал проще и прозрачней, код стал попадать на прод быстрее.
Качество субъективно не просело.
Есть небольшой стресс от отсутствия “анти-баг стены”, разработчики чувствуют больше ответственности, но в целом это скорее позитив.
В целом потребность в тестировщике значительно снизилась, но частично осталась, в основном не для регресса, а для нестандартных тестов.
Мнение лида (моё)
Мы не увидели просадки в качестве. Метрики показывают, что количество багов на проде осталось таким же, а число багов, найденных на тестовых средах, неожиданно сократилось в 2 раза. Скорее всего багов тестирования стало меньше, потому что разработчики стали, во-первых, находить большую часть багов во время разработки задачи, а во-вторых, потому что разработчики не всегда заводят баги, когда замечают проблему самостоятельно на тестовом стенде до релиза в прод.
Тем не менее, качество работы прода нас устроило, по нашей оценке оно не снизилось. За полгода у нас было 2 блокер-инцидента, но они произошли бы даже при наличии тестировщика, их причина была в изменении конфигурации инфраструктуры в облаке.
Что касается скорости разработки, то она понизилась, по моим оценкам процентов на 20. Это если мерять по времени нахождения тикета в статусах “разработка” и “ревью”. Но здесь надо учитывать ещё и другие затраты времени, которые раньше случались уже после окончания разработки: тестировщик теперь не приходит к разработчикам с вопросами и багами дни и недели спустя после того, как задача залита в мастер. Цикл обратной связи теперь короче за счёт хорошего покрытия тестами, плюс разработчик хорошо покрывает ими и свою текущую задачу, что сразу подсвечивает большинство проблем и позволяет их исправить ещё до того, как код уйдёт дальше.
В целом такой подход к тестированию мне показался более технологичным и интересным, и в нём определённо есть полезное зерно.
Но не все эффекты, которые мы пронаблюдали, были классными. Хотелось бы скорректировать нашу работу по итогу - оставить всё, что нам понравилось, и постараться убрать то, что мешает. Обсудили и пришли примерно к таким вещам:
Что оставляем:
Процесс поставки на прод стал гораздо понятней, он более объективен и формализован, меньше зависит от бас-фактора или личности кого-то из команды.
Повысилась скорость доставки кода на прод и частота релизов. Хочется, чтоб так было и дальше.
Разработчики внимательней готовят код к интеграции с главной веткой. Они понимают, что после них нет человека, который найдёт очевидные ошибки и проверит корректность работы, и поэтому сами лучше погружаются в требования, держат в голове смысл и цель своих изменений и покрывают это тестами.
На код ревью становится более важным сделать ревью не только кода, но и тестов: посмотреть, достаточно ли их, какие сценарии они покрывают.
Что хотим поменять:
Некому выполнять ручное тестирование время от времени. Команда чувствует себя неуверенно, когда нужно выкатить фичу, где требуется нормальный ручной тест. У членов команды не хватает на это квалификации в тестировании, а внешним тестировщикам не хватает погружения в требования, контекст продукта и команды, предсказуемости ресурса занятости.
Автоматические тесты хочется развивать, повышать культуру, улучшать подходы. Хочется, чтобы кто-то в команде целенаправленно этим занимался и обменивался опытом с другими командами.
Всё-таки разработчики больше склонны проверять хэппи вэй, а не думать о том, как маленьким щелчком пальца в нужном месте можно свалить весь карточный домик. Разработчик сам пишет тесты на свой код, и нет никого с альтернативным мнением, кто специально хотел бы найти проблемы в реализации. Код ревью это делает до определённой степени, но там это далеко не главный фокус.
Так мы поняли, что нам в команде всё-таки нужен тестировщик. Просто ручным регрессом он заниматься практически не должен, не больше пары-тройки дней в месяц. А в чём он реально был бы полезен, так это в исследовательском тестировании, чтобы помочь выявить те проблемы, которые не так очевидны. И очень мог бы помочь прокачать автотесты, чтобы у них росло покрытие, но они оставались при этом быстрыми и гибкими.
Возможно уже на следующей неделе к нам выйдет тестировщик, которого мы и позвали в команду помочь с этими вещами.
Кстати, насчёт найма
Через какое-то время после начала эксперимента мне нужно было усилить команду разработчиками. Нет, не из-за того, что половина разработчиков уволились после таких изменений :) Вакансии были предусмотрены ещё до начала эксперимента, никто не увольнялся :)
Так вот, я оказался в интересной ситуации. На собесах кандидаты спрашивают: “Расскажите про состав команды, про процессы”. А я отвечаю: “Кстати да, мы живём без тестировщика, но это не плохо, это мы сами от него отказались, и вообще это не баг а фича, и мы не отсталые, а наоборот такие прогрессивные”.
Мне самому казалось, что потенциальных разработчиков будет отпугивать отсутствие тестировщика, а идея, что можно жить и без него, ассоциируется скорее с отсталыми конторами, где говнокод, авралы, нет кофе-машины в офисе и всё остальное :)
Мне казалось, что слишком мало разработчиков на текущий момент пробовали жить так, как живём мы, и я сомневался, воспримут ли они это с позитивом.
Тем не менее, я закрыл все вакансии классными спецами. И решил спросить их о том, какое впечатление на собеседовании производила наша схема работы:
Когда узнавали на собеседовании, что в команде нет тестировщика, то как это влияло на привлекательность позиции?
Как ощущается теперь спустя месяц работы?
Ответы были такие:
развёрнутые ответы разработчиков-новичков
Разработчик:
Тут скорее не про команду без тестировщика (таких много), а вот команд, пишущих устойчивые тесты это да.) Это дополнительный опыт, и крутой по своей природе. Скорее захотелось поучаствовать в таком проекте.
Чувствуется спокойствие в команде и сам себя постепенно начинаю приводить к тому, что можно деплоиться и ночью, не просыпаться проверить логи)
Ещё разработчик:
"ВАУ, я хочу это увидеть!!!" Привлекательность сильно повысилась, появилось желание это опробовать.
Ещё не могу привыкнуть к долгим пайплайнам.
В целом получается, что привлекательность вакансии может быть даже выросла. Влияние на онбординг противоречивое, нужно больше точек данных :)
Тут конечно стоит учитывать ошибку выжившего - те, кто “не купил” идею, что работать как мы - это круто, наверное просто не пошёл на наши позиции.
Итоги
Суммируя наш опыт, вам стоит пробовать перейти на автоматический регресс, если:
У вас мало UI, или вы хорошо умеете его тестировать автоматически.
Вы хотите иметь быструю доставку изменений на прод, часто релизить (continuous deployment) или хотя бы всегда иметь код, готовый к релизу (continuous delivery).
Ваша команда достаточно прокачана, чтобы держать планку качества в таких условиях, и готова подписаться на такой эксперимент.
У вас прямо сейчас уже неплохое покрытие тестами. Если это не так, лучше сначала его нарастить.
У вас нет кучи легаси. Но тут см. пункт выше - возможно, если вы покроете ваше легаси тестами, оно перестанет быть таковым ;).
И да, совсем прощаться с тестировщиком не обязательно, это, наоборот, хорошая возможность вытащить его из бесконечного регресса и дать возможность прокачать скилы в автоматизации.
P. S. Многие вещи я упомянул в статье только вскользь, иначе она была бы ещё в 3 раза больше. Если интересно о чём-то узнать подробнее, спрашивайте в коментах. Отвечу на что смогу, или сделаю мини-статью, если тема большая. Мне интересно делиться опытом и сравнивать его с вашим, так можно узнать много интересного.
P. P. S. Привет всем из команды и компании, кому история из статьи уже знакома :) Я специально не стал указывать, о какой компании речь, ибо пишу не чтобы попиарить компанию, а просто от себя, чтобы поделиться практикой и обсудить впечатления от такого подхода. Велкам в комменты!