Как помочь мануальному тестировщику. Автоматизаторы спешат на помощь

от автора

В любой команде, которая уделает должное время тестированию, приходит тот момент, когда задается вопрос об автоматизации этого процесса. Как это происходит? Есть несколько путей для развития: либо сами тестировщики начинают автоматизировать, либо нанимается специально обученный человек, который, как панацея, должен решить все проблемы. В независимости от того, как это происходит, в конечном итоге мы все сталкиваемся с тем, что нужно как-то показать, что происходит, какова реальность — что же было сделано. Как говорил один мой коллега, «автоматизация ради автоматизации — это подобие культа Карго», так как бывает, что отдел автоматизации существует, а вот результата нет.

Итак, основная задача инженера-автоматизатора в том, чтобы сделать жизнь проще. В этот раз упростить жизнь мы собираемся отделу ручного тестирования (если таковой имеется) или же самим себе, если весь процесс тестирования возложен на наши плечи.

Немножко структурных данных

В нашей компании существует отдел ручного тестирования и автоматизаторы. Как система для организации тестов используется довольно популярный инструмент — TestRail. С моей точки зрения удобный и довольно функциональный.
Автоматизация построена тоже на довольно стандартном наборе Ruby + Cucumber + Watir/Selenium (можно упомянуть паттерн Page Object) + TeamCity.

Что происходит, когда на тестирование дается новый билд, (в нашем случае каждый раз мы имеем дело с регрешшеном)? Тестировщик создает новый тест ран, в который включаются все тест-кейсы с определенного тест-сьюта и — пошло поехало веселье. Уверен, всем знакомо то чувство, когда ты в 4-й раз прогоняешь вручную регрешшн или смоук на автомате, кликая/тапая на все элементы и проставляя статус для очередного теста. В этот момент пред красными глазами наверняка все плывет и картинка в голове повторяет знаменитое:

image

А порой и:

image

Именно сейчас приходим на помощь мы. Так уж получилось, что возникла идея. Если у нас есть автоматизация, то почему мы все еще не используем результаты нашей работы, чтобы жить стало проще? Мысль заключается в том, чтобы использовать отчет с TestRail вместо громоздких и непонятных отчетов с Cucumber. Довольно интересная задач — сделать так, чтобы тесты в TestRail сами меняли свой статус, в зависимости от того, как прошел автотест.

С помощью поиска всемогущего гугла была найдена документация по TestRail API для реализации сией благой цели. Мы решили для начала сделать так, чтобы запуская наши автотесты вся информация о текущем состоянии тестов отображалась в TestRail. Собственно, цель была достигнута — по нажатии на кнопку запуска тестов в RubyMine мы автоматически создавали новый тестран и отсылали результаты на сервер. Довольно просто, учитывая существующую информацию на сайте TestRail.

Как оказалось, это было всего лишь начало.

В конечном итоге удалось сделать довольно неплохую функциональность, а именно — мы настроили интеграцию TestRail + TeamCity + Automation Framework.

Теперь же подробности, уважаемые дамы и господа.

TestRail

Первая остановка у нас буде TestRail.

TestRail является программным обеспечением для управления данными полученными в результате тестирования. Данный инструмент помогает отслеживать процессы, управлять программным обеспечением и организовывать команду.

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

Начнем мы с того, что первое, что должен сделать наш юзер/мануал тестировщик — это создать собственно тестран, который в последствии мы и будем использовать для апдейтов.

Требования:
Фича: Запуск автотестов.
Для того, чтобы использовать автоматизации в реальной жизни.
Как пользователь я хочу, чтобы была волшебная кнопка «запустить ран с автотестами».

image

Сказано — сделано. Благо функционал TestRail позволяет нам интегрировать свой собственный код.

Как результат, мы имеем вот такую вот кнопочку:

image

Да, да — 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.

Ссылка на репозиторий: github.com/Kirikami/test_rail_integration
Ссылка на библиотеку: rubygems.org/gems/test_rail_integration

ссылка на оригинал статьи http://habrahabr.ru/post/259359/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *