Руководство по непрерывной интеграции: как повысить качество ПО и снизить риски.
Ранее мы разобрались в нюансах непрерывной поставки (CD), при которой в любой момент времени мы имеем готовое к выпуску в продакшн программное обеспечение. Это достигается за счет непрерывных циклов обратной связи. Непрерывная интеграция (CI) – это самое важное, что лежит в основе процесса CD, и причина, по которой он в принципе становится возможным.
Чтобы понять, что такое Continuous Integration, давайте выведем базовое определение. Первое слово означает “непрерывный”, а второе – “интеграция” или “объединение”. Таким образом, CI – это процесс, в котором что-то “непрерывно” “объединяется”.
Если рассуждать логически, следующий вопрос будет такой: что это за нечто, что объединяется, и где оно объединяется?
Учитывая, что CD – это всего лишь концептуальное расширение CI, ответ, вроде как, очевиден, не так ли?
“Что-то”, что объединяется (или еще говорят “сливается”) – это программный код, а “где” – это репозиторий или система контроля версий.
Таким образом, непрерывная интеграция – это процесс, в котором изменения в репозиторий с исходным кодом вносятся непрерывно, т.е. очень часто.
Кроме того, как уже говорилось в предыдущей статье, при каждом коммите в исходный код проекта автоматически запускаются тесты для выявления любых ошибок, тем самым создавая необходимый цикл обратной связи для непрерывной поставки.
Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ
Содержание:
Процесс непрерывной интеграции
Инструменты непрерывной интеграции
Внедрение CI и лучшие практики
Процесс непрерывной интеграции
Давайте вернемся к диаграмме конвейера CD, рассмотренной в предыдущей статье. Красный круг будет в центре нашего внимания в этой статье, чтобы понять процесс CI.
Несмотря на то, что процесс CI может показаться очень ориентированным на разработку, для QA-инженеров очень важно получить общую картину и адаптироваться соответствующим образом.
Прежде чем мы продолжим, важно знать следующую терминологию:
- Исходный код или система контроля версий содержит весь код, относящийся к проекту/функции.
- Главная ветка (mainline): самое последнее состояние кода в системе контроля версий.
- Локальная копия: если у вас был опыт работы с IDE типа Eclipse, вы знаете, что кодовую базу проекта можно импортировать на локальную машину в определенное место. Это место в вашей локальной системе является “локальной копией”.
- Переключение состояния (check out): когда разработчик приступает к работе, обычной практикой является импорт последней версии исходного кода в локальную копию. Это действие называется “Переключение состояния/версии”.
Допустим, два или три инженера-разработчика работают над функцией и используют непрерывную интеграцию.
Вот как выглядела бы последовательность событий:
1. На локальной копии разработчик создает свой код для новой фичи.
2. После написания кода он может добавить необходимые автоматизированные модульные тесты (юнит-тесты) для проверки своего кода.
3. Запускается локальная сборка, чтобы убедиться, что недавно добавленный код ничего не сломал.
4. После успешной сборки разработчик проверяет, не сделал ли кто-либо из его коллег новые изменения (коммиты) в главной ветке.
5. Если есть новые входящие изменения, он должен сначала принять эти входящие изменения, чтобы сделать свою локальную копию наиболее актуальной.
6. Синхронизация с главной веткой может привести к некоторым конфликтам из-за недавно объединенных локальных копий.
7. Если возникает конфликт, он исправляется таким образом, чтобы изменения были синхронизированы с кодом главной ветки.
8. После шага 7 изменения кода готовы к внесению в систему контроля версий. Это называется “фиксация изменений в коде” (code commit).
9. После коммита в CI запускается еще одна сборка, которая уже относится к главной ветке.
10. Теперь эта сборка готова к использованию на следующих этапах.
Инструменты непрерывной интеграции
Выбор инструментов непрерывной интеграции зависит от целей и потребностей той или иной компании.
Хотя некоторые из инструментов, такие как Hudson, CruiseControl, Jenkins, являются наиболее популярными, существует множество других инструментов, которые предоставляют аналогичные возможности в дополнение к своим собственным уникальным функциям.
Решение о выборе инструмента CI зависит от множества факторов, таких как:
- Возможность интеграции с инструментами управления конфигурацией
- Простая и настраиваемая отчетность
- Интеграция с инструментами для автоматизации тестирования и т.д.
Вы можете ознакомиться с основными функциями 15 таких продуктов, представленных в кратком обзоре инструментов непрерывной интеграции (англ.).
Преимущества CI
1. Раннее обнаружение ошибок. Если это ошибка в локальной копии или код был внесен в отдельную ветку без синхронизации с главной веткой, сбой сборки произойдет на соответствующем этапе. Это заставит разработчика исправить ошибку, прежде чем продолжить работу. Команды QA также получат от этого выгоду, поскольку они будут работать в основном над стабильными сборками.
2. Снижение накопления ошибок. Ошибки неизбежны, однако с использованием CI их количество значительно уменьшается. Риски могут быть минимальными в зависимости от того, насколько эффективна автоматизация, ведь ошибки легче обнаружить и исправить на ранней стадии разработки ПО.
3. Создание условий для непрерывной доставки. CI сокращает ручное вмешательство, поскольку сборка, sanity и другие тесты должны быть автоматизированы. Это прокладывает путь к успешной непрерывной поставке.
4. Повышенная прозрачность. CI делает более прозрачными общие процессы разработки и QA, так как дает четкое представление о том, какие тесты “падают” (не проходят), каковы причины этих падений, какие есть дефекты и т.д.
5. Экономическая эффективность. Исходя из вышеизложенных пунктов о раннем обнаружении ошибок, большей степени автоматизации и ясности во всей системе, нет необходимости говорить о том, что стоимость такой системы будет ниже.
CI в QA – точка зрения
Это естественное и логическое продолжение нашего предыдущего обсуждения. Для того чтобы использовать CI для тестирования, необходимо наличие факторов, перечисленных далее.
1. Начальные тесты. В последовательности событий мы остановились на том моменте, когда у нас есть хорошая сборка после коммита. Этот коммит должен вызвать некоторые автоматизированные тесты – smoke или sanity, подтверждающие, что сборка теперь готова для QA.
2. Фреймворк автоматизации. Чтобы оставаться верными CI, каждая команда QA должна инвестировать в создание фреймворка автоматизации тестирования, который автоматически запускает тесты, выявляющие не только недостатки конкретной фичи, но и определяющие требования к улучшению фреймворка (для текущих и новых тестов).
3. Параллельное тестирование с помощью автоматизации. Надежная система автоматизации облегчает параллельное тестирование и репликацию продакшн окружения с различными конфигурациями. Это также обеспечивает лучшее тестовое покрытие и пропуск меньшего количества ошибок.
Например, если требуется поддержка двух или более браузеров на определенных операционных системах, то тесты, имитирующие необходимые конфигурации, могут быть настроены и запущены параллельно, что значительно повышает эффективность тестирования.
4. Автоматизация различных видов тестирования. Продолжая предыдущий пункт, покрытие автотестами должно включать в себя различные типы тестирования – функциональное и нефункциональное (стресс-тесты, нагрузочные, тесты производительности, регрессионные, тесты базы данных, приемочные и т.д.).
5. Ошибки. Это особенно интересно, потому что даже регистрация ошибок может быть автоматизирована с помощью системы CI. Вы можете отслеживать появление определенных типов ошибок в логах и при их обнаружении автоматически регистрировать ошибку. Типичный пример такой ситуации – автоматическая регистрация ошибок для nullPointerExceptions, наблюдаемых в логах отслеживания сервера.
Внедрение CI и лучшие практики
Непрерывная интеграция направлена на резкое снижение количества ошибок при разработке программного обеспечения за счет механизмов обратной связи, автоматизации и быстрого исправления дефектов.
Реализация процесса CI и всех его механизмов может показаться слишком амбициозной задачей, но она, безусловно, может стать реальностью, если опираться на некоторые лучшие практики.
1. Общий репозиторий для поддержки кода. В условиях быстрого развития Agile само собой разумеющимся является наличие нескольких разработчиков, работающих над разными или одинаковыми фичами продукта. Поэтому совершенно необходимо иметь один репозиторий, в котором будет отражаться хронология изменений, вносимых всеми разработчиками.
Инструменты контроля версий помогают создавать различные направления разработки и лучше подготавливать команды, которые смогут соответствовать этим потребностям. Они также помогают хранить в одном месте все артефакты, необходимые для выполнения полной сборки (библиотеки, свойства, переменные окружения, тестовые сценарии и т.д.).
2. Запуск автоматизированных сборок через CLI. Сборки должны быть автоматизированы до такой степени, чтобы их можно было запускать через CLI.
Например, вы можете использовать ANT и Maven для запуска сборки. Это означает, что необходимо иметь возможность подключиться к серверу сборки, загрузить необходимые ресурсы из удаленного или локального репозитория, скомпилировать и запустить всю сборку с помощью простой команды в терминале. Иногда в большой сборке некоторые артефакты уже загружены как часть предыдущей сборки. Поэтому инструмент для сборки должен уметь определять и загружать только необходимые ресурсы.
Сборка может быть успешно скомпилирована, но это не значит, что она пригодна для тестирования. Поэтому также важно, чтобы некоторые тесты были включены как часть этапа сборки для обнаружения любых очевидных ошибок на ранней стадии.
3. Частые коммиты. Прелесть этой системы в том, что даже при наличии нескольких разработчиков конфликты при объединении кода легко обнаружить. Это происходит потому, что каждый разработчик должен обновить свою локальную копию, прежде чем он сможет сделать коммит. Когда это делается ежедневно или как можно чаще: больше коммитов = актуальнее локальная копия по сравнению с главной веткой. Чем актуальнее локальная копия, тем меньше конфликтов. Меньше конфликтов – выше стабильность!
4. Быстрое время сборки. Более длительное время сборки противоречит всей цели непрерывной интеграции, потому что невозможно получить постоянную быструю обратную связь. Во-вторых, частые коммиты кода будут становиться все более затруднительными. Как с этим бороться? Это подводит нас к следующей лучшей практике – поэтапным сборкам.
5. Поэтапные сборки. Чтобы ускорить процесс сборки, конвейер сборки может быть разбит на более мелкие части, которые будут выполняться параллельно.
6. Запуск сборки главной ветки на интеграционной машине. При описании последовательности событий в процессе CI мы говорили о запуске второй сборки, относящейся к главной ветке. Эта сборка происходит на интеграционной машине. Вы можете задаться вопросом, почему? Как тестировщики, мы сталкиваемся с ситуациями, когда ошибки видны только в определенном окружении, но не проявляются в другом. Именно по этой причине сборка главной ветки выполняется на интеграционной машине.
Иногда интеграционная машина преподносит сюрпризы, которых не было в локальной системе разработчика. Человеческие ошибки, например, не синхронизированный код с главной веткой, также проявляются здесь. Поэтому только после успешной сборки главной ветки можно оставить коммит.
7. Создание дубликата продакшн системы. Как тестировщики, мы хорошо знакомы с дефектами, связанными с окружением. Продакшн системы имеют свои собственные конфигурации в плане уровней баз данных, операционной системы, патчей ОС, библиотек, сетей, хранилищ и т.д.
Хорошей практикой является создание тестовой среды, максимально приближенной к реальной системе, если не точной копии. Таким образом, любые серьезные несоответствия и риски могут быть легко выявлены до того, как они попадут в продакшн системы.
8. Автоматизация развертывания. Для того чтобы перейти к запуску различных видов тестов в модели CI, необходимо предварительно выполнить настройку тестов. В качестве лучшей практики можно использовать скрипты, которые автоматически настраивают необходимые среды выполнения для тестирования.
9. Публикация URL сборок. При частом запуске сборок важно, чтобы все потребители знали, где можно найти последнюю сборку. Репозиторий, в котором публикуются сборки, может быть общим для всех участников процесса. Аналогично, для каждой сборки также должны быть опубликованы и результаты первоначального sanity тестирования, чтобы люди могли видеть, какие новые фичи или исправления были внесены.
Заключение
Применение CI в построении процесса тестирования оправдывает свою чрезвычайную полезность благодаря простору для автоматизации.
Как мы узнали выше, CI сокращает затраты на тестирование, при этом предлагая большую точность. Это крайне необходимо для процесса непрерывной поставки в целом.
CI/CD конвейер определенно способствует развитию Agile. Внедрение этих процедур сделает вас на шаг ближе к тому, чтобы адекватно реагировать на быстро меняющиеся и динамичные рынки.
Перевод статьи «Continuous Integration Process: How to Improve Software Quality and Reduce Risk».
Пингбэк: Что такое тестирование ПО? Виды, методы и инструменты тестирования