На заметку
   Когда меня спрашивают, в чем секрет нашего успеха, я всегда даю совет: «Не нанимайте слишком много тестировщиков».
   Как Google справляется с таким маленьким штатом тестировщиков? Если бы мне нужно было ответить просто, я бы сказал, что в Google вся ответственность за качество лежит на плечах тех, кто пишет код. Качество никогда не бывает проблемой «какого-то тестировщика». Каждый, кто пишет код в Google, – уже немного тестировщик, а качество – это проблема всего коллектива (рис. 1.1). Говорить о соотношении численности «разработчики/тестировщики» в Google – то же самое, что рассуждать о чистоте воздуха на поверхности Солнца. Эту тему бессмысленно поднимать. Каждый инженер является и тестировщиком. Если в его должности есть слово «тестирование», то он помогает другим специалистам проводить качественное тестирование.
 
   Рис. 1.1. Программисты Google предпочитают качество широте функциональности
 
   Мы выпускаем первоклассные программные продукты. Это свидетельствует о том, что наша формула достойна внимания. Возможно, какие-то ее части сработают и в других компаниях. Конечно, что-то может быть усовершенствовано. Ниже я привожу краткое описание нашей формулы. В последующих главах мы подробно проанализируем ее и разберемся, как же организовать процесс тестирования в царстве разработчиков.

Качество ≠ Тестирование

   Фраза «тестирование не определяет качество» уже настолько избита, что просто обязана быть правдой. В любой области разработки, от автомобилей до софта, не получится отточить продукт до совершенства, если он изначально неправильно сконструирован. Спросите любого автопроизводителя, который хоть раз отзывал партию своих машин, чего стоят запоздалые попытки прикрутить качество на готовое изделие. Делайте все правильно с самого начала, не создавайте себе лишних трудностей.
   Тем не менее это только звучит просто.
   С одной стороны, качество и не создается тестированием, с другой – без тестирования сделать качественный продукт невозможно. Как вы узнаете, насколько качественный ваш продукт, не проводя тестирование?
   Эта головоломка решается легко: перестаньте рассматривать разработку и тестирование по отдельности. Тестирование и разработка идут рука об руку. Напишите немного кода и протестируйте его. Затем напишите еще чуть-чуть и снова протестируйте. Тестирование не отдельная практика, это часть самого процесса разработки. Одним только тестированием качества не добиться. Рецепт получения высокого качества: смешивайте разработку и тестирование в блендере, пока они не станут единой субстанцией.
   На заметку
   Одним только тестированием качества не добиться. Рецепт получения высокого качества: смешивайте разработку и тестирование в блендере, пока они не станут единой субстанцией.
   Вот чего мы добивались: мы хотели объединить дисциплины разработки и тестирования, чтобы одной нельзя было заниматься без другой. Немножко программируем, потом тестируем. Еще немного пишем код и снова тестируем. Здесь важно, кто тестирует. Тестировщиков в классическом понимании у нас мало. Значит, кто должен тестировать? Разработчик. Кто лучше всего протестирует свой код? Тот, кто его написал. Кто больше всех заинтересован в коде без багов? Правильно. Вот почему Google обходится таким небольшим числом тестировщиков – за качество отвечают разработчики. Если продукт сломается после выпуска, то шишки полетят в разработчика, создавшего проблему, а не в тестировщика, который ее не нашел.
   В итоге качество достигается предотвращением, а не выявлением багов. Качество – часть разработки, а не тестирования. Интегрируя тестирование в разработку, мы создали поэтапный процесс, в котором можно легко откатить изменение, в котором слишком много багов. Так мы предотвращаем возникновение проблем у пользователей и сокращаем количество выделенных тестировщиков, которые выявляют баги, ставящие под угрозу выпуск продукта. В Google тестирование определяет, насколько хорошо мы предотвращаем ошибки.
   Наш подход к созданию продуктов подразумевает слияние разработки и тестирования. Это подтверждают комментарии к коду типа «где твои тесты, чувак?», развешенные в туалетах плакаты с правилами тестирования[7] и многое другое. Тестирование должно стать неотделимым от разработки. Качество родится только тогда, когда разработка и тестирование начнут жить вместе.
   На заметку
   Тестирование должно стать неотделимым от разработки. Качество родится только тогда, когда разработка и тестирование начнут жить вместе.

