В любой команде, которая уделяет должное время тестированию, приходит тот момент, когда задается вопрос об автоматизации этого процесса. Как это происходит? Есть несколько путей для развития: либо сами тестировщики начинают автоматизировать, либо нанимается специально обученный человек, который, как панацея, должен решить все проблемы. В независимости от того, как это происходит, в конечном итоге мы все сталкиваемся с тем, что нужно как-то показать, что происходит, какова реальность — что же было сделано. Как говорил один мой коллега, «автоматизация ради автоматизации — это подобие культа Карго», так как бывает, что отдел автоматизации существует, а вот результата нет.
Итак, основная задача инженера-автоматизатора в том, чтобы сделать жизнь проще. В этот раз упростить жизнь мы собираемся отделу ручного тестирования (если таковой имеется) или же самим себе, если весь процесс тестирования возложен на наши плечи.
В нашей компании существует отдел ручного тестирования и автоматизаторы. Как система для организации тестов используется довольно популярный инструмент — TestRail. С моей точки зрения удобный и довольно функциональный.
Автоматизация построена тоже на довольно стандартном наборе Ruby + Cucumber + Watir/Selenium (можно упомянуть паттерн Page Object) + TeamCity.
Что происходит, когда на тестирование дается новый билд, (в нашем случае каждый раз мы имеем дело с регрешшеном)? Тестировщик создает новый тест ран, в который включаются все тест-кейсы с определенного тест-сьюта и — пошло поехало веселье. Уверен, всем знакомо то чувство, когда ты в 4-й раз прогоняешь вручную регрешшн или смоук на автомате, кликая/тапая на все элементы и проставляя статус для очередного теста. В этот момент пред красными глазами наверняка все плывет и картинка в голове повторяет знаменитое:
А порой и:
Именно сейчас приходим на помощь мы. Так уж получилось, что возникла идея. Если у нас есть автоматизация, то почему мы все еще не используем результаты нашей работы, чтобы жить стало проще? Мысль заключается в том, чтобы использовать отчет с TestRail вместо громоздких и непонятных отчетов с Cucumber. Довольно интересная задач — сделать так, чтобы тесты в TestRail сами меняли свой статус, в зависимости от того, как прошел автотест.
С помощью поиска всемогущего гугла была найдена документация по TestRail API для реализации сией благой цели. Мы решили для начала сделать так, чтобы запуская наши автотесты вся информация о текущем состоянии тестов отображалась в TestRail. Собственно, цель была достигнута — по нажатии на кнопку запуска тестов в RubyMine мы автоматически создавали новый тестран и отсылали результаты на сервер. Довольно просто, учитывая существующую информацию на сайте TestRail.
Как оказалось, это было всего лишь начало.
В конечном итоге удалось сделать довольно неплохую функциональность, а именно — мы настроили интеграцию TestRail + TeamCity + Automation Framework.
Теперь же подробности, уважаемые дамы и господа.
Первая остановка у нас будет TestRail.
TestRail является программным обеспечением для управления данными полученными в результате тестирования. Данный инструмент помогает отслеживать процессы, управлять программным обеспечением и организовывать команду.
С помощью TestRail можно создавать тест кейсы, управлять тестовыми наборами и координировать весь процесс тестирования программного обеспечения. TestRail предоставляет возможность повысить производительность и получить полный обзор хода процесса тестирования.
Начнем мы с того, что первое, что должен сделать наш юзер/мануал тестировщик — это создать собственно тестран, который в последствии мы и будем использовать для апдейтов.
Требования:
Фича: Запуск автотестов.
Для того, чтобы использовать автоматизации в реальной жизни.
Как пользователь я хочу, чтобы была волшебная кнопка «запустить ран с автотестами».
Сказано — сделано. Благо функционал TestRail позволяет нам интегрировать свой собственный код.
Как результат, мы имеем вот такую вот кнопочку:
Да, да — Start Tests.
Поскольку у нас для одного сьюта тесткейсы есть для веб и мобайл, то на первой стадии мы проверяем по имени тестрана, какой именно фреймворк используется. В зависимости от того, для чего предназначен тестран, мы запускаем билд на TeamCity.
Дабы юзер не кликал слишком часто на кнопочку, у нас организована защита от дурака — после клика на кнопку мы добавляем ключевое «in progress» к имени тестрана, это блокирует волшебную кнопку, пока наши автотесты не закончат свое дело.
На конечной стадии был создан гем/библиотека, которая при разворачивании дает нам интеграцию с TestRail на любом нашем под-проекте.
Создание гема — совсем другая история, достойная отдельной статьи.
Если вкратце, то наша библиотека test_rail_integration имеет небольшой функционал, который мы используем у себя, но мне кажется, что кому-то тоже может быть полезной.
Для начала нужно его установить:
Далее добавить:
В after |scenario| hooks. И в env.rb файл:
Вот команды для запуска:
В нашем случае тесты запускались для 6 различных локализаций и все результаты отображались в 1 тестране. Иногда возникала ситуация, когда два апдейта приходили в одно время. Получалось так, что они не видели друг друга и после фейла приходил пасс статус. Такой вариант менял общую картину статуса теста. В общем, эта команда проходит все тесты и проверяет в ней соответствие, что в зеленых тестах нет красных результатов. Если же есть — то меняет статус теста на красный.
Тут все просто, данной командой мы создаем тестран с указанным именем в проекте-сьюте, который мы записали в конфиг файле. Команда возвращает номер созданного тесана:
Нужно написать при первом запуске, так как данная команда генерирует конфигурационный файл, к котором нужно указать необходимую информацию о TestRail:
Это и есть core фунционал c флагами:
Тут и так все понятно, нужно указать номер тест рана:
Специфические атрибуты, которые будут использованы при составлении команды для запуска (если, к примеру, вам нужно запускать ваши тесты через специфическую команду, то в конфиг файле нужно записать ее с использованием этих переменных, тогда при запуске мы должны их указать):
Этот флаг тоже специфический и, думаю, никому больше не пригодится:
Здесь можно указать новую команду для текущего запуска:
Так как у нас используется вся интеграция для 6 локализаций, то по номеру тестрана мы ищем имя и парсим его на параметры так, что тестран должен иметь имя, допустим, DT SG staging. Здесь мы и находим необходимую информацию для запуска.
Запуск без поиска и проверки на наличие каких-либо параметров, это наиболее полезная команда для Вас, уважаемый читатель.
Можно определить также номер типа тестов, которые буду запущены.
Полная команда для запуска тестов с существующим тестраном будет выглядеть так:
Либо же:
Тут, собственно говоря, все просто. Просто записываем команду так же, как мы бы ее запускали локально, разве только можно добавить несколько переменных для удобства и скомбинировать порядок запуска команд (в случае, если мы запускаем билд автоматически, сначала нужно указать команду на создание тестрана, потом на запуск тестов с номером, который пришел нам ранее).
Вот и все. Так как это мой первый опыт с написанием статьи, критика приветствуется. Надеюсь, что написал я все это вполне понятно и данное руководство будет кому-либо полезно.
Ссылка на репозиторий: github.com/Kirikami/test_rail_integration
Ссылка на библиотеку: rubygems.org/gems/test_rail_integration
Итак, основная задача инженера-автоматизатора в том, чтобы сделать жизнь проще. В этот раз упростить жизнь мы собираемся отделу ручного тестирования (если таковой имеется) или же самим себе, если весь процесс тестирования возложен на наши плечи.
Немножко структурных данных
В нашей компании существует отдел ручного тестирования и автоматизаторы. Как система для организации тестов используется довольно популярный инструмент — TestRail. С моей точки зрения удобный и довольно функциональный.
Автоматизация построена тоже на довольно стандартном наборе Ruby + Cucumber + Watir/Selenium (можно упомянуть паттерн Page Object) + TeamCity.
Что происходит, когда на тестирование дается новый билд, (в нашем случае каждый раз мы имеем дело с регрешшеном)? Тестировщик создает новый тест ран, в который включаются все тест-кейсы с определенного тест-сьюта и — пошло поехало веселье. Уверен, всем знакомо то чувство, когда ты в 4-й раз прогоняешь вручную регрешшн или смоук на автомате, кликая/тапая на все элементы и проставляя статус для очередного теста. В этот момент пред красными глазами наверняка все плывет и картинка в голове повторяет знаменитое:
А порой и:
Именно сейчас приходим на помощь мы. Так уж получилось, что возникла идея. Если у нас есть автоматизация, то почему мы все еще не используем результаты нашей работы, чтобы жить стало проще? Мысль заключается в том, чтобы использовать отчет с TestRail вместо громоздких и непонятных отчетов с Cucumber. Довольно интересная задач — сделать так, чтобы тесты в TestRail сами меняли свой статус, в зависимости от того, как прошел автотест.
С помощью поиска всемогущего гугла была найдена документация по TestRail API для реализации сией благой цели. Мы решили для начала сделать так, чтобы запуская наши автотесты вся информация о текущем состоянии тестов отображалась в TestRail. Собственно, цель была достигнута — по нажатии на кнопку запуска тестов в RubyMine мы автоматически создавали новый тестран и отсылали результаты на сервер. Довольно просто, учитывая существующую информацию на сайте TestRail.
Как оказалось, это было всего лишь начало.
В конечном итоге удалось сделать довольно неплохую функциональность, а именно — мы настроили интеграцию TestRail + TeamCity + Automation Framework.
Теперь же подробности, уважаемые дамы и господа.
TestRail
Первая остановка у нас будет TestRail.
TestRail является программным обеспечением для управления данными полученными в результате тестирования. Данный инструмент помогает отслеживать процессы, управлять программным обеспечением и организовывать команду.
С помощью TestRail можно создавать тест кейсы, управлять тестовыми наборами и координировать весь процесс тестирования программного обеспечения. TestRail предоставляет возможность повысить производительность и получить полный обзор хода процесса тестирования.
Начнем мы с того, что первое, что должен сделать наш юзер/мануал тестировщик — это создать собственно тестран, который в последствии мы и будем использовать для апдейтов.
Требования:
Фича: Запуск автотестов.
Для того, чтобы использовать автоматизации в реальной жизни.
Как пользователь я хочу, чтобы была волшебная кнопка «запустить ран с автотестами».
Сказано — сделано. Благо функционал TestRail позволяет нам интегрировать свой собственный код.
Как результат, мы имеем вот такую вот кнопочку:
Да, да — Start Tests.
Собственно код для этой кнопки.
name: Trigger tests
for run
description: Triggers automated tests
for a test run
author: Gurock Software
version: 1.0
includes: ^ runs / view
excludes:
js:
$(document).ready(
function() {
/* Create the button */
var button = $('<div id="start_auto_test" class="toolbar content-header-toolbar"><a class="toolbar-button toolbar-button-last toolbar-button-first content-header-button button-start" href="javascript:void(0)">Start Tests</a></div>');
/* Add it to the toolbar */
//if ($('.toolbar-button.content-header-button.button-edit').length > 0) {
$("#content-header .content-header-inner").prepend(button);
//}
/* Disable test run button */
if (uiscripts.context.run.name.indexOf('in progress') >= 0 || (uiscripts.context.plan != undefined && uiscripts.context.plan.name.indexOf('in progress') >= 0)) {
$("a", button).addClass('toolbar-button-disabled button-add-disabled');
}
/* Bind the click event to trigger the automated tests */
$("a", button).click(
function() {
if (!$("a", button).hasClass("button-add-disabled")) {
App.Dialogs.message(
'The tests are being processed in the background and the results are automatically posted back to TestRail.',
'Confirmation'
);
platform = uiscripts.context.run.name.split(" ")[0];
ventures = uiscripts.context.run.name.split(" ")[1];
if (platform == 'OMS') {
var teamcity_oms_build_trigger_url = 'http://TeamCityServer/httpAuth/action.html?add2Queue=BuildName&name=reverse.dep.*.test_run_id&value=' + uiscripts.context.run.id;
}
popup = window.open(teamcity_build_trigger_url, "windowName", "height=200,width=200");
setTimeout(function() {
popup.close();
}, 1000);
/* Change the test run/test plan name to disable button */
var api_url, new_data;
if (uiscripts.context.plan == undefined) {
api_url = uiscripts.env.page_base + '/api/v2/update_run/' + uiscripts.context.run.id;
new_data = JSON.stringify({
"name": uiscripts.context.run.name + ' (in progress)'
});
} else {
var entries = [];
$.ajax({
url: uiscripts.env.page_base + '/api/v2/get_plan/' + uiscripts.context.plan.id,
type: 'GET',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: new_data,
success: function(data) {
entries = data.entries;
var selected_entry;
$.each(entries, function(index, entry) {
if (entry.name == uiscripts.context.run.name) {
return selected_entry = entry;
}
});
api_url = uiscripts.env.page_base + '/api/v2/update_plan_entry/' + uiscripts.context.plan.id + '/' + selected_entry.id;
new_data = JSON.stringify({
"name": uiscripts.context.run.name + ' (in progress)'
});
$.ajax({
url: api_url,
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: new_data,
success: function(data) {
$("a", button).addClass('toolbar-button-disabled button-add-disabled');
}
});
}
});
};
$.ajax({
url: api_url,
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: new_data,
success: function(data) {
$("a", button).addClass('toolbar-button-disabled button-add-disabled');
}
});
}
}
);
}
);
Поскольку у нас для одного сьюта тесткейсы есть для веб и мобайл, то на первой стадии мы проверяем по имени тестрана, какой именно фреймворк используется. В зависимости от того, для чего предназначен тестран, мы запускаем билд на TeamCity.
Дабы юзер не кликал слишком часто на кнопочку, у нас организована защита от дурака — после клика на кнопку мы добавляем ключевое «in progress» к имени тестрана, это блокирует волшебную кнопку, пока наши автотесты не закончат свое дело.
Automation Framework
На конечной стадии был создан гем/библиотека, которая при разворачивании дает нам интеграцию с TestRail на любом нашем под-проекте.
Создание гема — совсем другая история, достойная отдельной статьи.
Если вкратце, то наша библиотека test_rail_integration имеет небольшой функционал, который мы используем у себя, но мне кажется, что кому-то тоже может быть полезной.
Для начала нужно его установить:
gem install test_rail_integration
Далее добавить:
TestRail::Hook.update_test_rail(scenario)
В after |scenario| hooks. И в env.rb файл:
if ENV['TESTRAIL'] == '1'
puts 'Option : TestRail [ON]'
require "test_rail_integration"
require 'test_rail_integration/generator/test_rail_hooks'
end
Вот команды для запуска:
test_rail_integration check_test_run_and_update
В нашем случае тесты запускались для 6 различных локализаций и все результаты отображались в 1 тестране. Иногда возникала ситуация, когда два апдейта приходили в одно время. Получалось так, что они не видели друг друга и после фейла приходил пасс статус. Такой вариант менял общую картину статуса теста. В общем, эта команда проходит все тесты и проверяет в ней соответствие, что в зеленых тестах нет красных результатов. Если же есть — то меняет статус теста на красный.
test_rail_integration create_test_run
Тут все просто, данной командой мы создаем тестран с указанным именем в проекте-сьюте, который мы записали в конфиг файле. Команда возвращает номер созданного тесана:
test_rail_integration perform
Нужно написать при первом запуске, так как данная команда генерирует конфигурационный файл, к котором нужно указать необходимую информацию о TestRail:
test_rail_integration shoot
Это и есть core фунционал c флагами:
--test_run_id
Тут и так все понятно, нужно указать номер тест рана:
--venture
и --env
Специфические атрибуты, которые будут использованы при составлении команды для запуска (если, к примеру, вам нужно запускать ваши тесты через специфическую команду, то в конфиг файле нужно записать ее с использованием этих переменных, тогда при запуске мы должны их указать):
--showroom
Этот флаг тоже специфический и, думаю, никому больше не пригодится:
--command
Здесь можно указать новую команду для текущего запуска:
--auto
Так как у нас используется вся интеграция для 6 локализаций, то по номеру тестрана мы ищем имя и парсим его на параметры так, что тестран должен иметь имя, допустим, DT SG staging. Здесь мы и находим необходимую информацию для запуска.
--simple
Запуск без поиска и проверки на наличие каких-либо параметров, это наиболее полезная команда для Вас, уважаемый читатель.
--type
Можно определить также номер типа тестов, которые буду запущены.
Полная команда для запуска тестов с существующим тестраном будет выглядеть так:
test_rail_integration shoot --test_run_id 1 --simple
Либо же:
test_rail_integration shoot --test_run_id 1 --simple --command <cucumber -t > --type 3
TeamCity
Тут, собственно говоря, все просто. Просто записываем команду так же, как мы бы ее запускали локально, разве только можно добавить несколько переменных для удобства и скомбинировать порядок запуска команд (в случае, если мы запускаем билд автоматически, сначала нужно указать команду на создание тестрана, потом на запуск тестов с номером, который пришел нам ранее).
Вот и все. Так как это мой первый опыт с написанием статьи, критика приветствуется. Надеюсь, что написал я все это вполне понятно и данное руководство будет кому-либо полезно.
Время для профессиональных благодарностей
Хотелось поблагодарить за помощь и наставления следующих людей: Любовь Шишова, Евгений Пустовит, Сливка Василий, Дмитрий Коновалов, Никита Никон, Игорь Роздобудько, Андрей Толпеев и Alexis Grohar а так же моей любимой команды 24/7 Entertainment и IT Labs.
Ссылка на репозиторий: github.com/Kirikami/test_rail_integration
Ссылка на библиотеку: rubygems.org/gems/test_rail_integration