Для организации разработки и тестирования сегодня принято выстраивать пирамиду тестов, это считается мейнстримом. Существуют десятки, если не сотни, вариаций пирамиды, опубликовано много докладов и статей о том, как она должна выглядеть. И почти все эти материалы помогут ответить на вопрос «Как мне построить пирамиду тестирования в новом проекте?».
Но что делать, если вы приходите в проект, в котором исторически применялся подход «мороженки» тестирования, когда основную часть проверок закрывали ручным тестированием? При этом компания проходит трансформацию, и от вас ждут, что вы приведёте процессы в соответствие современным практикам и ускорите их?
Меня зовут Максим Бугров, я больше 8 лет работаю в тестировании ПО. На Московскую биржу я пришел летом 2021 года на позицию начальника отдела тестирования. Наш департамент преимущественно разрабатывает софт, который связывает клиентов и торгово-клиринговые системы Биржи. И я расскажу, как мы начали превращать мороженку в пирамиду — нас ждал огромный ледник задач.
Пирамида тестирования
Для начала кратко расскажу, что такое пирамида тестирования и для чего она нужна. Теории я коснусь только вскользь, потому что на эту тему написано достаточно материалов.
Пирамида тестирования — это абстракция, которая показывает соотношение видов тестов приложения. Основная цель пирамиды — помочь обнаруживать баги на ранних стадиях, когда их исправление значительно дешевле, чем на поздних.
Ключевые утверждения, которые справедливы для пирамиды.
Наибольший объем тестов должен быть сконцентрирован на нижних уровнях.
Чем выше поднимаемся по пирамиде, тем дороже и медленнее будут тесты.
Тяжелых Е2Е-тестов должно быть минимальное количество.
В построении пирамиды должны участвовать и разработчики, и тестировщики.
Пример пирамиды, которую мы хотим у себя видеть:
Исходные данные
Теперь расскажу о ситуации, которая сложилась к началу превращения нашей мороженки в пирамиду, и какими ресурсами мы обладали.
Летом 2021 года у нас было:
огромный монолит, которому уже больше 10 лет. Активно распиливается на микросервисы;
микросервисы для новой функциональности и выпиленные части монолита;
5 ручных тестировщиков, которые работали в четырех смежных проектах;
30 разработчиков;
отсутствие автоматизации тестирования;
почти полное отсутствие юнит-тестов для монолита и микросервисов;
нехватка ресурсов.
То есть, ситуация выглядела так:
Классическая мороженка тестирования, когда основной объем тестов сконцентрирован на поздних стадиях, преимущественно в виде ручного тестирования. При этом со стороны бизнеса и пользователей все чаще звучали пожелания ускорить разработку, повысить качество и надежность нашего софта. Чтобы выйти из текущей ситуации, первым делом нужно было разработать стратегию.
Первые шаги к светлому будущему
Первые шаги по превращению мороженки в пирамиду были такими.
Сосредоточиться на найме дополнительных тестировщиков в команду.
Начать выстраивать автоматизацию.
Договориться с разработчиками по развитию юнит-тестирования.
С наймом тестировщиков больших проблем не было, а вот над двумя другими пунктами пришлось поломать голову.
Юнит-тестирование для начинающих
С юнит-тестами ситуация обстояла так.
Для монолита тесты отсутствовали.
Для новых сервисов тесты писали, но мало. При этом у разработчиков не было общего подхода к написанию тестов и выработанных стандартов тестов.
Не было возможности автоматически измерять покрытие юнит-тестами.
На написание юнит-тестов нужны были дополнительные ресурсы разработки.
С монолитом все было, в принципе, понятно – покрывать его юнит-тестами большого смысла не было, потому что в ближайшие два года монолит планировали полностью распилить на микросервисы. Но все-таки новая функциональность еще добавлялась и в монолит. Мы решили, что сосредоточимся на покрытии юнит-тестами нового кода. Так получится сохранить ресурсы и рассудок разработчиков и начать движение в правильном направлении.
Чтобы решить задачу с измерением покрытия, мы подключили статический анализатор кода во все наши проекты.
Основной проблемой стал вопрос, где найти ресурсы на написание тестов. Нельзя же просто так увеличить время разработки на 20–30 %, бизнес не пойдет на это. К решению мы подошли с точки зрения общего количества ресурсов, которое требуется на вывод проекта в эксплуатацию. Отсутствие юнит-тестов приводит к тому, что большинство багов мы пропускаем на стадии разработки. Эти баги в дальнейшем съедают ресурсы тестировщиков, девопсов, поддержки, бизнеса и пользователей. Поэтому, если мы будем тратить ресурсы на написание тестов, то на более поздних этапах мы их будем экономить. Идею поддержали, в том числе, разработчики, поэтому мы продвинулись в этой истории.
Также мы запустили серию митапов по юнит-тестам, чтобы выровнять навыки всех разработчиков по подходу написания тестов. И к концу 2022 года планируем добиться покрытия нового кода юнит-тестами на 80%.
Автоматизация
Проблемы
Основные проблемные зоны в выстраивании автоматизации были такими.
Нужна была команда автоматизаторов, желательно с лидом.
Отсутствовал план работ. Существующие тестировщики занимались срочными задачами, им было не до тестовой документации.
Первое время все попытки автоматизации не приносили и видимого результата.
Найм
Я начал с поиска лида по автоматизации. Стэк был выбран близкий к разработке: Java. Удалось за несколько месяцев найти лида (привет, Саша :)). Вместе с ним определились, что первое время автоматизаторы, которых наймем, будут работать в одной платформенной команде, чтобы они находились на одной волне: вырабатывали общие практики, проверяли код друг друга и были знакомы со всеми частями приложения.
Параллельно успешно нанимали ручных тестировщиков и лидов проектных команд, поэтому появилась возможность создать план работ по каждой части приложений. К концу 2021 года количество ручных тестировщиков удалось довести до 20. Даже с учетом двукратного роста команды разработки это соотношение тестировщиков к разработке можно считать приемлемым в нашем случае. Найм автоматизаторов тоже хорошо пошел к концу года, с октября по конец декабря нам удалось набрать 9 человек.
Уровни пирамиды
По-хорошему, автоматизацию нужно выстраивать на основе фундамента в виде юнит-тестов, но мы не можем ждать год, чтобы только потом начать работу. Поэтому начали активно покрывать автотестами критичную функциональность каждой из проектных команд.
Для начала стали собирать smoke-набор со всех команд, который в дальнейшем объединили в общий smoke нашего любимого монолита. Поскольку это монолит, то уровень интеграционных и API тестов для нас ограничен, поэтому мы преимущественно написали UI-автотесты. Там, где это возможно, для функциональности микросервисов наибольшую часть smoke покрыли API-тестами, а оставшаяся часть пошла на UI-тесты.
Теперь поясню, что я имею в виду под интеграционными тестами. Это тесты, которые проверяют конкретную интеграцию сервиса с одной внешней зависимостью (в крайнем случае, с несколькими). Все остальные зависимости мокаются. Из-за глубокой связанности кода внутри монолита и микросервисов (правильней будет назвать их микромонолитами) уровень интеграционных тестов в пирамиде нам дается сложнее всего. Здесь нам начинают помогать разработчики, которые вместе с юнит-тестами первое время будут брать на себя и интеграционные тесты. В дальнейшем команда тестирования также будет подключаться к написанию интеграционных тестов.
Стоит немного рассказать и про уровень Е2Е-тестов и наши системы. Бизнес-процессы Биржи могут протекать через множество колоссальных по размеру систем, за которые порой отвечают разные департаменты. Если говорить про автоматизацию тестирования таких бизнес-процессов, то для этого у нас есть выделенная команда, которая сейчас активно покрывает Е2Е-тестами несколько процессов. Часть этих тестов будут собирать из smoke-тестов конкретных систем, в том числе и нашей. Сейчас у нас автоматизировано несколько бизнес-процессов поменьше, которые затрагивают не более двух-трех систем.
Где мы находимся сейчас и дальнейшие планы
Текущую ситуацию можно изобразить так:
Юнит-тесты
Мы включили quality gate в нашем CI для всех наших сервисов. Активно начали покрывать новый код юнит-тестами. До конца первого квартала 2022 планируем довести покрытие нового кода юнит-тестами до 25 %. А к концу года, как говорил выше, планируем довести до 80 %. Также мы уже провели первый внутренний митап по модульному тестированию, который понравился аудитории.
Автотесты
У нас уже автоматизирован smoke половины команд, который преимущественно состоит из API- и UI-тестов. Критичную новую функциональность также автоматизируем. К концу первого квартала у нас будет автоматизирован smoke всех команд, и мы начнем подступаться к почти неподъемному регрессу!
Впереди у нас еще много работы по выстраиванию пирамиды. Нужно начать автоматизировать менее критичную функциональность, расширить покрытие регрессионными тестами, довести покрытие юнит-тестами до планируемых значений. Но мы уже сейчас начинаем извлекать пользу из всех этих активностей: сокращаем наш TTM (time to market) без потери в качестве.
Lessons learned
Когда ты смотришь на все эти привлекательные картинки разных пирамид тестирования, то кажется, что вот оно — мы нашли то, что нам нужно. Выглядит всё логично, складно. Ты закатываешь рукава и говоришь себе: «Давайте сделаем это!» А потом ты сталкиваешься с суровой реальностью. Например, юнит-тесты, это, конечно, круто, но кто их будет писать для legacy-монолита, в котором полмиллиона строк кода? А как быть с API-тестами? Можно всё покрыть UI-тестами, но тогда у нас мороженка превратится в автоматизированную мороженку, что имеет право на жизнь, но совершенно не то, что нам хотелось бы получить после изучения best practices. Тебя мало кто поддерживает, часто людям просто не до тебя. А твой опыт постройки пирамиды с нуля лишь отчасти поможет в перестраивании мороженки.
Не нужно строить иллюзий, что всё будет легко и просто, раз вы изучили крутые доклады, прочитали модные статьи и сходили на несколько конференций. Признаюсь честно, что такие иллюзии у меня были, и где-то на середине пути, когда они развеялись, я был на пороге выгорания. Благо хороший отпуск, сильная мотивация и переосмысление ситуации всё смогли поправить ?
Стоит учитывать, что чем крупнее организация, тем сложнее и дороже даются любые развороты и смены направления. Поэтому старайтесь трезво оценивать свои возможности, возможности компании и объективную реальность. В конце концов, пирамида тестирования — это всего лишь рекомендация, к которой стоит стремиться, но совершенно необязательно соответствовать ей на 100%.
Послесловие
Мы еще только в начале своего пути, впереди новые проблемы, но мне кажется, что с самыми сложными мы уже справились! Если в первое время наша команда была настроена пессимистично, то теперь концентрированный оптимизм витает в наших чатиках и митингах.
У каждой компании, проекта и команды будут свои уникальные проблемы при попытке выстраивания пирамиды тестирования. Главное, чтобы в ней были люди, которые не готовы мириться с текущим положением дел. Начать этот путь можно даже в одиночку. Если ваше дело правое, то у вас быстро появятся сторонники. Всем благ!