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

Достаточно давно (по меркам ИТ-мира) я посмотрел доклад Артема Ерошенко с Heisenbug 2020 «Тест-кейсы как код». С переходом в Леруа Мерлен со старой TMS на Allure TestOps появилось желание полноценно попробовать данный подход у себя. В статье расскажу о том, что из этого получилось.

Привет, Хабр! Меня зовут Сергей Старков, я работаю в области тестирования с 2011 года. Ранее тестировал: десктопные клиент-серверные системы видеонаблюдения вместе с железом для них, кассовое ПО (Windows и DOS) вместе с железом, распределенный монолит, в основе которого Oracle Siebel CRM. В Леруа Мерлен являюсь инженером по тестированию различных продуктов для внутренних и внешних пользователей.

Переезд на новую TMS? 

Не хотелось бы устраивать холивары по выбору TMS-системы. Скажу сразу, что наш приоритет был определен очень прагматично. Allure TestOps по сумме лицензий выходил дешевле своих конкурентов, поддерживать этот продукт проще, а еще он находится полностью в нашей зоне ответственности, также в плюс интуитивно понятный интерфейс и то, что очень просто использовать внешние интеграции с Jira, Jenkins и т. д.
Понятно, что переезд нескольких десятков команд, сотни проектов с тестовой базой, состоящей из десятков тысяч тест-кейсов, пугал, но мы справились — чему сейчас очень рады.

Чего мы ждали от подхода «тесты как код»

IT-составляющая в Леруа Мерлен последние пару лет развивается очень быстрыми темпами. Поэтому нам хотелось сформировать единый подход к написанию тест-кейсов. Кроме того, была надежда снизить трудозатраты на их написание и рефакторинг, а также косвенно увеличить скорость актуализации тестов. Ну и конечно, всё это было сдобрено духом авантюризма: «А что из этого выйдет?»

У нас имеется классический CI/CD, когда по мержу в ветку (например, dev) происходит запуск статического анализа кода приложения, различные проверки информационной безопасности, прогоняются unit-тесты и, наконец, раскатка на соответствующее окружение. После этого запускаются функциональные тесты, и результаты попадают в Allure TestOps. Плюс, при желании, можно запланировать дополнительные уведомления в Slack.

При миграции из старой TMS для сохранения иерархии папок для тестовых моделей мы решили сделать маппинг с помощью аннотаций @Section … @Section2 и в итоге получили 3 уровня вложенности. Пример аннотации выглядит так:

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@LabelAnnotation(name = "section")
public @interface Section {
  String value();
}

В самой TMS был настроен маппинг:

Затем для удобства фильтрации тестов мы добавили @Layer и настроили необходимый маппинг.

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@LabelAnnotation(name = "layer")
public @interface Layer {
  String value();
}

Для удобства отображения ссылок на задачи в Jira добавлены были аннотации @JiraIssues и @JiraIssue, а также маппинг в Issue Schemas.

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface JiraIssues {
  JiraIssue [] value();
}
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@LabelAnnotation(name = "jira")
@Repeatable(JiraIssues.class)
public @interface JiraIssue {
  String value();
}

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

@Test()
@AllureId("87996")
@Section("Тесты примеры")
@Section1("API тесты")
@JiraIssues({@JiraIssue("TEST-2")})
@Links({@Link("TEST-2")})_____________________________________________________________
@Tags({@Tag("example")})
@Layer("api")
@DisplayName("Пример API теста")
public void apiTestExample() {
  step("Отправить запрос GET /v1/addresses/store=999&lmCode=10966327", () -> {
  });
  step("Проверить:", () -> {
    step("Получили httpcode=200", () -> {});
    step("В ответе вернулся json:", () -> {
      file.attachFile("Ответ", "examples/example_response.json", "json");
    });
  });
}

После выгрузки результатов в сам Allure TestOps получаем внутри прогона подобный вид теста:

Рабочий цикл тестировщика выглядит теперь следующим образом:

На этапе Create test можно как написать ручной тест-кейс, так и сразу подготовить автотест. Все зависит от конкретной задачи и связанной с ней необходимости.

Сложности, с которыми мы столкнулись

1. Не все поля подлежат маппингу

Как оказалось, аллюр позволяет использовать поля Precondition и Expected result, но данные поля невозможно выгрузить из кода. Принимаем это как ограничение при построении тестов.

В коде просто добавляем шаги с описанием предусловий.

step("Предусловия", () -> {
    step("Открыть приложение", () -> {});
  });

2. Ручные тесты под видом автоматизированных

Оказалось, что все выгружаемые тесты (ручные и авто) воспринимаются Allure TestOps как автоматизированные. Из коробки готового примера или аннотации для формализации этого вопроса нет. Поэтому мы написали свою кастомную аннотацию.

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@LabelAnnotation(name = "ALLURE_MANUAL")
public @interface Manual {
  boolean value();
}

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

Пока прогон не завершен, такие тесты отображаются со статусом «In progress» (синий цвет). После завершения прогона непройденные тесты получат статус «Unknown» и станут фиолетовыми.

Таким образом помечаем аннотацией @Manual(true) соответствующий тестовый класс или тестовый метод, после чего получаем реальную картинку по количеству автотестов и ручных тестов в проекте.

3. Вложения

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

При этом если перейти в результаты теста (синий линк), то вложения будут видны, и в данном случае это картинка.

4. Версионность тестов

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

Итоги

Внедрение подхода «тесты как код» сделало нашу работу быстрее, а также помогло навести порядок в достаточно объемной практике тестирования сразу для нескольких десятков команд. 

В дополнение теперь при запуске автотестов какой-то группы (smoke, api и т. д.) мы получаем тестовый прогон, включающий все тесты: автоматизированные, устаревшие и ручные. Казалось бы, зачем это в прогоне? Устаревшие тесты маячат перед глазами и сподвигают на их скорейшую актуализацию, ручные сообщают нам о том, что необходимо пройти ручками какую-то часть функционала и отследить динамику автоматизации от прогона к прогону. 

Кроме этого я бы хотел отметить еще пару полезных преимуществ нового подхода:

  • Если вам когда-либо приходилось массово рефакторить пример JSON’а для API-теста, ссылки на макеты или что-то иное, то теперь подобный рефакторинг сводится к простой массовой замене параметров в нужных файлах. И это делается намного быстрее подобных ручных изменений в TMS.

  • При разработке тестов мы получаем готовые шаблоны, которые затем можно автоматизировать, причем для этого не придется постоянно заходить в сам аллюр — всё перед глазами в IDE. 

  • Абсолютно все, кто попробовал данный подход, оценили его удобство, снижение трудозатрат на написание и поддержку тест-кейсов. Это стало дополнительным подтверждением, что всё это действительно стоило провернуть.

P.S. А еще мы получили неожиданный эффект: ручные тестировщики начали активно погружаться в автоматизацию. Стоило им познакомиться с IDE, как пропали страхи перед кодингом.

Комментарии (2)


  1. Rampage
    11.01.2023 16:13

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


    1. AugustoZ Автор
      11.01.2023 17:37
      +1

      Спасибо за комментарий. У нас так же всплывают подобные трудности, когда аналитики накидывают драфты в сам Аллюр. Мы нашли для себя решение в том, что есть возможность импорта тест-кейсов в сам код, но там так же есть подводные камни, связанные с маппингом и тем, что придется ручками прописывать теги или кастомизированные поля