Роли

   Чтобы девиз «Сам построил, сам и ломай» работал (и работал долго), вам нужна не только традиционная роль разработчика кода, но и другие роли. Конкретнее, должны появиться инженеры, которые помогут разработчикам тестировать эффективно и правильно. Они часто скромничают, называя себя тестировщиками, но на самом деле обеспечивать продуктивность – вот их основная задача. Тестировщики нужны для того, чтобы разработчики работали более продуктивно. Причем рост продуктивности основан на предотвращении появления ошибок из-за небрежной разработки. Так качество становится частью этой продуктивности. Все эти роли мы подробно рассмотрим в следующих главах, а пока обойдемся кратким описанием.
   Роль разработчика (Software Engineer, SWE) всем знакома и привычна. Он пишет код функциональности приложений, который поставляется пользователям. Он создает проектную документацию, определяет структуры данных и общую архитектуру, а большую часть времени пишет код и проводит код-ревью[8]. Разработчик пишет много тестового кода, например во время написания тестов для TDD и юнит-тестирования, и, как будет показано дальше в этой главе, участвует в создании малых, средних и больших тестов. Разработчик отвечает за качество всего кода, к которому он прикасается: пишет, исправляет или вносит изменения. Да, все верно: если разработчик должен изменить функцию и его изменение нарушает существующий тест или требует написания нового, он должен написать этот тест. Практически 100 % рабочего времени разработчик пишет программный код.
   Роль разработчика в тестировании (Software Engineer in Test, SET) тоже связана с разработкой, но фокусируется на тестируемости кода и создании инфраструктуры тестирования. Разработчик в тестировании анализирует архитектуру, уделяет особое внимание качеству кода и рискам проекта. Он выполняет рефакторинг, чтобы сделать код тестируемым, пишет фреймворки юнит-тестирования и средства автоматизации. Разработчик в тестировании работает с тем же кодом, что и разработчик, но больше заинтересован в улучшении качества и тестового покрытия, чем в добавлении новых фич или повышении производительности. Разработчик в тестировании тоже проводит почти 100 % своего времени за написанием кода, но делает это ради повышения качества, а не для реализации фич для пользователей.
   На заметку
   Разработчик в тестировании работает с тем же кодом, что и разработчик, но занимается скорее повышением качества и тестовым покрытием, чем добавлением новых фич или повышением производительности. Разработчик в тестировании пишет код, который помогает разработчику тестировать написанные им фичи.
   Роль инженера по тестированию (Test Engineer, TE) связана с ролью разработчика в тестировании, но здесь на первом месте находятся пользователи и только на втором – разработчики. Некоторые инженеры по тестированию в Google пишут много кода для автотестов и управления сценариями использования и даже для имитации действий пользователя. Кроме того, именно они организуют работу по тестированию, которую выполняют другие инженеры, управляют выполнением тестов и интерпретируют их результаты тестов. Особенно важна их работа на поздних стадиях проекта, когда напряжение с приближением выпуска растет. Инженеры по тестированию – это эксперты продукта, консультанты по качеству и специалисты по анализу рисков. Одни пишут много кода, другие – мало[9].
   На заметку
   Инженеры по тестированию фокусируются на тестировании с точки зрения пользователя. Они занимаются общей организацией контроля качества, управляют выполнением тестов, интерпретируют их результаты и строят сквозную автоматизацию тестирования.
   Итак, с точки зрения качества разработчики отвечают за фичи приложения и их качество отдельно от всего остального. Они ответственны за то, чтобы архитектура была устойчивой к ошибкам, приложение восстанавливалось после сбоев, отвечают за TDD, юнит-тесты и вместе с разработчиками в тестировании пишут код для тестирования фич.
   Разработчики в тестировании отвечают за фичи тестирования. Они настраивают среду для изолированного выполнения кода с помощью имитации реального рабочего окружения. Для этого они создают такие компоненты, как заглушки (stubs), подставные объекты (mocks) и имитации (fakes), – мы рассмотрим их позже. Настроить очередь для управления отправкой кода в репозиторий – тоже их задача. Другими словами, разработчики в тестировании пишут код, который помогает разработчикам тестировать написанные ими фичи. Большую часть тестирования выполнит сам разработчик. Разработчики в тестировании в основном следят за тем, чтобы функциональность можно было легко протестировать, а разработчики не ленились писать тест-кейсы.
   Получается, что разработчики в тестировании работают для разработчиков. Их конечная цель – качество кода и отдельных фич. Для этого они создают разработчикам удобную среду для тестирования кода. О пользователях думают тестировщики.
   Если разработчики провели модульное и функциональное тестирование хорошо, то следующая задача – понять, насколько хорошо их исходный код вместе с данными будет работать на благо пользователей. Тестировщики проверяют добросовестность разработчиков дважды. Любые очевидные баги свидетельствуют о том, что тестирование раннего цикла было недостаточным или небрежным. Если таких багов мало, тестировщик переходит к своей основной задаче – убедиться в том, что продукт выполняет пользовательские сценарии, соответствует ожиданиям по производительности, что он надежен, правильно локализован и т. д. Тестировщики много тестируют сами и вдобавок обеспечивают координацию с другими инженерами, внешними тестировщиками-подрядчиками, тестировщиками из сообщества, внутренними пользователями, бета– и ранними внешними пользователями. Они сводят воедино все риски, которые могут сыграть из-за недочетов в базовой архитектуре, сложности функциональности и отказов в системе предотвращения сбоев. Как только тестировщики взялись за дело, их работе не видно конца.

