— оба теста пытаются подключиться к одному порту для единоличного получения сетевого трафика;
— оба теста пытаются создать каталог, используя один путь;
— один тест создает и заполняет таблицу базы данных, а другой пытается удалить ту же таблицу.
Такие конфликты могут вызывать сбои не только в самих тестах, но и в соседних тестах, которые выполняются в той же системе, даже если эти другие тесты соблюдают правила. Наша система умеет выявлять такие ситуации и оповещать владельцев тестов-бунтарей.
Если установить специальный флаг, тест будет выполняться единолично на выделенной машине. Но это лишь временное решение. Все равно придется переписать тесты и удалить зависимости от критических ресурсов. Например, эти проблемы можно решить так:
— каждый тест запрашивает свободный порт у системы выполнения тестов, а тестируемая программа динамически к нему подключается;
— каждый тест создает все папки и файлы во временной директории, созданной и выделенной системой специально для него перед выполнением тестов;
— каждый тест работает со своим экземпляром базы данных в изолированной среде с выделенными системой выполнения тестов директориями и портами.
Ребята, ответственные за сопровождение системы выполнения тестов Google, довольно подробно описали свою среду выполнения тестов. Их документ называется «Энциклопедией тестирования Google», и он отвечает на все вопросы о том, какие ресурсы доступны тестам во время выполнения. «Энциклопедия тестирования» составлена как стандартизированный документ, где у терминов «должен» и «будет» однозначное значение. В энциклопедии подробно объясняются роли и обязанности тестов, исполнителей тестов, систем хостинга, рантайм-библиотек, файловых систем и т.д.
Вряд ли все инженеры Google читали «Энциклопедию тестирования». Скорее всего, большинство предпочитает учиться у других, или испытывать метод проб и ошибок, или постоянно натыкаться на комментарии рецензентов их кода. Они и не подозревают, что общая среда выполнения тестов может обслужить все проекты по тестированию Google. Чтобы это узнать, достаточно заглянуть в энциклопедию. Им неизвестно, что этот документ — главная причина того, что тесты ведут себя в общей среде ровно так же, как и на личной машине написавшего тест инженера. Технические детали даже самых сложных систем остаются незамеченными теми, кто их использует. Все же работает, зачем читать.
Тестирование на скоростях и в масштабах Google
Пуджа Гупта, Марк Айви и Джон Пеникс
Системы непрерывной интеграции — главные герои обеспечения работоспособности программного продукта во время разработки. Типичная схема работы большинства систем непрерывной интеграции такая.
1. Получить последнюю копию кода.
2. Выполнить все тесты.
3. Сообщить о результатах.
4. Перейти к пункту 1.
Решение отлично справляется с небольшой кодовой базой, пока динамичность изменений кода не выходит за рамки, а тесты прогоняются быстро. Чем больше становится кода, тем сильнее падает эффективность подобных систем. Добавление нового кода увеличивает время «чистого» запуска, и в один прогон включается все больше изменений. Если что-то сломается, найти и исправить изменение становится все сложнее.
Разработка программных продуктов в Google происходит быстро и с размахом. Мы добавляем в базу кода всего Google больше 20 изменений в минуту, и 50% файлов в ней меняются каждый месяц. Разработка и выпуск всех продуктов опираются на автотесты, проверяющие поведение продукта. Есть продукты, которые выпускаются несколько раз в день, другие — раз в несколько недель.
По идее, при такой огромной и динамичной базе кода команды должны тратить кучу времени только на поддержание сборки в состоянии «зеленого света». Система непрерывной интеграции должна помогать с этим. Она должна сразу выделять изменение, приводящее к сбою теста, а не просто указывать на набор подозрительных изменений или, что еще хуже, перебирать их все в поисках нарушителя.
Чтобы решить эту проблему, мы построили систему непрерывной сборки (рис. 2.6), которая анализирует зависимости и выделяет только те тесты, которые связаны с конкретным изменением, а потом выполняет только их. И так для каждого изменения. Система построена на инфраструктуре облачных вычислений Google, которая позволяет одновременно выполнять большое количество сборок и запускать затронутые тесты сразу же после отправки изменений.
Примером ниже мы показываем, как наша система дает более быструю и точную обратную связь, чем типичная непрерывная сборка. В нашем сценарии используются два теста и три изменения, затрагивающие эти тесты. Тест gmail_server_tests падает из-за изменения 2. Типичная система непрерывной сборки сообщила бы, что к сбой случился из-за изменения 2 или 3, не уточняя. Мы же используем механизм параллельного выполнения, поэтому запускаем тесты независимо, не дожидаясь завершения текущего цикла «сборка–тестирование». Анализ зависимостей сузит набор тестов для каждого изменения, поэтому в нашем примере общее количество выполнений теста то же самое.
Рис. 2.6. Сравнение систем непрерывной интеграции
Наша система берет данные о зависимостях из спецификаций сборки, которые описывают, как компилируется код и какие файлы входят в сборку приложения и теста. Правила сборки имеют четкие входные и выходные данные, объединив которые получим точное описание процесса сборки. Наша система строит в памяти график зависимостей сборки, как на рис. 2.7, и обновляет его с каждым новым изменением. На основании этой схемы мы определяем все тесты, связанные прямо или косвенно с кодом, вошедшим в изменение. Именно эти тесты нужно запустить, чтобы узнать текущее состояние сборки. Давайте посмотрим на пример.
Рис. 2.7. Пример зависимостей сборки
Мы видим, как два отдельных изменения в коде, находящихся на разных уровнях дерева зависимостей, анализируются, чтобы подобрать минимальный набор тестов, который определит, дать ли зеленый свет проектам Gmail и Buzz.
Сценарий 1: изменение в общей библиотеке
Для первого сценария возьмем изменение, которое модифицирует файлы в common_collections_util, как показано на рис. 2.8.
Рис. 2.8. Изменение в common_collections_util.h
Отправив изменение, мы перемещаемся по линиям зависимостей вверх по графику. Так мы найдем все тесты, зависящие от изменений. Когда поиск завершится, а это займет лишь доли секунды, у нас будут все тесты, которые нужно прогнать, и мы получим актуальные статусы наших проектов (рис. 2.9).
Рис. 2.9. Тесты, на которые влияет изменение
Сценарий 2: изменение в зависимом проекте
Во втором примере возьмем изменение, которое модифицирует файлы в youtube_client (рис. 2.10).
Рис. 2.10. Изменение в youtube_client
Проведя аналогичный анализ, мы определим, что изменение влияет только на buzz_client_tests и что нужно актуализировать статус проекта Buzz (рис. 2.11).
Рис. 2.11. Buzz нужно обновить
Примеры показывают, как мы оптимизируем количество тестов, прогоняемых для одного изменения, без потери в точности результатов. Уменьшение количества тестов для одного изменения позволяет выполнить все нужные тесты для каждого зафиксированного изменения. Нам становится легче выявлять и отлаживать проблемы в проблемном изменении.
Умные инструменты и возможности инфраструктуры облачных вычислений сделали систему непрерывной интеграции быстрой и надежной. И мы постоянно стараемся ее улучшить, хотя она уже используется в тысячах проектов Google, чтобы выпускать проекты быстрее и проводить больше итераций. И — что важно — наш прогресс замечают пользователи.
Тест-сертификация
В начале книги Патрик Коупленд замечает, как сложно было привлечь разработчиков к тестированию. Первым делом мы создали им отличную компанию и наняли технически подкованных тестировщиков. А чтобы втянуть разработчиков в процесс, мы придумали «Тест-сертификацию». Оглядываясь назад, можно сказать, эта программа сыграла важную роль в становлении культуры тестирования разработчиками в Google.
Тест-сертификация начиналась как соревнование. Будут ли разработчики серьезно относиться к тестированию, если мы сделаем эту работу престижной? Что, если награждать разработчиков, которые следуют тестовым практикам? А что, если мы скажем, что они теперь сертифицированные инженеры? А может, еще ввести систему наградных бейджей (рис. 2.12), которыми можно пощеголять перед коллегами?
Рис. 2.12. Бейджи тест-сертификации показываются на вики-страницах проектов