Интеграция с Allure: структурировать, упростить, стабилизировать

image-loader.svg

Привет! Меня зовут Сергей Потанин, я QA Automation Team Lead в Wrike. В этой статье расскажу о том, как мы используем интеграцию с Allure в повседневной работе и как этот инструмент помог нам существенно упростить процесс автотестирования, стабилизировать тесты и даже автоматизировать процесс их анализа.

Изначально, Allure — это инструмент для создания отчетов о тестировании с множеством интересных функций: статистика и аналитика, временная шкала, группировка результатов тестирования по различным атрибутам и т. д.

Большинство из тех, кто уже использует Allure, вероятнее всего, работают с Allure Report. Мы в Wrike реализовали интеграцию с Allure Server, который также известен как Allure EE и Allure TestOps.

image-loader.svg

Какие проблемы мы хотели решить с помощью Allure TestOps

Сначала давайте разберемся, почему мы решили использовать Allure TestOps и какие проблемы хотели решить.

Написание и сопровождение подробной тестовой документации требует много ресурсов. В реальной жизни практически невозможно найти на это время. Например, сейчас в нашем тестовом проекте около 30 тысяч Selenium-тестов. Когда мы начинали использовать Allure, их было чуть меньше 10 тысяч, но это все равно много.

Тестовая документация плохо структурирована. Раньше для каждого теста QA-инженер составлял короткий чеклист в Wrike, который мы используем как таск-трекер. Затем эти списки становились набором подробных тестовых кейсов в виде TMS, электронной таблицы или другой задачи в Wrike. После этого тест-кейсы автоматизировались. При изменении логики продакшна необходимо обновить и автотест, и тест-кейс. Это очень трудоемкий процесс. В большинстве случаев мы просто обновляли автоматизированные тесты и сосуществовали с нерелевантной документацией к ним.

Отчеты хранятся в разных местах. После того, как тесты автоматизированы и готовы, мы запускаем их в CI (в Wrike мы используем Teamcity). К каждой сборке Teamcity прикреплен отчет Allure. Отчеты Allure это здорово, но по разным техническим причинам у нас много сборок Teamcity, в которых прогоняются Selenium-тесты. Получалось так, что отчеты хранились не в одном месте, и проанализировать конкретный тест было сложно.

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

Непонятно, кто отвечает за тест. Еще одна проблема — как понять, кто отвечает за тест?

Тут у меня для вас есть несколько плохих советов:

  • Смотрите на авторство в Javadoc. Проблема в том, что со временем информация там станет неактуальной. Может случиться так, что человек, который написал тест, теперь ничего о нем не знает, потому что перешел в другую команду и теперь отвечает за другую функциональность или вообще в другой отдел. Все меняется.

  • Используйте историю коммитов. Этот вариант еще хуже: некоторые люди могут просто провести рефакторинг кода, и поэтому последнее изменение в файле будем принадлежать им.

В большинстве случаев оба варианта недостаточно хороши.

Как мы используем Allure TestOps

Чтобы понять, как нам удалось справиться со всеми проблемами, давайте посмотрим на код. В Wrike для написания автоматических тестов мы используем Java, поэтому примеры кода также будут на Java.

Вот пример одного из наших простейших автоматических тестов:

@StandardSeleniumExtensions
@GuiceModules(WebTestsModule.class)
@Epic("Workspace")
@Feature("Task list")
@Story("Task creation")
@TeamExample
public class CreateTaskExampleTest {

   @Inject private WrikeClient wrikeClient;
   @Inject private LoginPageSteps loginPageSteps;
   @Inject private SpaceTreeSteps spaceTreeSteps;
   @Inject private TaskListSteps taskListSteps;

   @Test
   @TestCaseId(104082)
   public void testCreateTask() {
       User user = wrikeClient.createAccount(ENTERPRISETRIAL);
       loginPageSteps
               .login(user);
       spaceTreeSteps
               .openSpace("Personal");
       taskListSteps
               .createTaskViaEnter("new task")
               .checkTask("new task");
   }
}

Сценарий тестирования находится в теле метода. Каждый метод в нем — шаг в тестовом сценарии. 

Сценарий довольно прост: создать учетную запись пользователя, войти в систему как пользователь, открыть личное пространство (space) пользователя, создать новую задачу в списке и убедиться, что задача создана и появилась в списке задач. 