Организационная структура

   В большинстве компаний, где я работал, разработчики и тестировщики относились к одной команде разработки продукта. И разработчики, и тестировщики подчинялись одному и тому же руководителю проекта. Один продукт, одна команда – все участники говорят на одном языке.
   К сожалению, я еще не видел, чтобы такой подход работал на практике. Обычно командой руководят менеджеры, вышедшие из среды программирования или управления, но не из среды тестировщиков. В предрелизном аврале они предпочтут выпустить функциональность полностью и закрыть как можно больше задач по «отделке» приложения, чем позаботиться об общем качестве. Внутри команды тестированию часто отводится второстепенная роль по отношению к разработке. Это отлично заметно по обилию глючных продуктов и преждевременных выпусков в нашей отрасли. Кто тут заказывал сервис-пак?
   На заметку
   Совместными командами обычно руководят менеджеры, вышедшие из среды программирования или управления, но не из среды тестировщиков. В предрелизном аврале они предпочитают выпустить функциональность полностью и закрыть как можно больше задач по «отделке», чем позаботиться об общем качестве. Внутри команды тестированию часто отводится второстепенная роль по отношению к разработке.
   Давайте разберемся, кто кому подчиняется в Google. У нас есть своя иерархия, которая делится на направления, называемые Focus Area (FA). У нас есть направления Client (проекты Chrome, Google Toolbar и т. д.), Geo (проекты Maps, Google Earth и т. д.), Ads, Apps, Mobile и т. д. Все разработчики подчиняются директору или вице-президенту направления.
   Правда, тестирование ломает эту схему. Тестирование находится в отдельном горизонтальном направлении, которое отвечает за продуктивность разработки. Направление продуктивности разработки существует параллельно с продуктовыми направлениями. Тестировщиков, по сути, предоставляют командам разработки продуктов во временное пользование. Они свободно поднимают вопросы безопасности и освещают области, где нет тестов или много багов. Так как мы не подчиняемся команде разработки продукта, нам нельзя ответить, что для нас есть дела поважнее. Мы сами устанавливаем свои приоритеты, и они всегда в рамках обеспечения надежности, безопасности и всего такого, пока мы не решим, что продукту нужно что-то другое. Если команда разработки захочет провести тестирование по упрощенной схеме, это необходимо согласовать заранее, а мы всегда можем сказать «нет».
   С такой структурой работы мы можем сохранять небольшой штат тестировщиков. Команда разработки продукта не может снизить техническую планку тестировщиков или нанять их больше, чтобы свалить на них рутинную работу. Рутинная работа вокруг фичи входит в обязанности разработчика, ее нельзя переложить на какого-нибудь тестировщика-несчастливчика.
   Тестировщиков на проекты назначают руководители направления продуктивности разработки. Они принимают стратегические решения, опираясь на приоритеты компании, сложность продукта и потребности конкретной команды проекта в сравнении с другими. Конечно, они могут ошибаться, и такое случается. Но в целом такая схема обеспечивает баланс ресурсов между фактическими, а не предполагаемыми потребностями.
   На заметку
   Тестировщиков на проект назначают руководители направления продуктивности разработки. Они принимают стратегические решения, опираясь на приоритеты компании, сложность продукта и потребности конкретной команды проекта в сравнении с другими. Такая схема сохраняет баланс ресурсов между фактическими, а не предполагаемыми потребностями. Централизованность подходов, идей и решений помогает всей компании использовать самые удачные из них.
   Статус временно выделяемых на проект тестировщиков упрощает их перемещение по проектам. Они не только сохраняют свежий взгляд и остаются в курсе дел, но и быстро распространяют удачные идеи по компании. Прием или инструмент тестирования, который хорошо сработал в продукте направления Geo, скорее всего, пойдет в работу снова, когда этот тестировщик перейдет на Chrome. Нет более быстрого способа распространения инноваций, чем перемещение самих новаторов.
   Мы считаем, что тестировщику достаточно 18 месяцев работы над одним продуктом, а потом он может (если, конечно, хочет) перейти в другую команду. Конечно, есть и ложка дегтя – команда теряет накопленный опыт. Но это компенсируется появлением тестировщиков с широким кругозором, знакомых с разными продуктами и технологиями. В Google много тестировщиков, понимающих клиентские, браузерные и мобильные технологии, способных эффективно программировать на многих языках и для разных платформ. А поскольку все продукты и услуги Google сейчас интегрированы друг с другом теснее, чем когда-либо, тестировщики легко перемещаются в пределах компании и их опыт применим везде, независимо от проекта.

