Всем привет! Меня зовут Иван Чечиков, я QA lead в МТС Digital, работаю над проектом стримингового сервиса WASD.TV. В этой статье я поделюсь опытом внедрения системы управления тестированием (TMS) Allure TestOps в наш проект и расскажу, что из этого получилось. А еще отмечу подводные камни, с которыми мы столкнулись и обозначу пути их обхода. Статья может быть полезна тем, кто задумываются о переходе на данную TMS с других готовых решений, таких так Zephyr, TestRail, Test IT.

Allure TestOps – это коробочное решение, позволяющее управлять как ручным, так и автоматизированным тестированием: создавать тест-кейсы и чек-листы, запускать ручные и автоматические прогоны, заводить дефекты и собирать статистику по проделанной работе. Также у Allure большой набор интеграций с различными инструментами и языками программирования.
В нашем проекте для QA мы используем Jira Server, Confluence, Jenkins CI/CD, автотесты на Java + Maven + Cucumber + Gherkin + Serenity RestAssured (для API тестов) и Selenium (для UI тестов). Как основную TMS применяли плагин Zephyr для Jira, но нам предстоял переезд на Allure Test Ops. Что делать в таком случае?
-
Нужно настроить интеграцию с Jira Server и Allure TestOps.
-
Нужно перенести существующие тестовые артефакты из надстройки Zephyr в Jira в Allure TestOps и уйти в дальнейшем от Zephyr.
-
Нужно настроить запуск автотестов в Allure TestOps, подружив его с нашей джобой в Jenkins CI/CD и получать результаты прогонов. На данный момент мы работаем с Gitlab CI/CD, но опыт с Jenkins был также уникален для нас.
-
Объединить ручные и автотесты в один проект в Allure TestOps.
-
Написать инструкции для QA-инженеров по использованию Allure Test Ops
-
Начать работать в Allure TestOps.
-
Собрать первые метрики по проделанной работе.
Разберем каждый этап подробно:
Интеграция с Jira Server или Jira Cloud – дело несложное, выполняется как на стороне Allure, так и на стороне Jira. Создаем интеграцию с Jira в Allure TestOps, указываем креды и эндпоинт Jira Server.
Allure TestOps


В Jira в панели Администратора необходимо установить плагин Allure TestOps for JIRA

Указываем эндпоинты Allure Test Ops, выбираем версию 4.x.x и проставляем id интеграции Jira в Allure. Ссылка на официальный мануал.
Jira Server

Единственное замечание – желательно иметь актуальную версию Jira не ниже 8.4 (Jira Server) и Allure TestOps не ниже 4.2.2, иначе интеграция может быть неполноценной, у нас, к примеру, не отображались прогоны с Allure в Jira.
Результаты интеграции: отображение прогонов и тестовой документации из Allure в Jira.

Кейсы из плагина Zephyr в Jira мы переносили через скрипт Qameta, для нас его существование было неочевидным, поэтому пришлось писать в поддержку. Скрипт лежит на сайте у разработчиков, миграцию мы делали на удаленной машине, имеющей доступы к эндпоинтам Allure и Jira. Вызывали скрипт, передавая json в виде конфига.
java -jar allure-testops-migration-2.9.5.jar config
Проблем с миграцией не было. Все наши 2000 с лишним кейсов мигрировали в Test Cases Allure TestOps, все поля тестовых артефактов были перенесены.
Интеграция с Jenkins CI/CD заняла значительное количество времени. Проблемы были как с самой джобой дженкинса, так и с конфигурацией кода проекта. Подружить Jenkins и Allure TestOps на уровне интеграции не так сложно.
В Jenkins CI/CD в разделе плагинов устанавливаем плагин Allure TestOps for Jenkins последней версии. Это важно, так как может не произойти выгрузка результатов автотестов в Allure TestOps.
Jenkins

В настройках системы в Jenkins указываем эндпоинт Allure TestOps и админские креды.

В Allure Test Ops прописываем эндпоинт Jenkins.


