В любой команде, которая уделает должное время тестированию, приходит тот момент, когда задается вопрос об автоматизации этого процесса. Как это происходит? Есть несколько путей для развития: либо сами тестировщики начинают автоматизировать, либо нанимается специально обученный человек, который, как панацея, должен решить все проблемы. В независимости от того, как это происходит, в конечном итоге мы все сталкиваемся с тем, что нужно как-то показать, что происходит, какова реальность — что же было сделано. Как говорил один мой коллега, «автоматизация ради автоматизации — это подобие культа Карго», так как бывает, что отдел автоматизации существует, а вот результата нет.
Итак, основная задача инженера-автоматизатора в том, чтобы сделать жизнь проще. В этот раз упростить жизнь мы собираемся отделу ручного тестирования (если таковой имеется) или же самим себе, если весь процесс тестирования возложен на наши плечи.
Немножко структурных данных
В нашей компании существует отдел ручного тестирования и автоматизаторы. Как система для организации тестов используется довольно популярный инструмент — 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
Тут, собственно говоря, все просто. Просто записываем команду так же, как мы бы ее запускали локально, разве только можно добавить несколько переменных для удобства и скомбинировать порядок запуска команд (в случае, если мы запускаем билд автоматически, сначала нужно указать команду на создание тестрана, потом на запуск тестов с номером, который пришел нам ранее).
Вот и все. Так как это мой первый опыт с написанием статьи, критика приветствуется. Надеюсь, что написал я все это вполне понятно и данное руководство будет кому-либо полезно.
Ссылка на репозиторий: github.com/Kirikami/test_rail_integration
Ссылка на библиотеку: rubygems.org/gems/test_rail_integration
ссылка на оригинал статьи http://habrahabr.ru/post/259359/
Добавить комментарий