понедельник, 7 июля 2014 г.

TeamCity triggers & dependencies: построение процессов разработки и тестирования

В процессах разработки и тестирования программного обеспечения всегда можно выделить отдельные подпроцессы:
  • сборку или компиляцию (building, compilation) программных модулей из исходных кодов,
  • модульное unit-тестирование,
  • подготовку дистрибутивного пакета из собранных модулей,
  • тестирование сборки (Build Verification Testing),
  • сохранение дистрибутива в некоторой системе репозиториев,
  • проверка основной функциональности при помощи smoke-тестирования,
  • прочие виды тестирования: функциональное, интеграционное, стресс-тестирование, UI-тестирование, тестирование инсталляции, удобства использования, и т.д., которые также можно выделить в отдельные подпроцессы.
Каждый из подпроцессов обычно стремятся автоматизировать, связать друг с другом в единый процесс, непрерывный и зависящий от результатов каждого подпроцессв. В системе интеграции TeamCity, кроме непосредственно разработки конфигураций для автоматизации чего-либо, возможно организовать такие взаимосвязанные процессы. Для этого в ней предусмотрены механизмы триггеров (triggers) и зависимостей (dependencies) конфигураций. Рассмотрим их использование на примере двух разнонаправленных процессов: подготовки дистрибутива (I) и его тестирования (II).

Пусть для простоты в некотором абстрактном проекте Project выделено только четыре подпроцесса:
  1. Сборка проекта (включая unit-тестирование) – Building + unit-testing.
  2. Проверка сборки – BVT.
  3. Подготовка дистрибутива и сохранение его в репозиторий – Repo check-in.
  4. Запуск функциональных smoke-тестов – Smoke-testing.
Очевидно, что процессы зависимые: проверять сборку и инсталляцию можно только если успешно собран билд и на него прошли модульные тесты, сохранять билд в репозиторий можно только если все тесты сборки прошли успешно, а проверять основную функциональность сборки возможно только если эта сборка физически доступна в репозитории, чтобы её можно было скачать в автоматических smoke-тесты. Схематично направления обоих процессов изображены на Рис. 1.

Рис. 1. Схема процессов подготовки дистрибутива (I) и его тестирования (II).

Почему же подготовка дистрибутива и его тестирование – разнонаправленные процессы? Это связано с различными точками зрения. Первый процесс используют разработчики. С их точки зрения, подготовка дистрибутива заключается в последовательном выполнении подпроцессов 1-4, каждый из которых должен завершиться успешно. Со вторым процессом сталкиваются тестировщики. С их точки зрения, для того, чтобы они могли получить очередной билд на тестирование, на него должны быть успешно пройдены автоматические smoke-тесты. Для этого билд должен быть доступен в репозитории. Чтобы это произошло, на сборку должна быть запущена BVT-конфигурация. А для этого сам дистрибутив должен быть собран и на него должны завершиться модульные тесты. Таким образом, перед передачей сборки тестировщикам и началом процесса тестирования, подпроцессы в Project должны пройти в обратной последовательности: 4, 3, 2, 1.

Рис. 2. Отдельные несвязанные конфигурации для подпроцессов в Project.

Допустим, что отдельные конфигурации четырёх наших подпроцессов уже настроены в TeamCity (см. Рис. 2.). Объединим их в две цепочки, в два отдельных процесса. Для построения цепочки процессов (I) в TeamCity используются триггеры успешного завершения сборки, которые запускают текущую сборочную конфигурацию только в случае успешного завершения предыдущей. Для построения цепочки процессов (II) в TeamCity используются зависимые конфигурации, которые до исполнения текущей сборочной конфигурации запускают все конфигурации, от результатов которых она зависит.

Для настройки процесса (I) необходимо зайти в параметры конфигурации каждого подпроцесса, начиная со второго, и на вкладке Triggers добавить новый триггер: "Finish Build Trigger". Поле "Build configuration" должно указывать на предыдущий подпроцесс, успешное окончание которого (параметр "Trigger after successful build only") должно запускать текущую конфигурацию (см. Рис. 3.). Для одной конфигурации может быть добавлено несколько различных триггеров.

Рис. 3. Настройка триггеров для Project.

Для настройки процесса (II) необходимо зайти в параметры конфигурации каждого подпроцесса, начиная со второго, и на вкладке Dependencies добавить новую зависимость: "Add new snapshot dependency". Поле "Depend on" должно указывать на предыдущий подпроцесс, который требуется запустить перед запуском текущей конфигурации (см. Рис. 4.). Чтобы зависимый подпроцесс запускался каждый раз перед запуском текущей конфигурации, первые две опции в настройках должны быть выключены: "Do not run new build if there is a suitable one" и "Only use successful builds from suitable ones".

Рис. 4. Настройка зависимостей для Project.

После правильной настройки зависимостей, при запуске любого из связанных подпроцессов для родительского проекта (Project) в TeamCity появится вкладка Build Chains, на которой будут отображаться все когда либо запущенные цепочки подпроцессов (см. Рис. 5.). Это позволяет быстрее выявлять и локализовать проблемы в процессах проектов.

Рис. 5. Автоматически построенная цепочка зависимостей для Project.

Для одной конфигурации может быть добавлено несколько различных зависимостей. При запуске любой из связанных конфигураций, все конфигурации, от которых она зависит, также будут запущены (см. Рис. 6.).

Рис. 6. Автоматический запуск зависимых подпроцессов.

В конфигурациях, для которых определены зависимости, есть возможность использовать переменные определённые в связанных конфигурациях. Для этого используется префикс dep. к переменным, существующим в другой конфигурации. Пусть, например, в конфигурации "Building + unit-testing" в процессе исполнения изменяется значение переменной test_param. Тогда в конфигурации "BVT", которая зависит от "Build + unit-testing", можно использовать эту переменную следующим образом: %dep.build_id.test_param%, где build_id – идентификатор конфигурации "Build + unit-testing" (см. Рис. 7.).

Рис. 7. Использование переменных из связанной конфигурации.

Нужно помнить, что в TeamCity через триггер можно получить параметры из другой конфигурации через %dep.***%, только если с ней есть связь через dependency. Если же нет, но вам требуется получить или передать значение параметра в или из другой конфигурации, то можно воспользоваться возможностями TeamCity по управлению конфигурациями через HTTP-запросы. Например, чтобы из одной конфигурации запустить другую с параметрами, в любом её шаге (Build Step) можно сделать HTTP-запрос через curl вида:

curl -k -v "http(s)://testuser_login:testuser_password@teamcity-server-domain/httpAuth/action.html?add2Queue=build_id&name=param_1&value=param_1_value&name=param_2&value=param_2_value"

где testuser_login, testuser_password – логин и пароль пользователя TeamCity, у которого есть права на удалённый запуск конфигураций, минимально необходимы: Run build, View project and all parent projects, Customize build parameters;
teamcity-server-domain – сетевой адрес TeamCity;
build_id – идентификатор конфигурации, которую нужно запустить – это параметр Build configuration ID, который можно узнать на вкладке General Settings;
*name=, *value= – имена и значения множества параметров, которые нужно передать в запускаемую конфигурацию.

Таким образом, триггеры и зависимости в TeamCity позволяют вам выстраивать произвольные цепочки процессов, соответствующие нуждам вашего проекта.