У нас автотесты на Java с использованием Maven, Cucumber, Gherkin, Serenity и Selenium. Для получения результатов в Allure с прогонов автотестов пришлось править конфигурационный файл pom.xml. Я добавил зависимости:
pom.xml
<dependencies> ...... <dependency> <groupId>io.qameta.allure</groupId> <artifactId>allure-junit4-aspect</artifactId> <version>2.0-BETA15</version> </dependency> <dependency> <groupId>io.qameta.allure</groupId> <artifactId>allure-rest-assured</artifactId> <version>2.18.1</version> </dependency> <dependency> <groupId>io.qameta.allure</groupId> <artifactId>allure-cucumber5-jvm</artifactId> <version>2.18.0</version> </dependency> ...... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M4</version> <configuration> <forkCount>3</forkCount> <reuseForks>true</reuseForks> <argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine> <testFailureIgnore>true</testFailureIgnore> <includes> <include>**/*${type.of.suite}.java</include> </includes> <systemPropertyVariables> <webdriver.base.url>${webdriver.base.url}</webdriver.base.url> <allure.results.directory>${project.build.directory}/allure-results</allure.results.directory> </systemPropertyVariables> <parallel>classes</parallel> <threadCount>${parallel.tests}</threadCount> <forkCount>${parallel.tests}</forkCount> </configuration> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency> </dependencies> <executions> <execution> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Чтобы все это добро заработало в Cucumber – пришлось прописывать плагины для API и Ui-классов.
ApiCucumberTestSuite.java
package starter.runner.api; import io.cucumber.junit.Cucumber; import io.cucumber.junit.CucumberOptions; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions( plugin = {"io.qameta.allure.cucumber5jvm.AllureCucumber5Jvm"}, features = "src/test/resources/features/api/", glue = {"starter"} ) public class ApiCucumberTestSuite {}
UiCucumberTestSuite.java
package starter.runner.ui; import io.cucumber.junit.Cucumber; import io.cucumber.junit.CucumberOptions; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions( plugin = {"io.qameta.allure.cucumber5jvm.AllureCucumber5Jvm"}, features = "src/test/resources/features/ui/", glue = {"starter"} ) public class UiCucumberTestSuite {}
Для определения типов тестов добавил аннотации allure.label.layer в features файлы.
authorizationApi.feature
@auth @api @all @smoke @allure.label.layer=Api Функция: Авторизация Пользователь делает авторизацию через API @positive @api Структура сценария: успешная авторизация Когда <User> делает авторизацию через API Тогда пользователь получает access token Примеры: | User | | user1 |
authorizationUi.feature
@auth @ui @all @allure.label.layer=Ui Функция: Авторизация Пользователь авторизуется @positive @ui Структура сценария: успешная авторизация Дано пользователь переходит на главную страницу Когда пользователь авторизуется под юзером <User> Тогда пользователь проверяет, что отображается имя юзера <User> Примеры: | User | | user1 | | user3 |
Для логирования API тестов через SerenityRest в Allure TestOps добавил в коде в респонсы фильтр с AllureRestAssured.
ApiAuthorizationStepDefinitions.java
...... JSONObject requestBody = new JSONObject(); requestBody.put("user_email", user_email); requestBody.put("user_password", user_password); response = SerenityRest.given().filter(new AllureRestAssured()).log().all(). and(). body(requestBody.toMap()). contentType(ContentType.JSON). post(EndPoints.tokens); ......
Для логирования UI-тестов через Selenium в Allure TestOps добавил в коде шаги с получением скрина текущей страницы с помощью класса AllureForScreenshot.
AllureForScreenshot.java
package allure; import io.qameta.allure.Allure; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; public class AllureForScreenshot { public void takeScreenshot(WebDriver webDriver) throws FileNotFoundException { File screenshotAs = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE); Allure.addAttachment("Screenshot", new FileInputStream(screenshotAs)); } }
UiAuthorizationStepDefinitions.java
...... switch (user) { case "user1": allureForScreenshot.takeScreenshot(mainPage.getDriver()); mainPage.openAuthForm(); allureForScreenshot.takeScreenshot(authorizationPage.getDriver()); authorizationPage.fillEmailField(user1Email); allureForScreenshot.takeScreenshot(authorizationPage.getDriver()); authorizationPage.clickAuthLoginButton(); allureForScreenshot.takeScreenshot(authorizationPage.getDriver()); authorizationPage.clickPasswordButton(); allureForScreenshot.takeScreenshot(authorizationPage.getDriver()); authorizationPage.fillPassField(user1Pass); allureForScreenshot.takeScreenshot(authorizationPage.getDriver()); authorizationPage.clickOnEnterButton(); break; ......
Результаты работы API и UI-тестов:


С джобой в Jenkins пришлось повозиться. Она была не параметризированная, параметры задавались на каждом шаге, логика работы билда лежала в Jenkinsfile. Allure TestOps не умеет работать с такими сборками, так как при запуске джобы из Allure она тупо висела в Jenkins на первом шаге, ожидая в интерфейсе ввода значения. Решение было простым – переписать логику Jenkinsfile под параметризированную сборку и поменять тип билда в Jenkins.
Jenkins

Jenkinsfile
pipeline { agent any parameters { gitParameter branchFilter: 'origin/(.*)', defaultValue: '', name: 'BRANCH', type: 'PT_BRANCH' choice(name: 'TEST_SUITE', choices: ['TestSuite', 'Parallel'], description: 'Выберите способ запуска тестов') choice(name: 'TYPE_OF_TESTS', choices: ['@api', '@ui'], description: 'Выберите тип тестов') choice(name: 'MODULE_OF_TESTS', choices: ['Список модулей тестов через @'], description: 'Выберите модуль тестов') choice(name: 'ENV_1', choices: ['Список тестовых стендов'], description: 'Выберите стенд') } stages { stage("Run tests") { steps { script { def inptext = readFile file: "serenity.properties" inptext = inptext.replaceAll("env1", "${params.ENV_1}") writeFile file: "serenity.properties", text: inptext sh """ls ./""" wrap([$class: 'Xvfb', additionalOptions: '', assignedLabels: '', displayNameOffset: 3, installationName: 'xvfb', parallelBuild: true, screen: '1600x1200x24']) { sh 'printenv' sh """mvn clean verify -Dcucumber.options=\"--tags '${params.MODULE_OF_TESTS} and ${params.TYPE_OF_TESTS}'\" -Denvironment=${params.ENV_1} -Dtype.of.suite=${params.TEST_SUITE}""" } } } } } post { always { withAllureUpload(indexExistingFiles: true, serverId: 'Id сервера в Allure TestOps', projectId: 'Номер проекта в Allure TestOps', results: [ [path: 'target/allure-results'] ]) { } } } }
Результаты прогона отправляются на последнем этапе работы билда. Внешний вид прогонов в Jenkins:

Джоба в Allure TestOps имеет вид:


Мы запускаем билд через параметры в environment. Это удобно, так как можно создать значения в данной форме, которые будут выбираться из выпадающего списка, исключая повторный ввод вручную. Есть нюанс с дефолтными полями: Device, OS, Host, Browser, Environment – к сожалению, их нельзя удалить либо отключить, если они не используются. Приходится игнорировать их при запуске джобы.
Внешний вид прогона в Allure TestOps:

Под ручные и авто тесты я создал один общий проект.

Разделил в фильтрах ручные тестовые артефакты по командам, внутри каждой команды тест кейсы и чек-листы разделены по функционалу. Автоматизированные кейсы лежат в отдельных фильтрах (API, UI). В ближайшем будущем планирую также разделить их по командам.

Разделил в фильтрах ручные тестовые артефакты по командам, внутри каждой команды тест кейсы и чек-листы разделены по функционалу. Автоматизированные кейсы лежат в отдельных фильтрах (API, UI). В ближайшем будущем планирую также разделить их по командам.
В Allure TestOps по дефолту три уровня вложенности и есть шаблон под тестовые артефакты (тест-кейсы, чек-листы).

В самом тестовом артефакте можно:
-
проставлять различные тэги;
-
линковать его с тасками в багтрекере;
-
писать в нем комментарии
-
прикреплять файлы и изображения;
-
вешать различные роли (владелец, ревьювер и прочие, в зависимости от флоу тестирования);
-
менять его статусы;
-
создавать с ним ручные и авто прогоны, линковать их в той же Jira, выполнять по шагам, проставляя статусы (Passed, Failed, Skipped и прочие).

Также присутствует возможность заведения дефектов параллельно с созданием сущностей в Jira.

Allure TestOps позволяет отслеживать статусы заведенных дефектов в багтрекере (что крайне удобно) для своевременного их закрытия в Allure.
Инструкции мы создали в Confluence, провели QA-ретро и познакомились всем отделом качества с функционалом Allure TestOps.
Начали работать с Allure. Наш флоу: анализ задачи, написание тестовой документации, командное кроссревью, созданного тестового артефакта, ручное тестирование, автоматизированное тестирование (смоук, регресс), деплой. Какие трудности мы испытали:
-
нельзя переносить папки с тестовыми артефактами в интерфейсе Allure;
-
заведение дефектов параллельно с созданием задач в Jira вызывает дискомфорт, так как требуется переход в баг-трекер для дозаполнения тасок;
-
не хватает почтовых уведомлений при ревью тестовой документации, да и вообще для любых изменений в TMS;
-
в нашем случае для запуска джобы автотестов было бы удобно создавать несколько environments, тем самым запуская за раз несколько билдов в Jenkins, но у нас так не работает;
-
не хватает аналитики по заведенным дефектам
-
хотелось бы метрики с дашбордов экспортировать в pdf для передачи отчетов заинтересованным лицам
Прошел спринт и я собрал первые метрики по проделанной работе QA-отдела. Для этого в Allure TestOps можно создавать отдельные дашборды на главной странице проекта и с помощью AQL помещать в них диаграммы по сущностям Allure. Результаты радуют, QA активно работают в новой TMS, выполняют ручные и автоматизированные прогоны, заводят дефекты. Чего не хватает для сбора аналитики: AQL для заведенных в Allure TestOps багов и их параметров, но вроде бы Qameta скоро релизнет такой функционал.

Итог: с момента самостоятельного внедрения Allure TestOps до запуска проекта и начала работы в нем прошло порядка двух месяцев. Большое спасибо компании Qameta за предоставленный продукт, а команде поддержке за своевременную и полноценную помощь. Мы получили уникальный и полезный опыт при работе с продуктом. Ждем с нетерпением новых релизов и пользуемся тем, что уже есть!
Спасибо за уделенное время, если у вас есть вопросы – буду рад на них ответить в комментариях.
ссылка на оригинал статьи https://habr.com/ru/company/ru_mts/blog/689330/
Добавить комментарий