В первой части этой статьи я полностью описал процесс настройки автоматизации тестирования с помощью RM. Во второй (и последней) части статьи я расскажу о некоторых проектных решениях, проблемах, с которыми мы столкнулись при настройке системы, и способах преодоления этих проблем.
Решение: когда мы приступили к созданию определений выпуска, стало очевидно, что необходимо направлять каждое определение выпуска подходящему агенту, поскольку требования всех тестовых комплектов были различными. Сначала мы создавали отдельный пул агентов для каждого определения выпуска, но управлять большим количеством пулов агентов оказалось затруднительно. В конечном счете мы последовали совету Криса Паттерсона (Chris Patterson) из группы сборки и разработали систему, в которой использовался единственный пул агентов с названием RMAgentPool. Все агенты этого пула отличались друг от друга возможностями пользователя. Теперь каждое определение выпуска и определение сборки выполняется подходящим агентом с помощью возможности RmCdpCapability. Например, компьютер, который подготовлен для RM.CDP.TfsOnPrem, имеет возможность RmCdpCapability=TfsOnPrem:
RM.CDP.TfsOnPrem RD направляет свое выполнение этому агенту с помощью требования RmCdpCapability=TfsOnPrem:
Решение: когда поведение тестового комплекта непредсказуемо, мы включаем задачу «Pause Agent on test failure» («Приостановить агент при ошибке тестирования») в определении выпуска:
Эта задача приостанавливает выпуск при возникновении ошибки в непредсказуемом тесте. В этой ситуации разработчик может удаленно подключиться к агентскому компьютеру, состояние которого будет в точности совпадать с его состоянием в момент возникновения ошибки. Обратите внимание на то, что это возможно только в случае, если значение время ожидания среды равно 0 (время ожидания отсутствует).
Задача Pause принимает следующие аргументы (выделенные на иллюстрации выше):
-AlternateCredentialsUserName $(release.alternateusername) -AlternateCredentialsPassword $(release.alternatepassword) -ReleaseId $(Release.ReleaseId) -TaskName $(TaskToDebugName) -NumberOfSeconds $(TaskToDebugTimeInSeconds)
Ключевым аргументом здесь является $(TaskToDebugName): он имеет значение «Run RMCDPOnPrem tests» для RM.CDP.TfsOnPrem, т.е. название задачи, у которой происходят перемежающиеся сбои. Все определения выпусков RM.CDP.* включают в себя ту же задачу с теми же аргументами, но значение $(TaskToDebugName) в каждом определении выпуска соответствует задаче, чередующиеся сбои которой мы хотим отладить.
Исходный код этой задачи можно найти здесь (вместо «YourAccount» следует подставить название учетной записи и воспользоваться ей).
Решение: мы решили эту проблему с помощью задачи «Powershell on Target Machines» («Powershell на целевых компьютерах») и удаленного доступа к текущему агентскому компьютеру в роли администратора. Например, мы устанавливаем службу TFS в RM.CDP.RmEqTfs следующим образом:
Решение: для решения этой проблемы мы предприняли следующие действия:
Наше определение выпуска RM.CDP.DevFabricUpgrade выглядит следующим образом: главный тест выполняется с помощью сценария powershell RunAOConfigTest.ps1.
Затем выполняется задача VsTest, которая анализирует файл журнала и проверяет, есть ли в нем ошибки.
Примечание: до недавнего времени код теста RM.CDP.DevFabricUpgrade, совместимый с VsTest, просто помещал в файл журнала текст «Expected True, but found False» («Ожидалось значение True, но обнаружено False»), что серьезно осложняло отладку. Разработчики были вынуждены открывать выходной файл журнала RunAOConfigTest.ps1, что само по себе отнимало время, поскольку файл был весьма велик, и искать в нем реальную ошибку, как показано на снимке экрана ниже:
Недавно мы изменили этот код, чтобы тщательнее анализировать выходной файл журнала RunAOConfigTest.ps1. Теперь при неудачном тестировании выводится более подробная информация об ошибке:
Решение: поскольку большая часть наших тестов рассчитана на то, что развертывание службы и выполнение тестов выполняются на агентском компьютере, мы можем просто установить дополнительное оборудование (с правильной возможностью RmCdpCapability) на проблемные определения выпусков.
Решение: быстрый и примитивный способ решить эту проблему — запустить агент в интерактивном режиме (а не в режиме службы), поскольку в режиме службы агент не может взаимодействовать с настольным компьютером. Недостатком этого метода является то, что при выполнении агента в интерактивном режиме не поддерживаются функции автоматического обновления — для обновления агента требуется войти на агентский компьютер и перезапустить агент.
Более автоматизированный подход заключается в том, чтобы запустить агент в режиме службы и воспользоваться задачами «Visual Studio Test Agent Deployment» («Развертывание тестового агента Visual Studio») и «Visual Studio Test using Test Agent» («Выполнение теста Visual Studio с помощью тестового агента»), соответственно. Мы используем метод, аналогичный описанной выше задаче «Powershell on Target Machines» («Powershell на целевых компьютерах»), в которой мы удаленно входим на текущий агентский компьютер с правами администратора. Эти задачи выполняют на агенте службу тестирования, настроенную на взаимодействие с настольным компьютером.
Для того, чтобы воспользоваться этим методом, мы сначала создаем группу подходящих компьютеров в разделе Test (Тест):
Затем мы используем эту группу компьютеров в двух задачах тестового агента VS, упомянутых выше. В задаче VsTest Agent Deployment (Развертывание агента VsTest) необходимо выбрать «Interactive Process» («Интерактивный процесс»):
В конце задача «Vs Test using Test Agent» («Тест Vs с помощью тестового агента») выполняет тесты с помощью нашей группы компьютеров, при этом используются те же фильтры, что и в стандартной задаче VsTest:
Стоит отметить, что в ближайшем будущем этот процесс станет более последовательным; нам больше не потребуется создавать группы компьютеров для задач тестового агента и будет достаточно указать имя компьютера в параметре $(Agent.MachineName).
Решение: переменные, которые доступны в среде выполнения и которые могут использоваться в определении выпуска, перечислены в начале следующих журналов:
Решение: сначала служба RMO демонстрировала некоторую нестабильность при высоких нагрузках, однако во второй половине 2015 г. мы устранили ее с помощью серии стресс-тестов. Теперь RMO с легкостью справляется с задачами нашей группы. На приведенном ниже снимке экрана показано около 20 выпусков RM.CDP.DevFabircUpgrade, выполненных за последние 24 часа, что соответствует 20 * 9 = 180 выпускам нашей группы за тот же период времени.
Я надеюсь, что эта публикация поможет вам решить большинство проблем, возникающих при автоматизации тестирования с помощью RM.
Один или несколько пулов агентов?
Вопрос: как перенаправить определение выпуска на подходящий агентский компьютер, т.е. на компьютер с ресурсами, необходимыми этому определению выпуска?Решение: когда мы приступили к созданию определений выпуска, стало очевидно, что необходимо направлять каждое определение выпуска подходящему агенту, поскольку требования всех тестовых комплектов были различными. Сначала мы создавали отдельный пул агентов для каждого определения выпуска, но управлять большим количеством пулов агентов оказалось затруднительно. В конечном счете мы последовали совету Криса Паттерсона (Chris Patterson) из группы сборки и разработали систему, в которой использовался единственный пул агентов с названием RMAgentPool. Все агенты этого пула отличались друг от друга возможностями пользователя. Теперь каждое определение выпуска и определение сборки выполняется подходящим агентом с помощью возможности RmCdpCapability. Например, компьютер, который подготовлен для RM.CDP.TfsOnPrem, имеет возможность RmCdpCapability=TfsOnPrem:
RM.CDP.TfsOnPrem RD направляет свое выполнение этому агенту с помощью требования RmCdpCapability=TfsOnPrem:
Отладка JIT
Вопрос: как отлаживать перемежающиеся сбои, когда файлы журналов содержат в себе недостаточно данных? К моменту, когда разработчики обнаруживают проблему, следующий запуск теста удаляет «ошибочное состояние» с тестового компьютера.Решение: когда поведение тестового комплекта непредсказуемо, мы включаем задачу «Pause Agent on test failure» («Приостановить агент при ошибке тестирования») в определении выпуска:
Эта задача приостанавливает выпуск при возникновении ошибки в непредсказуемом тесте. В этой ситуации разработчик может удаленно подключиться к агентскому компьютеру, состояние которого будет в точности совпадать с его состоянием в момент возникновения ошибки. Обратите внимание на то, что это возможно только в случае, если значение время ожидания среды равно 0 (время ожидания отсутствует).
Задача Pause принимает следующие аргументы (выделенные на иллюстрации выше):
-AlternateCredentialsUserName $(release.alternateusername) -AlternateCredentialsPassword $(release.alternatepassword) -ReleaseId $(Release.ReleaseId) -TaskName $(TaskToDebugName) -NumberOfSeconds $(TaskToDebugTimeInSeconds)
Ключевым аргументом здесь является $(TaskToDebugName): он имеет значение «Run RMCDPOnPrem tests» для RM.CDP.TfsOnPrem, т.е. название задачи, у которой происходят перемежающиеся сбои. Все определения выпусков RM.CDP.* включают в себя ту же задачу с теми же аргументами, но значение $(TaskToDebugName) в каждом определении выпуска соответствует задаче, чередующиеся сбои которой мы хотим отладить.
Исходный код этой задачи можно найти здесь (вместо «YourAccount» следует подставить название учетной записи и воспользоваться ей).
Как выполнять тесты в режиме администратора на агентском компьютере?
Вопрос: даже если агент выполняется с правами администратора, то он выполняет задачу в режиме, отличном от режима администратора. Это делает невозможным выполнение задачи, которую необходимо выполнять в режиме администратора (например, установка службы на агентском компьютере).Решение: мы решили эту проблему с помощью задачи «Powershell on Target Machines» («Powershell на целевых компьютерах») и удаленного доступа к текущему агентскому компьютеру в роли администратора. Например, мы устанавливаем службу TFS в RM.CDP.RmEqTfs следующим образом:
Тесты, которые не могут повторно воспользоваться задачей VsTest
Вопрос: некоторые тесты были созданы относительно давно (мы будем называть их «устаревшими») и не совместимы с задачей VsTest. Как в таких ситуациях воспользоваться всеми преимуществами подготовки отчетов, которые обеспечивают тесты, совместимые с задачей VsTest?Решение: для решения этой проблемы мы предприняли следующие действия:
- Мы выполнили устаревшие тесты с помощью пакетного сценария или задачи powershell (в зависимости от того, что удобнее) и определили местоположение выходного файла журнала.
- Мы добавили задачу VsTest, которая проводила анализ выходного файла журнала, обнаруженного на предыдущем этапе, и определяла, было ли выполнение теста успешным.
Наше определение выпуска RM.CDP.DevFabricUpgrade выглядит следующим образом: главный тест выполняется с помощью сценария powershell RunAOConfigTest.ps1.
Затем выполняется задача VsTest, которая анализирует файл журнала и проверяет, есть ли в нем ошибки.
Примечание: до недавнего времени код теста RM.CDP.DevFabricUpgrade, совместимый с VsTest, просто помещал в файл журнала текст «Expected True, but found False» («Ожидалось значение True, но обнаружено False»), что серьезно осложняло отладку. Разработчики были вынуждены открывать выходной файл журнала RunAOConfigTest.ps1, что само по себе отнимало время, поскольку файл был весьма велик, и искать в нем реальную ошибку, как показано на снимке экрана ниже:
Недавно мы изменили этот код, чтобы тщательнее анализировать выходной файл журнала RunAOConfigTest.ps1. Теперь при неудачном тестировании выводится более подробная информация об ошибке:
Как устранить узкие места при выполнении тестов?
Вопрос: выполнение некоторых определений выпуска занимает очень много времени, что приводит к появлению очереди и существенно увеличивает время их обработки. Что можно улучшить в данной ситуации?Решение: поскольку большая часть наших тестов рассчитана на то, что развертывание службы и выполнение тестов выполняются на агентском компьютере, мы можем просто установить дополнительное оборудование (с правильной возможностью RmCdpCapability) на проблемные определения выпусков.
Как выполнять тесты пользовательского интерфейса?
Вопрос: как выполнять тесты пользовательского интерфейса на агентском компьютере?Решение: быстрый и примитивный способ решить эту проблему — запустить агент в интерактивном режиме (а не в режиме службы), поскольку в режиме службы агент не может взаимодействовать с настольным компьютером. Недостатком этого метода является то, что при выполнении агента в интерактивном режиме не поддерживаются функции автоматического обновления — для обновления агента требуется войти на агентский компьютер и перезапустить агент.
Более автоматизированный подход заключается в том, чтобы запустить агент в режиме службы и воспользоваться задачами «Visual Studio Test Agent Deployment» («Развертывание тестового агента Visual Studio») и «Visual Studio Test using Test Agent» («Выполнение теста Visual Studio с помощью тестового агента»), соответственно. Мы используем метод, аналогичный описанной выше задаче «Powershell on Target Machines» («Powershell на целевых компьютерах»), в которой мы удаленно входим на текущий агентский компьютер с правами администратора. Эти задачи выполняют на агенте службу тестирования, настроенную на взаимодействие с настольным компьютером.
Для того, чтобы воспользоваться этим методом, мы сначала создаем группу подходящих компьютеров в разделе Test (Тест):
Затем мы используем эту группу компьютеров в двух задачах тестового агента VS, упомянутых выше. В задаче VsTest Agent Deployment (Развертывание агента VsTest) необходимо выбрать «Interactive Process» («Интерактивный процесс»):
В конце задача «Vs Test using Test Agent» («Тест Vs с помощью тестового агента») выполняет тесты с помощью нашей группы компьютеров, при этом используются те же фильтры, что и в стандартной задаче VsTest:
Стоит отметить, что в ближайшем будущем этот процесс станет более последовательным; нам больше не потребуется создавать группы компьютеров для задач тестового агента и будет достаточно указать имя компьютера в параметре $(Agent.MachineName).
Какие переменные доступны в среде выполнения?
Вопрос: какие переменные доступны в среде выполнения?Решение: переменные, которые доступны в среде выполнения и которые могут использоваться в определении выпуска, перечислены в начале следующих журналов:
Можно ли масштабировать RM в соответствии с потребностями нашей группы?
Вопрос: по мере приближения к концу спринта количество проверок в нашей группе экспоненциально возрастает, и у нас появились сомнения в том, что RMO справится с этими нагрузками. Выполнение 15 проверок в день на этапе выпуска является обычной практикой и подразумевает 15 * 9 = ~135 развертываний в день (поскольку каждая проверка активирует девять определений выпуска).Решение: сначала служба RMO демонстрировала некоторую нестабильность при высоких нагрузках, однако во второй половине 2015 г. мы устранили ее с помощью серии стресс-тестов. Теперь RMO с легкостью справляется с задачами нашей группы. На приведенном ниже снимке экрана показано около 20 выпусков RM.CDP.DevFabircUpgrade, выполненных за последние 24 часа, что соответствует 20 * 9 = 180 выпускам нашей группы за тот же период времени.
Заключение
Я надеюсь, что эта публикация поможет вам решить большинство проблем, возникающих при автоматизации тестирования с помощью RM.