Давайте подробнее рассмотрим один из методов — openSpace:

@Step("Open space `{spaceName}` from folder tree")
public SpaceTreeSteps openSpace(String spaceName) {
   onSpaceTree().spaceSection(spaceName)
           .spaceNode()
           .spacesTitle()
           .waitUntil(displayed())
           .click();
   return this;
}

Чтобы увидеть методы в отчете, необходимо использовать аннотацию @Step. Эта аннотация также может работать с параметрами, устанавливая фактическое значение переменной вместо заглушки.

Чтобы найти тест в Allure, нужно получить его идентификатор. В Wrike для этого мы используем специальную аннотацию тестового метода @TestCaseId:

...
   @Test
   @TestCaseId(104082)
   public void testCreateTask() {
...   

Это уникальный идентификатор, и он останется неизменным, даже если Java-метод будет переименован. Теперь мы можем найти этот тест в Allure.

Главный вью теста в Allure TestOps выглядит так:

image-loader.svg

Сейчас нас интересует вкладка «Сценарий». Так выглядит один и тот же шаг в разделе отчета и в коде:

image-loader.svg

Теперь у каждого метода есть описание @Step из соответствующей аннотации. Чтобы документация формировалась автоматически, нам нужно разместить аннотацию @Step в коде над каждым шагом. Это нужно сделать один раз, а затем переиспользовать в других местах. При изменении логики тестирования и использовании других шагов в тестах, документация будет автоматически обновляться вместе с автотестом.

Как структурировать тестовые сценарии

Теперь мы хотим не только получить все тесты с соответствующими сценариями, но и иметь возможность их структурировать.

Вернемся к примеру с автотестом и посмотрим на аннотации тестового класса:  

...
@Epic("Workspace")
@Feature("Task list")
@Story("Task creation")
@TeamExample
public class CreateTaskExampleTest {
...

Есть аннотации классов @Epic, @Feature и @Story, как в Allure Report. Но при использовании Allure TestOps они могут быть еще полезнее. Давайте разберемся, почему.

Так выглядит поисковый вью Allure TestOps:

image-loader.svg

На левой панели множество атрибутов для фильтрации тестов. Мы нашли тест по идентификатору. Справа находится результат поиска, который показывает не только тест, но также вложенную структуру, которая представляет собой аннотации в Java-коде.

В этом же вью можно узнать, сколько тестов существует для аннотаций @Feature, @Story или @Epic:  

Например, можно посмотреть, сколько тестов есть для списка задач. Это значит, что мы можем видеть, какие части приложения покрыты тестами лучше другихНапример, можно посмотреть, сколько тестов есть для списка задач. Это значит, что мы можем видеть, какие части приложения покрыты тестами лучше других

Как выглядит упрощенный процесс автотестирования

Теперь мы можем упростить процесс до трех шагов:  

image-loader.svg

  1. Создать короткий чеклист в Wrike. 

  2. Написать Selenium-тесты для этих кейсов.

  3. После запуска тестов в Teamcity результаты отправятся в Allure. И даже после запуска тестов в разных сборках Teamcity все результаты будут собраны в одном месте — Allure TestOps.

Как стабилизировать тесты

Теперь посмотрим, что можно сделать для стабилизации тестов. Как и многие QAA-инженеры, мы в Wrike прогоняем тесты повторно, чтобы они стали зелеными, если это возможно. Что именно происходит, когда мы перезапускаем тесты, поможет понять Allure.

Это один из наших реальных отчетов и временная шкала небольшого набора тестов:

Зеленым цветом обозначены временные интервалы для прошедших тестов, желтым пунктиром - для неудавшихся тестов, которые позже были перезапущены, и сплошным желтым - для неудавшихся.Зеленым цветом обозначены временные интервалы для прошедших тестов, желтым пунктиром — для неудавшихся тестов, которые позже были перезапущены, и сплошным желтым — для неудавшихся.

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

Также в Allure можно смотреть статистику стабильности, анализировать ее и определять самые нестабильные тесты, чтобы исправить их в первую очередь.

Вернемся к test-вью в Allure TestOps и посмотрим историю:

image-loader.svg

После нажатия на последний неудачный результат отображается много полезной информации.

Что мы видим:

image-loader.svg

Чуть ниже также можно увидеть информацию о том, на каком этапе тест не прошел, какое было сообщение об ошибке, скриншот экрана в момент, когда тест не прошел и т. д.

image-loader.svg

Как автоматизировать процесс анализа

Информация об истории тестов доступна через API, а это значит, что процесс анализа можно автоматизировать. У нас есть несколько сервисов для сбора и анализа тестовой статистики.

Поскольку Allure хранит все данные о каждом запуске каждого теста, сначала мы собираем необходимые данные в отдельную базу данных. Мы делаем это, чтобы не перегружать Allure большим количеством аналитических запросов, которые выполняются при анализе тестов. Здесь мы учитываем данные об истории тестов, стек-трейсы сбоев, количество повторных прогонов и многие другие факторы. В итоге получаем список самых нестабильных тестов.

image-loader.svg

Как исключить из анализа нестабильные тесты

Теперь мы знаем, какие тесты нестабильны. Мы хотим исправить их, исключить из отчетов и не запускать с другими тестами. Как это сделать?  

Во-первых, отключить эти тесты. Для этого в Allure TestOps есть вкладка Mutes, в которой есть кнопка Create mute. Она позволяет отключить тест.

image-loader.svg

При нажатии кнопки Create mute можно указать имя и причину отключения теста. И что более важно — установить таск-трекер и связать его с фактическим идентификатором задачи в этом трекере. В нашем случае идентификатор задачи — это идентификатор соответствующей задачи в Wrike.

image-loader.svg

Мы нашли все нерабочие тесты и отключили их с помощью Allure. 

С помощью Allure API можно получить список всех отключенных тестов. 

Мы изменили программу запуска тестов таким образом, чтобы перед запуском каждого набора API запрашивал все отключенные тесты у Allure и исключал их из списка тестов, которые мы хотели прогнать.

Представьте, что есть набор тестов, который нужно прогнать. Передаем список этих тестов в test runner. Некоторые тесты отключены — их мы запускать не хотим. Чтобы точно узнать, какие тесты отключены, test runner запрашивает список отключенных тестов у API Allure TestOps. Затем он исключает эти тесты из исходного набора и получает новый набор тестов, который готов к работе. 

image-loader.svg

Как понять, какая команда отвечает за тесты

Теперь нам не нужно беспокоиться об отключенных тестах. Но кто-то должен будет их править. Как узнать, кто отвечает за каждый тест? Мы создали собственные аннотации для каждой команды и связали их с Allure, чтобы узнать, какие команды отвечают за тесты. 

Вернемся еще раз к коду теста и посмотрим на аннотации классов:

...
@Epic("Workspace")
@Feature("Task list")
@Story("Task creation")
@TeamExample
public class CreateTaskExampleTest {
...

Здесь есть аннотация пользовательского класса @TeamExample, которая содержит информацию об ответственных тестировщиках из команды. 

Посмотрим на код аннотации:

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@LabelAnnotations({@LabelAnnotation(
       name = "owner",
       value = "sergey.potanin, another.person"
), @LabelAnnotation(
       name = "ownerLabel",
       value = "sergey.potanin"
), @LabelAnnotation(
       name = "ownerLabel",
       value = "another.person"
)})
public @interface TeamExample {
}

Так мы отмечаем ответственных за каждую команду. В этом примере владельцы тестов — я и еще один человек. 

Как это отображается в результатах Allure? В главном окне тестов в Allure есть раздел со списком пользователей. Он содержит информацию о владельцах, сопровождаемую аннотацией, которую я показал выше. Таким образом, для каждого теста в Allure есть информация об ответственных людях. 

Эта информация тоже доступна через API: можно автоматизировать назначение задач для отключенных тестов или настроить Slack-уведомления для их владельцев.Эта информация тоже доступна через API: можно автоматизировать назначение задач для отключенных тестов или настроить Slack-уведомления для их владельцев.

Что мы получили в итоге

Какие преимущества мы получили от использования функций Allure и их интеграции в нашу собственную автоматизированную систему:

  1. У нас теперь есть структурированная и автоматически поддерживаемая тестовая документация.

  2. Используя информацию о тестовой статистике, мы построили систему, которая обнаруживает плохие тесты и отключает их. 

  3. Теперь мы знаем все о владельцах тестов, поэтому можем отключать тесты и сразу назначать задачи их владельцам.

А какими инструментами для упрощения процесса автотестирования пользуетесь вы в своей компании?

© Habrahabr.ru