Практически в каждой компании имеются тестировщики, но далеко не каждый программист уверен в том, что от них есть толк. Автор этой статьи попытался переубедить своих «неверующих» коллег по цеху и доказать, что специалисты по тестированию ПО вносят серьезный вклад в успех общего дела. А также поведал, как, по его мнению, должна быть построена их работа, чтобы все задействованные в процессе были «одинаково полезны».
Мне доводилось беседовать со многими людьми из больших и малых софтверных компаний на следующие темы: как в их организациях строится управление разработкой программ, как устроен рабочий процесс, каких методологий они придерживаются, какие из этих приемов действительно работают. Большинство моих собеседников, работающих в небольших командах, сочли непозволительной роскошью нанимать в проект людей, которые занимались бы только тестированием приложений и ничем иным. Ведь тестировщики не пишут код, поэтому фактически считаются обузой. Таким образом, разработчикам приходится самим тестировать свои творения — или этим будет заниматься заказчик.
Что делают тестировщики в Agile-команде?
Во многих компаниях, работающих по принципу Agile, распространена такая точка зрения: для создания готового ПО тестировщики не нужны. Тестировщики воспринимаются как реликт водопадной модели (требования, проектирование, код, тестирование кода). В командах «экстремальных программистов» каждый является разработчиком, разработчики отвечают и отчитываются за тестирование своего кода. Они пишут автоматизированные модульные тесты, а затем — автоматизированные приемочные тесты, условия которых формулирует заказчик. В Scrum вообще не объясняется, как проводить тесты — команда должна определить это сама в ходе «проверки и адаптации» в духе следования рекомендованным методам.
Если разработчики уже тестируют свой код (и даже работают попарно, рецензируя код прямо по ходу его написания), то зачем же нужны тестировщики?
Джанет Грегори и Лиза Криспин написали большую книгу о роли тестировщиков в Agile-командах, в которой объясняют и разработчикам, и самим тестировщикам, как такие специалисты вписываются в Agile-команды. Тем не менее, во многих командах по-прежнему сохраняется предубеждение против тестировщиков. Особенно это касается «инженерно-ориентированных культур» (так называются стартапы, основанные программистами).
В частности, один из аргументов в пользу отказа от тестировщиков сводится к тому, что Agile-команда работает слишком быстро и тестировщикам за ней не угнаться. Действительно, специалисты по тестированию «методом черного ящика» (black-box testing) сначала пишут планы, а портом прорабатывают сценарии ручного тестирования или постоянно обновляют свои регрессионные тесты, в которых применяется Quality Center или Selenium UI. Разумеется, они работают медленнее, чем команда, реализующая новые фичи после каждого короткого спринта. Если тестировщик не обладает минимальными техническими навыками — хотя бы для написания приемочного теста в Fitnesse или Cucumber, либо недостаточно хорошо ориентируется в предметной области конкретной бизнес-модели и не может ставить себя на место заказчика/владельца, отвечая на вопросы разработчиков, то для чего же он нужен?
Острее всего эти проблемы проявляются при непрерывном развертывании — такая практика стала популярной с подачи компаний вроде IMVU и Facebook, где разработчики рецензируют работу коллег и свою работу, пишут автоматизированные тесты, ставят на учет подготовленный код и тесты. Если тест проходит успешно, то все изменения немедленно, автоматически поступают в рабочую версию кода.
Пусть вашу работу тестируют заказчики
Некоторые компании рассматривают непрерывное развертывание как возможность «краудсорсить» тестирование — проще говоря, заставить самих клиентов заниматься тестированием. Такой подход открыто позиционируется как конкурентное преимущество. Но на самом деле очень сложно — или даже невозможно — создавать таким образом надежные и безопасные программы, о чем я уже писал. О критической проверке качества системы, которая непрерывно развертывается и предъявляется заказчику, рассказано в интереснейшей статье Джеймса Баха.
Другие организации, практикующие непрерывное развертывание, действуют более осмотрительно и используют метод «запуска втихую» (dark launching), впервые опробованного в Etsy/Flickr. В таком случае все изменения развертываются непрерывно, но перед включением и предоставлением пользователю они обязательно тестируются, критикуются, а само предоставление новых функций организуется по нарастающей. При этом результаты работы тщательно отслеживаются.
Так или иначе, важно учитывать, что некоторые аспекты могут протестировать только сами пользователи — и именно пользователи должны их тестировать. Так, заказчику виднее, полезна данная возможность или нет, удобна ли она, какая именно информация необходима для корректного решения задачи, какова оптимальная последовательность решения задач. Именно эти проблемы должны решаться в ходе А/B тестирования: оно предполагает эксперименты с идеями, возможностями и последовательностями задач, нахождение взаимосвязей между данными об использовании, а также выяснение того, что именно кажется клиенту самым интересным или удобным, а что совершенно не нравится. Все это нужно для оценки имеющихся альтернатив и получения отдачи от клиента.
При этом клиент не должен тестировать, закончена разработка конкретной фичи или нет, работает ли код, является ли система стабильной и безопасной, как она будет работать под высокой нагрузкой.
Что нужно от команды тестировщиков?
Даже самые лучшие, ответственные и опытные разработчики иногда совершают ошибки. Так, у нас в компании все сотрудники опытные — некоторые из них работают в этой сфере уже по 10—15 лет. Наши люди аккуратно тестируют свою работу и обновляют комплект автоматизированных модульных тестов и функциональных тестов на каждом этапе постановки на учет. Эти тесты и проверки с применением статического анализа выполняются в ходе непрерывной интеграции. Мы научились всецело полагаться на наши комплекты тестов (теперь у нас есть тысячи и тысячи тестов, обеспечивающие очень высокий уровень покрытия кода), а также на инструменты поиска багов при статическом анализе и на инструменты обнаружения уязвимостей. Все это помогает нам находить распространенные программистские ошибки. Кроме того, абсолютно все изменения, вносимые в код, проверяются кем-то из старших разработчиков.
Тем не менее, программисты продолжают совершать ошибки даже при отличной дисциплине и при использовании очень качественного инструментария. Иногда это малозаметные ошибки (несогласованность, проблемы наглядности и восприятия, преобразование и настройка данных), а в других случаях — принципиальные (ошибки времени исполнения при работе под нагрузкой, проблемы, связанные с параллелизмом, неучтенные требования, ошибки в правилах, ошибки при обработке ошибок). Я стремлюсь гарантировать, что мы найдем все (или почти все) ошибки такого рода прежде, чем это сделает клиент. Так и работаем.
И вот тут нам на помощь приходят наши тестировщики. У нас в компании работает небольшая команда опытных и высокоспециализированных тестировщиков. Один из них занимается приемочным тестированием, проверяет функциональные требования, юзабилити и рабочие последовательности на соответствие бизнес-составляющей. Другой тестировщик работает над функциональной регрессией, следит за правильностью бизнес-правил и за тем, насколько тесты покрывают код, отыскивает недостающие правила и изъяны в комплектах тестов, имеющихся у разработчиков. Кроме того, он автоматизирует наши интеграционные тесты на уровне API. Основные задачи еще одного тестировщика — эксплуатационное тестирование, стресс-тестирование на случаи резких скачков нагрузки и потребительского шока, а также тестирование стабильности, поиск утечек и возможных проблем со сборщиком мусора, разрушающее системное тестирование и отлов багов. Словом, он всеми силами старается сломать систему. Все тестировщики обладают достаточными знаниями, чтобы подменять друг друга в случае необходимости, но каждый обладает собственными уникальными навыками и сильными сторонами, умеет по-своему подходить к решению проблем.
Когда мы впервые занимались построением системы, у нас был большой отдел тестирования, задачи которого в основном сводились к покрытию кода тестами и обеспечению гарантии качества. Большое внимание уделялось планированию тестов, их отслеживаемости, составлению подробных списков параметров для ручного тестирования, написанию автоматических регрессионных тестов на уровне пользовательского интерфейса. Но при работе таким образом приходилось впустую тратить массу времени и сил.
Теперь мы в большей степени опираемся на автоматизированные тесты, написанные разработчиками и действующие на более низких уровнях, чем пользовательский интерфейс. Эти тесты нужны нам для функционального покрытия и регрессионной защиты. Наши тестировщики занимаются в основном исследовательским функциональным тестированием, системным и эксплуатационным тестированием. Тесты формулируются так, чтобы максимально учитывались потенциальные риски и интересы заказчика. Так обнаруживаются баги, слабые места в коде, предпринимаются попытки их эксплойта. Такой подход нравится и самим тестировщикам, и мне, и нашим разработчикам, поскольку он помогает нам находить по-настоящему важные баги, устранять такие проблемы, которые могут проскользнуть в программу при рецензировании кода и модульном тестировании.
Изменения тестов проверяются «на дым», как только разработчики ставят их на учет, в различных пользовательских конфигурациях. Тестировщики трудятся в парах с разработчиками «в условиях, приближенных к боевым», тщательно прорабатывая все новые фичи, опробуя готовые имитационные модели. Так мы стремимся выявить ошибки времени исполнения, условия гонки, проблемы синхронизации, недостатки рабочих последовательностей. Все это делается в реалистичных условиях. Мы провоцируем отказы системы, чтобы убедиться в надежности механизмов обнаружения таких отказов и последующего восстановления системы. Наши сотрудники тестируют функции обеспечения безопасности, различные варианты настроек, выполняют тесты на проникновение вместе с консультантами. В системе моделируется типичный рабочий день. Вместе с эксплуатационным отделом тестировщики также занимаются сертификацией интеграции, взаимодействуя с новыми заказчиками и партнерами. Все это делается в режиме коротких спринтов вместе с остальной командой, релизы продукта у нас происходят каждые две недели (иногда даже чаще).
Кроме того, команда тестировщиков отвечает за ввод программы в эксплуатацию. Они объединяют все релизы, проверяют зависимости, принимают решение о готовности релиза, определяют, что в него войдет, а что — нет. Тестировщики обеспечивают выполнение всей работы по контролю, которая была оговорена с командой, проверяют процедуры отката (отмены изменений) и преобразования данных, а далее вновь взаимодействуют с эксплуатационным отделом, окончательно развертывая релиз перед вводом его в производство. Наши тестировщики не тормозят работу команды, не мешают нам вовремя подготавливать релизы. Они помогают нам убедиться, что наши программы работают и нашими продуктами смело можно пользоваться.
Тестировщик не просто ищет баги
Я долгое время работал в высоконадежных, сильно интегрированных компаниях, которые просто не могли позволить себе работать без тестировщиков. Цена ошибки там была слишком высока. Но я в принципе не считаю, что реальные программы можно писать «сразу на чистовик», без всякой помощи тестировщиков. Если только ваша компания — не зарождающийся стартап, занятый поиском своей концепции, а также если вы не работаете в маленькой команде, разрабатывающей какой-то инструмент для внутрикорпоративного пользования (но тогда вы вряд ли стали бы это читать), то вам обязательно нужны тестировщики, которые помогут обеспечить работоспособность системы.
Неважно, как именно вы работаете, применяете ли водопадную модель или какой-то вариант Agile. Тестировщики понадобятся вам в любом случае. Если вы работаете быстро и налегке, то тестировщикам придется адаптироваться к вашему темпу и к применяемым в вашей компании моделям получения информации и обмена ею. Это нормально. Хорошие тестировщики с этим справятся.
Я, конечно, (уже) не считаю, что команда тестировщиков найдет абсолютно все баги в системе — это наивное мнение. Более того, основная задача тестировщиков не в этом. Но тестировщики, разумеется, должны уметь находить все очевидные и явные баги прежде, чем это сделает заказчик.
Истинная задача тестировщиков — помочь нам найти ответы на следующие важные вопросы: Готовы ли мы к релизу? Какие детали программы слишком шероховатые, нестабильные или недоработанные, что нужно дополнительно укрепить, еще раз проконтролировать, а возможно, и переписать? Каковы слабые стороны дизайна? Где не хватает автоматизированных тестов? Какие фичи слишком сложны для понимания, противоречивы, неудобны в настройке? Каких сообщений об ошибках не хватает, какие из уже имеющихся подобных сообщений кажутся двусмысленными? Не пытаемся ли мы сделать слишком много на скорую руку? Что необходимо изменить в дизайне, коде или процессе проектирования/программирования, чтобы система стала лучше и надежнее?
Джеймс Бах высказал очень важную мысль:
Тестирование не дает исчерпывающей информации, но какую-то информацию все же дает. Хорошее тестирование дает массу полезной информации».
Без помощи тестировщиков вы не только выдаете клиенту код, который, возможно, не следует выдавать, но и не находите багов, которые необходимо было найти. Вы к тому же упускаете массу важной информации об истинном качестве вашего продукта, плохо представляете, как его можно было бы улучшить. Если вас действительно волнует качество создаваемого кода, не стоит экономить на тестировщиках и отказываться от их важного труда.
Релоцировались? Теперь вы можете комментировать без верификации аккаунта.