Ползти, идти, бежать

   Одна из ключевых причин, почему Google успешен даже с маленьким количеством тестировщиков, в том, что мы редко пытаемся сразу поставить большой набор фич. Как раз наоборот. Мы строим минимально жизнеспособный продукт и выпускаем его в тот момент, когда он может стать полезным как можно большему количеству людей, получаем обратную связь и дальше развиваем продукт итеративно. Так мы действовали с Gmail, у которого ярлык «бета-версии» сохранялся четыре года. Мы предупреждали пользователей, что продукт все еще дорабатывается. Ярлык «бета-версии» мы убрали, только когда достигли поставленной цели в 99,99 % нормальной работоспособности почты. По той же схеме мы работали с Android при выпуске G1 – продукта, получившего хорошие отзывы. Он был улучшен и обогащен новыми фичами, когда выходил для линейки телефонов Nexus. Важно помнить, что ранняя версия, за которую платят пользователи, должна быть достаточно функциональной и полезной для них. То, что версия является ранней, еще не означает, что она должна быть слабым продуктом.
   На заметку
   Google часто выпускает «минимально полезный продукт» как исходную версию и собирает обратную связь от внутренних и внешних пользователей. А потом быстро выдает обновления, тщательно анализируя качество на каждом этапе. Прежде чем попасть к пользователям, продукты проходят через разные каналы: канареечный, разработки, тестирования, бета– и выпуска.
   Это не такое уж жульничество, как может показаться на первый взгляд. Чтобы дойти до состояния канала бета-версии, продукту надо пройти через ряд других каналов и доказать свою ценность. Для Chrome – продукта, над которым я работал первые два года в Google, – мы использовали разные каналы в зависимости от нашей уверенности в качестве продукта и от объема отзывов, который нам был нужен. Последовательность примерно такая.
   – Канареечный канал: используется для ежедневных сборок, которые, на наш взгляд, еще не готовы для выпуска. Помните канареек, с которыми спускались в шахты для обнаружения токсичного газа? Если ежедневная сборка оказывается нежизнеспособной (канарейка умирает, если есть хоть небольшая примесь газа в воздухе), это свидетельствует о том, что процесс разболтался и работу надо пересмотреть. Канареечные версии подходят только для самых преданных пользователей, которые экспериментируют с продуктом. Они не для тех, кто использует приложение для реальной работы. Как правило, сборки из канареечного канала используют только инженеры (разработчики и тестировщики) и менеджеры, работающие над продуктом.
   На заметку
   Команда Android пошла еще дальше – телефоны основной команды разработки почти постоянно работают на ежедневной сборке. Идея в том, что разработчики будут писать меньше кода с багами, если от этого зависит их возможность позвонить домой.
   – Канал разработки: используется разработчиками в повседневной работе. Обычно это еженедельные сборки, которые стабильно использовались какое-то время и прошли набор тестов (об этом подробнее в следующих главах). Все инженеры, работающие над продуктом, обязаны взять сборку канала разработки и использовать ее в реальной работе, чтобы проверить при продолжительном применении. Если сборка из канала разработки непригодна для нормальной работы, она отправляется обратно в канареечный канал. Это неприятная ситуация, которая потребует от инженеров серьезного пересмотра своей работы.
   – Тестовый канал: сюда попадает лучшая сборка месяца – та, которая прошла наиболее продолжительное тестирование и которой доверяют инженеры. Сборку тестового канала можно выкатывать для внутренних пользователей. Это кандидат на сборку бета-канала, если покажет хорошие результаты при долгосрочном использовании. Однажды сборка тестового канала станет достаточно стабильной для использования внутри компании, а иногда мы даже передаем ее внешним сотрудникам и партнерам, которым может быть полезно раннее знакомство с продуктом.
   – Бета-канал или канал выпуска: сюда попадают только стабильные сборки, успешно прошедшие внутреннее использование и удовлетворяющие всем критериям качества, установленным командой. Это первые сборки, которые доступны пользователям.
   Метод «ползти, идти, бежать» помогает нам проводить тесты и экспериментировать с приложением на ранней стадии разработки. В дополнение к данным ежедневных автоматических тестов мы получаем ценную обратную связь от настоящих пользователей.

