Pull to refresh

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

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

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

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


В нашей компании существует отдел ручного тестирования и автоматизаторы. Как система для организации тестов используется довольно популярный инструмент — 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 а так же моей любимой команды 24/7 Entertainment и IT Labs.

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

Articles