Виды тестов

   Вместо того чтобы разделять тестирование на модульное, интеграционное и системное, мы делим все тесты на малые, средние и большие. Пожалуйста, не путайте с методом оценки из гибких методологий. Мы ориентируемся на охват, а не на размер теста. Малые тесты покрывают малые объемы кода, средние – объемы побольше и т. д. Любой инженер, независимо от своей роли, может заниматься любыми типами тестов. Их можно проводить в ручном или запускать в автоматическом режиме. Реальный опыт говорит, что чем меньше тест, тем скорее он будет автоматизирован.
   На заметку
   Вместо того чтобы разделять тестирование на модульное, интеграционное и системное, мы делим все тесты на малые, средние и большие, исходя из их охвата, а не размера.
   Малые тесты чаще всего (хотя и не всегда) автоматизируются. Они исполняют код одной функции или модуля. Обычно они проверяют типичные функциональные проблемы, повреждение данных, неверные условия и ошибки, связанные со сдвигом значений на единицу. Малые тесты выполняются быстро, за несколько секунд и меньше. Как правило, их пишут разработчики, реже – разработчики в тестировании и почти никогда – инженеры по тестированию. Для выполнения малых тестов обычно нужна среда с подставными объектами и имитациями. Подставные объекты и имитации относятся к заглушкам (то есть заменителям реальных функций), они работают как заменители объектов в зависимостях – несуществующих, слишком ненадежных или затрудняющих эмуляцию ошибочных ситуаций. Мы расскажем об этом подробнее в следующих главах. Инженеры по тестированию редко пишут малые тесты, но могут выполнять их, диагностируя конкретные сбои. Малые тесты отвечают на вопрос «Делает ли этот код то, что он должен делать?»
   Средние тесты обычно автоматизируются. Они покрывают две или больше функции. Тесты фокусируются на том, чтобы проверить взаимодействие между функциями, которые вызывают друг друга или контактируют напрямую. Такие функции мы называем ближайшими соседями. Разработчик в тестировании управляет разработкой средних тестов на ранней стадии цикла продукта. Их пишут, исправляют и сопровождают разработчики. Если тест не проходит, разработчик чинит его сам. На более поздней стадии разработки инженеры по тестированию могут выполнять средние тесты вручную (если его трудно или дорого автоматизировать) или автоматически. Средние тесты отвечают на вопрос «Взаимодействуют ли соседние функции друг с другом так, как должны?»
   Большие тесты покрывают не меньше трех (а обычно больше) функций. Это реальные пользовательские сценарии, которые используют реальные источники данных, а их выполнение может занять несколько часов и даже больше. Они затрагивают и интеграцию в целом, но чаще всего большие тесты проверяют, насколько приложение соответствует потребностям пользователей. Все три роли вовлечены в создание больших тестов. Их можно проводить разными способами, от автоматизированного до исследовательского ручного тестирования. Большие тесты отвечают на вопрос «Работает ли продукт так, как нужно пользователю, и дает ли желаемый результат?» Сквозные сценарии, которые выполняются на завершенном продукте, относятся к большим тестам.
   На заметку
   Малые тесты проверяют один программный блок в полностью имитированной среде. Средние тесты проверяют взаимодействие модулей в имитированной или реальной среде. Большие тесты проверяют любое количество модулей в реальной среде с настоящими, не имитированными ресурсами.
   Не так критично, как именно вы называете тесты, главное, чтобы все понимали эти термины одинаково[10]. Здесь важно то, что тестировщики Google говорят на одном языке, описывая, что именно тестируется и в каком объеме. Когда кто-то особо изобретательный говорит о четвертой разновидности тестов, которую они прозвали громадными тестами, любой инженер в компании сразу представит себе общесистемный тест, который выполняется очень долго и проверяет все функциональные аспекты. Ничего больше пояснять не требуется[11].