Pull to refresh

Allure. В поисках почти идеальной TMS

Reading time17 min
Views25K
Офис allure :)
Офис allure :)

Введение

Приветствую тебя, мой виртуальный друг! Если ты читаешь эту статью, скорее всего тебе интересен Allure, или ты хочешь разобраться с тем, что это за зверь и как он интегрируется в тестирование без многонедельных плясок с бубном. В этой статье хочу рассказать о том, как мы внедряли один из инструментов, который помогает (или пытается) сделать жизнь инженерам по обеспечению качества продукта немножечко легче: постараюсь рассказать в деталях с чего все начиналось, как шло внедрение, через что прошла команда, что в итоге получили и куда планируем двигаться дальше. А виновником появления этой статьи, как нетрудно догадаться, стал тот самый инструмент — бывший Allure EE, Allure Server и нынешний Allure Testops.

А что было до?

Несколько лет назад я присоединился к одному очень интересному и амбициозному проекту. В команде было шесть разработчиков и два QA-инженера, включая меня. На тот момент тестовым стеком, который уже был внедрен и использовался в компании, являлся:

  • PHP 7.4 и framework Codeception

  • Framework Selenoid

  • В качестве CI/CD системы мы использовали Gitlab

  • Отдельной системы генерации отчетов как такой не было: для авто тестов мы использовали встроенный в codeception простой генератор отчетов (включается при передаче флага --html при запуске самих тестов), а для ручных тестов мы использовали TMS Zephyr

Соответственно приходилось смотреть два разных отчета и делать сопоставление между ручными и автотестами, что, сами понимаете, не очень-то удобно. Кроме неудобства в репортинге, постоянно возникали вопросы вроде "А как же скрестить ежа с попугаем?" Ладно, шучу! "А как же получить отчет в котором будет наглядный список автоматических и ручных тестов?" или "как же получить отчет в котором будет четко показано, что проверяют уже написанные автотесты?" Ответы на эти вопросы очень затягивались и в итоге сам стек для автотестов на тот период времени было принято не менять по причинам плотной интеграции и существующей базы автотестов, но вот касаемо отчетов и полноценной report-системы решили, что пришла пора переменам.

Попытка номер раз

Главным преимуществом системы, которая изначально была у нас в стеке, напомню, это был Zephyr, была глубокая интеграцияс JIRA. Интеграция позволяла вести всю тестовую документацию прямо не выходя из нее, настраивать дэшборды, используя JQL, писать тест кейсы прямо в таске и интегрировать их в "борду". Впрочем, были и минусы. Во-первых, очень сложно и неудобно писать/редактировать тесты в маленьком окошке (да-да, оно умеет настраиваться по размеру, но все равно неудобно, особенно при большом объеме документации). Во-вторых, мы не смогли найти ответ, как слинковать автотесты c ручными и настроить сквозные отчеты для нашей тестовой инфраструктуры (возможно плохо искали). Эти недостатки и отправили нас в путешествие в надежде найти тихую гавань, в которой хочется заниматься тестированием и качеством продукта, а не постоянной рутиной по сборке и допиливанию отчетов. Мы отправились искать другой инструмент.

Попытка номер два

Вторым заходом в бухту стал всем известный TestRail. При первом знакомстве с ним я был в восторге! В одном месте можно удобно хранить тесты, тест планы, делать прогоны ваших тестов и показывать красивые отчеты: тут и история создания тест-кейсов есть, и удобное редактируемое поле для шагов в самом тест-кейсе. Но и без ложки дегтя не обошлось - как с автотестами подружить отчеты и сделать единые прогоны? Да, у TestRail есть API-документация, которую мы использовали, и даже реализовали свою версию (за что отдельное спасибо команде разработчиков,которая нам помогала в этом) интеграции с запуском и проставлением статусов у каждого теста. Просто в определенный момент пришло осознание, что мы уделяем интеграции и ее настройке уйму времени, а конечного результата на горизонте все еще нет. "Тихой гавани" не было видно, поэтому переезд номер три был не загорами.

Попытка номер три

В этот раз у нас не было права на ошибку и мы занялись серьезной подготовкой к выбору следующего инструмента: долгий поиск в интернете, советы с коллегами, жаркие дискуссии и чтение книг, - все это привело нашу команду на одну из конференций по тестированию, на которой выступал Артем Ерошенко. Доклад был посвящен тому самому Allure Testops, что это за инструмент, что он умеет и как это готовить. Впечатлившись выступлением, я пошел разбираться, будет ли все это безобразие работать со стеком на нашем проекте.

Здесь стоит сделать отступление, что наша команда уже запланировала переезд на другой тестовый стек и мы плотно над этим работаем, но об этом в другой раз.

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

Первая интеграция и первые результаты

Пятница, поздний вечер… Всей командой сидим на работе? Какого ***?

Ответ прост - мы получили триальный ключик Allure TestOps! Развернув само приложение на отдельном сервере через docker-compose, мы наконец-то увидели форму авторизации залогинившись в которой, получили пустой проект и полное осознание того, что впереди еще долгий путь. Ведь Всю тестовую инфраструктуру надо поднимать и настраивать почти что с нуля, а потом еще и показать коллегам, как это будет работать. Понеслась!

allure Signup form
allure Signup form

Создали проект в UI Allure TestOps, добавили в composer нашего проекта новую зависимость, создали ветку, пушнули, иии... магии нет :) Что ж, придется почитать документацию и выяснить неочевидный факт - отчет надо загружать через allurectl. С подключением зависимости в composer и описанием yaml-файла проблем не возникло, в репозитории есть пример, а вот как отчет грузить, это прям вопрос? Как я писал выше, у нас используется gilLab в качестве CI/CD системы и определенная пачка тестов бегает в docker контейнерах, а часть тестов - на тестовых стендах. Хорошо... Для начала пытаемся интегрировать allurectl в docker и подружить его с gitlab-ом.

Создаем dockerfile, указываем путь к репозиторию allurectl и делаем этот файл исполняемым. Пример запуска скрипта allurectl (в примере используется файл для x86 архитектуры):

FROM docker/compose:alpine-1.25.5

RUN apk add \
   bash \
   git \
   gettext

ADD https://github.com/allure-framework/allurectl/releases/latest/download/allurectl_linux_386 /bin/allurectl

RUN chmod +x /bin/allurectl

Уже лучше, дальше описываем логику работы с пайплайном и запускаем скрипт (allurectl) после прохождения тестов на CI. Для того чтобы Allure Testops узнал про наши тесты, нужно описать работу двух джоб: allure-start и allure-stop.

Пример реализации джобы allure-start:

allure-start:
  stage: build
  image: image вашего проекта
  interruptible: true
  variables:
    GIT_STRATEGY: none
  tags:
    - если используется
  script:
    - allurectl job-run start --launch-name "${CI_PROJECT_NAME} / ${CI_COMMIT_REF_NAME} / ${CI_COMMIT_SHORT_SHA} / ${CI_PIPELINE_ID}" || true
    - echo "${CI_PROJECT_NAME} / ${CI_COMMIT_REF_NAME} / ${CI_COMMIT_SHORT_SHA} / ${CI_PIPELINE_ID} / ${CI_JOB_NAME}"
   rules:
   - if: если нужны какие правила для запуска и ниже условия
     when: never
   - when: always
 needs: []
Вот так это может выглядеть в логах gitLab. Здесь мы так же распечатали эти переменные для дальнейшей настройки
Вот так это может выглядеть в логах gitLab. Здесь мы так же распечатали эти переменные для дальнейшей настройки

А allure-stop - так:

allure-stop:
 stage: test-success-notification
 image: ваш образ
 interruptible: true
 variables:
   GIT_STRATEGY: none
 tags:
   - ваши теги
 script:
   - ALLURE_JOB_RUN_ID=$(allurectl launch list -p "${ALLURE_PROJECT_ID}" --no-header | grep "${CI_PIPELINE_ID}" | cut -d' ' -f1 || true)
   - echo "ALLURE_JOB_RUN_ID=${ALLURE_JOB_RUN_ID}"
   - allurectl job-run stop --project-id ${ALLURE_PROJECT_ID} ${ALLURE_JOB_RUN_ID} || true
 needs:
   - job: allure-start
     artifacts: false
   - job: acceptance
     artifacts: false
 rules:
   - if: $CI_COMMIT_REF_NAME == "master"
     when: never

Тут стоит добавить, что Allure TestOps создает папку allure-results в папке {имя вашего проекта}/tests/_output которую формирует сам framework (в нашем случае codeception). И все что нужно сделать - загрузить артефакты, сформированные после прогона тестов в Allure через консольную команду allurectl.

.after_script: &after_script
 - echo -e "\e[41mShow Artifacts:\e[0m"
 - ls -1 ${CI_PROJECT_DIR}/docker/output/
 - allurectl upload ${CI_PROJECT_DIR}/docker/output/allure-results || true
Вот выглядит процесс загрузки артифактов в консоли Gitlab. Напомню, команда вызвается после прохождения всех тестов
Вот выглядит процесс загрузки артифактов в консоли Gitlab. Напомню, команда вызвается после прохождения всех тестов

Чтобы отправлять нотификации к примеру об упавших тестах в slack, достаточно передать launch id. Grep-нуть его можно примерно так:

if [[ ${exit_code} -ne 0 ]]; then
 # Get Allure launch id for message link
 ALLURE_JOB_RUN_ID=$(allurectl launch list -p "${ALLURE_PROJECT_ID}" --no-header | grep "${CI_PIPELINE_ID}" | cut -d' ' -f1 || true)
 export ALLURE_JOB_RUN_ID
И вот так это может выглядеть в slack
И вот так это может выглядеть в slack

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

Вот так может выглядеть пайплайн:

Мы пошли еще чуть дальше и смогли настроить еще одну полезню функцию - это Parent-child pipelines. А понадобилось нам это для того, что бы можно было развернуть бранч на физический стнед и уже на нем запускать ряд тестов. Прокидываем необходимые переменные и убеждаемся, что результаты грузятся в один launch в Allure Testops. ${CI_PIPELINE_ID} и ${PARENT_PIPELINE_ID}

.run-integration: &run-integration
  image: 
  services:
    - name: ваш образ
      alias: docker
  stage: test
  variables:
    <<: *allure-variables
  tags:
    - ваши теги
  script:
    - echo "petya ${CI_PROJECT_NAME} / ${CI_COMMIT_REF_NAME} / ${CI_COMMIT_SHORT_SHA} / ${CI_PIPELINE_ID} / ${PARENT_PIPELINE_ID} / ${CI_JOB_NAME} / {$SUITE}"
    - cd ${CI_PROJECT_DIR}/gitlab
    - ./gitlab.sh run ${SUITE}
  after_script: *after_script
  artifacts:
    paths:
      - docker/output
    when: always
    reports:
      junit: docker/output/${SUITE}.xml
  interruptible: true

Первый шаг интеграции готов. Смотрим первые результаты и пытаемся понять, что в итоге загрузилось в Allure ? Есть тесты с шагами и бублик с разными статусами. Значит, запуск тестов на каждой ветке и конкретном sha-ref (коммите) работает, а еще на каждый коммит и создание ветки запускается набор тестов, который по итогам выполнения отправляет результаты в Allure. Allure в свою очередь рисует бублик со статусами выполненных тестов. Успех и маленькая победа!

На этом вечерние посиделки в пятницу были завершены, и мы с радостными мыслями удалились в бар по домам :).

Разочарование

Итак, тесты успешно бегают на бранчах и для каждого sha-ref (коммита) - восторгу нет предела. Впрочем, как известно,эйфория проходит быстро. Именно так и случилось. Мы полезли смотреть на дерево автотестов (к тому моменты они уже успешно бегали в Gitlab) и обнаружили совершенно нечитаемую историю, по которой никак нельзя понять, что в ней проверяется. В этот момент пришло горькое осознание, что мы сделали шаг вперед и два назад. Примерно так выглядел результат после успешной загрузки xml-отчета в Allure Testops:

Кстати, это темная тема, по мне так выглядит очень круто!
Кстати, это темная тема, по мне так выглядит очень круто!

Само дерево строится по принципу название тестового метода + data set #1 (если он есть в тесте).

Шаги в тестах выглядят примерно так:

Из этих шагов, естественно, ничего не понятно: что за get web driver, что за get helper, зачем мы перезагружаем страницу или зачем мы ждем тот или иной селектор и т.д., - если такие отчеты увидит кто-то из руководства, вопросов будет больше, чем шагов в тесте. И сейчас вы наверняка думаете, что я расскажу, как в два клика мы победили эту "неувязочку" ? Нет!

Тут начинается боль… Боль инженера по обеспечению качества. Ребята из Qameta предлагают решить эту проблему при помощи аннотаций к тестам: определить, где у нас features, где story, а где component и для каждого теста выставить аннотации над методом. Такая разметка позволяет динамически строить красивое дерево.

А что насчет шагов? Аннотировать каждый? Для этого тоже есть решение, которое заключается в создании обертки для каждого метода. Эта обертка будет служить красивым и понятным именем для метода и шага. В целом предложения и подход здравые, нокогда на проекте n^8-тестов, этот процесс может сильно затянуться. По сути, разметка тестов для Allure требует практически полного рефакторинга всего, что есть в проекте! Очень много времени...

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

Валидация аннотаций

P/s. В качестве решения валидации аннотаций, можно посоветовать установить плагин для phpStoprm: PHP Annotations, который поможет найти подобные ошибки, но конечно же не все.

Доработка напильником

Ну что, дорогие читатели, напильник в руки и начинаем полировать заготовку! Добавляем аннотации к автотестам, по пути рефакторим код тестов, а так же согласуем с аналитиками и ВСЕМИ участниками вашей команды будущую структуру вашего дерева. Давайте посмотрим на то как это может быть выглядеть в коде на примере одного автотеста:

/**
     * @Title("Название вашего теста - короткое")
     * @Description("Пишем подробное описание")
     * @Features({"А что за фича собственно?"})
     * @Stories({"Ну про сторю не забываем!"})
     * @Issue({А где требования Карл?})
     * @Labels({
     *     @Label(name = "Jira", values = "SA-1111"),
     *     @Label(name = "component", values = "Наш компонет"),
     *     @Label(name = "layer", values = "the layer of testing architecture"),
     * })
*/ 

То, что вы видите на скриншоте, это адаптированный стандарт документирования Javadoc для PHP. Теперь посмотрим, как это выглядит в Allure TestOps:

На скриншоте видно, что тесты выстроены в структуре, а именно: Component -> Feature -> Story. Это предварительно настраивается в самом Allure TestOps.

Настройка отображения дерева: Component->Feature->Story
Настройка отображения дерева: Component->Feature->Story

В любой момент структуру можно отредактировать и дерево пересоберется в соответствии с запросом. Теперь пора навести порядок с шагами в автотестах. Можно использовать метод executeStep как надстройку и красивое описание для нашего метода. В нашем примере в сигнатуру метода первым параметром передаем текст, который будет отображаться как human readable step в UI Allure TestOps для метода addInvite (пример реализации):

public function createInviteCode(User $user, string $scheme): Invite
{
   return $this->executeStep(
       'Create invite code for ' . $user->username . ' with ' . $scheme,
       function () use ($user, $scheme) {
           return $this->getHelper()->addInvite(['user' => $user, 'schemeType' => $scheme]);
       }
   );
}

Таким образом, вся внутренняя реализация скрывается под капотом, а шаги в тестах "естественным" образом получаются красивые и понятные названия. В итоге тестовый сценарий в Allure TestOps выглядит примерно вот так:

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

Финишная прямая

Подведем некий итог, что же в итоге получилось? Напомню, что изначальной задачей было приведение всего набора автотестов порядок, чтобы их можно было спокойно читать и использовать, не забыв при этом про ручные тесты. В нашем случае, на создание разработчиком pull-request в Gitlab создается ветка с названием и sha-ref коммита и заводится пайплайн, в котором запускаются тесты. Так вот, мы хотели понимать, какие тесты запускались на каждой из веток или каждом из коммитов.

Настроив интеграцию, мы получили отдельную страницу со всеми запусками (Launches) в Allure TestOps. Страница Launches показывает эту информацию в структурированном виде, позволяет отфильтровать ее и получить нужный срез данных (запущенные тесты, процент успешно выполненных и упавших тестов и другую схожую информацию) по конкретной ветке.

Если провалиться в конкретный Launch, можно посмотреть на структуру нашего проекта: какие есть компоненты, какие фичи, сколько было перезапусков, какие именно тесты перезапускались, информацию о дереве тест-кейсов, график, который показывает сколько времени бежал самый долгий тест, график с длительностью тестов, - и в конце концов экспортировать этот прогон в JIRA-тикет. Отдельно хочется упомянуть про политики для Live documentation, которая в автоматическом режиме обновляет дерево тест-кейсов по правилам и триггерам, например, только из ветки мастер.

Работает это так: у нас есть автотест, в котором изменили пару шагов и поправили аннотации. Далее этот тест запускается и выполняется с набором тестов на мастере (на пулл-реквест в мастер), после чего можно либо вручную закрыть launch, либо дождаться, когда launch будет закрыт по cron’у, который настраивается в интерфейсе Allure. При закрытии запуска старый автотест обновляется - получаем актуальный тест-кейс. Это позволяет в принципе забыть про актуализацию тестовой документации в интерфейсе. Безумно удобно!

Где ручные кейсы, Карл?

Про ручные тесты мы конечно забыли :)
Про ручные тесты мы конечно забыли :)

Итак, стало понятно, что и где тестируется, какие тесты выполняются, как часто перезапускаются и какие дают результаты по итогам прогонов. Кажется, все! или нет? Ах да! Мы забыли про ручные кейсы. Давайте чуть разберемся в структуре тест-кейсов, которой нам предлагает следовать Allure TestOps - она предполагает, что тест представляет из себя законченный сценарий, а expected result является как бы необязательным элементом теста. А там, где это необходимо, можно описывать “expected result” в виде вложенных шагов. Написав пару-тройку тест-кейсов в таком стиле, становится ясно, что это удобно и практично. Пример такого теста может выглядеть так:

Если такой стиль написания кейсов не устраивает по какой-либо причине, всегда можно включить другую структуру с предусловиями.

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

Думаете, все? Как бы не так! В конечном итоге мы получили базу с ручными и автоматическими тестами в едином месте и были готовы презентовать результаты работы коллегам, но что-то пошло не так и обнаружилась еще одна неприятная история.

Выглядело это примерно вот так ^
Выглядело это примерно вот так ^

Перед той самой презентацией мы решили настроить все отчеты, фильтры, показать, какие у нас есть ручные тест-кейсы, какие автоматические, как все это прекрасно работает, но, немного перемудрив с настройками Allure TestOps, мы окончательно запутались в нашем дереве и с трудом стали различать, где ручной, а где автоматический тест. Почему так произошло? Потому что мы попытались интегрировать ручные тесты в структуру автоматических тестов. Впрочем, проблема оказалась не фундаментальной, а технической: поскольку структура для автоматических тестов была написана с помощью аннотаций в коде, а ручные тесты создавались/редактировались прямо в интерфейсе Allure, после закрытия каждого прогона с мастер ветки начиналась путаница в статусах всех тест-кейсов. Осознав, где свернули не туда, мы решили удалить текущее дерево и все настроить заново. С автоматическими тестами проблем не возникло, они очень быстро обновили документацию и выстроились в новое дерево на основе аннотаций. Но один важный вопрос остался открытым: что же делать с ручными тестами? Если пойти тем же путем, что и в прошлый раз, получим инструмент, который решает задачи связанные только с автоматизацией, оставим TestRail для ручных тестов и продолжим связывать вручную два разрозненных отчета, как в старые добрые времена.

Решение нашлось неожиданно: как-то вечером перед Гейзенбагом, одной из самых больших конференций по тестированию, я просматривал программу прошлых докладов и обнаружил доклад на тему Тест-кейсы как код. Да, практика не новая, и про нее многие слышали. Ее суть заключается в том, что даже ручные тесты следует писать как метод под будущую автоматизацию: создали тестовый метод, в нем описали сценарий, сделали ветку, сделали merge request, прислали коллегам на ревью. Если коллегам что-то не понравилось в mr, они оставляют комментарий, вы правите, после чего ветка успешно мержится в основную. Что характерно, все это можно делать прямо в вашей CI (напомню, что в нашем случае это gitlab).

Отличная практика, но как ее подружить c Allure TestOps и получить вменяемые отчеты? На помощь снова приходят аннотации. Пишем ручной тест в нужном месте в репозитории, размечаем его с помощью аннотаций, созданных для автотестов, после чего указываем, что тест - ручной. Примерно так:

   /*
    * @Title("Короткое описание")
    * @Description("Чуть понятнее пытаемся расписать")
    * @Features({"Наша фича к которой относится тест кейс"})
    * @Stories({"Если нужна"})
    * @Issues({"Ссылка на требования, к примеру conf"})
    * @Labels({
    *     @Label(name = "Jira", values = "Номер jira тикета"),
    *     @Label(name = "component", values = "Компонент"),
    *     @Label(name = "createdBy", values = "автор тест кейса"),
    *     @Label(name = "ALLURE_MANUAL", values = "true"),
    * })
    */
Test case as code
Test case as code

Метод step в данном случае так же как и в случае с автотестами является просто оберткой над встроенным методом Allure TestOps executeStep. Единственное отличие в том, что для такого теста добавляется Label = ALLURE_MANUAL.

А так это выглядит в Allure TestOps
А так это выглядит в Allure TestOps

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

 /**
     * @param string $elementName
     * @param string $elementType
     * @return $this
     */
    public function click(string $elementName, string $elementType = 'button'): self
    {
        $this->tester->step('Click on "' . $elementName . '" ' . $elementType);

        return $this;
    }

Здесь мы создали некую заглушку для общего метода click, который будем переиспользовать в шагах наших автотестов и на тех страницах где это необходимо.

/**
     * @return $this
     */
    public function clickCreateFreeAccountButton(): SignupModal
    {
        $this->click('Create Free Account');

        return new SignupModal($this->tester);
    }

Ну и сам тест выглядит уже таким образом:

 /**
     * @Title("Successful signup without email")
     * @Features({"Signup"})
     * @Stories({"Signup without email"})
     * @Labels({
     *     @Label(name="layer", values="manual"),
     *     @Label(name="ALLURE_MANUAL", values="true")
     * })
     *
     * @param ManualTester $I
     * @param Header $header
     */
    public function successfulSignupWithoutEmail(ManualTester $I, Header $header): void
    {
        $I
            ->amOnPage(IndexPage::URL)
            ->amAuthenticatedAsGuest();

        $header
            ->clickCreateFreeAccountButton()
            ->clickSignupWithoutEmailButton()
            ->fillUsername($I->generateRandomCredentials()['username'])
            ->fillPassword(AcceptanceTester::STRONG_PASSWORD)
            ->clickCreateFreeAccountButton();

        $I->expectUserAccountCreated();
    }

Здесь, мы обращаемся к атеку - ManualTester и вызываем его методы, которые предварительно должны написать. Пример:

<?php
/**
 * @SuppressWarnings(PHPMD)
 */
class ManualTester extends Actor
{
    use StepSupport;

    /**
     * @param string $url
     * @return \Tests\_support\ManualTester
     */
    public function amOnPage(string $url): self
    {
        return $this->step('Am on page ' . $url);
    }

    /**
     * @return $this
     */
    public function amAuthenticatedAsGuest(): self
    {
        return $this->step('Am authenticate as guest');
    }
}

Стоит ли применять такой подход и является ли он избыточным - вопрос хороший! Одно могу точно сказать, что можно совмещать эти два подхода в написание ручных тест кейсов. Первый можно использовать для быстрых мыслей и ближайшей автоматизации, а второй к примеру для созданиея структурированных и вдумчивых тест кейсов. Да, при этом редактировать и убираться в репозитории приходится чаще, а подходить к созданию тест-кейсов нужно более ответственно. Лично мне почему-то такой подход ближе. Возможно потому, что он избавляет нас от бездумных тест-кейсов в стиле "проверяю то, сам не знаю что", но это мое личное мнение. Теперь о глобальных минусах. Если нужно что-то прикрепить (картинку или файл) к тест-кейсу, сделать это будет довольно сложно, так как в Allure TestOps эта возможность реализована не для всех языков. Для PHP, это пока что в стадии доработки. Еще один минус заключается в том, что такие ручные тесты постоянно запускаются с автотестами и потребляют драгоценно евремя при прогоне всего набора тестов. Конечно время выполнения такого теста очень маленькое, но это может оттолкнуть от идеи использовать такой подход.

Стоит отметить, что сами тесты после запуска прогона на ветке получают статус: in_progress, что достаточно удобно, когда в отчете есть ручные и автоматические тесты. Это означает, что их нужно пройти вручную. Вообще, Allure TestOps умеет назначать тесты на тестировщиков, если вы пропишете правила в настройках запуска. Так же для более удобной работы с такимитестами, есть плагин Allure TestOps Support , который позволяет удобно выгружать результаты прогонов как ручных так и авто тестов в Allure Testops прямо не выходя из IDE.

Одно могу точно сказать: ребята из Qameta сейчас активно работают в этом направлении и я думаю, что со временем предложат более элегантное решение этого вопроса. Как несложно догадаться, наша команда получила то, чего желала, и пока что остается на этом пути.

Dashboards and reports

Что ж, с ручными тестами вроде разобрались, перенесли часть тестов в код, часть удалили, часть по пути автоматизировали, а некоторые тесты вообще расписали как документацию в Confluence, получив внутреннюю базу знаний. Осталось разобраться с отчетами. В Allure TestOps для этого есть отдельная страница, которая так и называется - dashboards. Она представляет из себя набор маленьких дэшбордов и виджетов, на которых можнонайти информацию обо всех тестах, их количестве, запусках (launches) и статистике исполнения.

Страница Dashboards
Страница Dashboards

На виджете “test cases” видно общее количество наших тестов, как ручных, так и автоматических. На виджете launches видны запуски и количество тестов, которые были запущены в каждом из них. Если этой информации покажется недостаточно, можно настроить свои виджеты с помощью встроенного query language (аналог языка в JIRA) и сделать практически любой отчет. К примеру мне очень понравилась идея с отчетом, который называется Test Case Tree Map Chart, показывающий матрицу покрытия.

Представьте себе единый график, на котором можно посмотреть, что для одной фичи у нас 3 ручных и 1 автотест, а для другой — только 5 ручных тестов. Такой график легко позволяет понять, где хромает автоматизация или тестовое покрытие в принципе.

Заключение и планы на будущее

Интеграция на этом этапе была завершена и то, что было реализовано в проекте, на текущий момент времени удовлетворяет наши потребности. В ближайших планах более гибкая настройка запуска тестов из Allure TestOps, т.е подготовка набора шаблонов с тестами, организация их в тест-планы и запуск их по отдельности из Allure TestOps на разных устройствах/браузерах/операционных системах. Еще планируем доработать напильником процесс работы с ручными тест-кейсами, а так же перенести часть старых тестов на новый стек. Самое приятно здесь то, что в случае использовании нового стека, нам не нужно менять TMS! Allure TestOps интегрируется почти со всеми популярными фрэймворками и работает из коробки, разве что с тостером не заведтся :)

Сам процесс рефакторинга, как я писал ранее, занял у команды долгий и тяжелый месяц, зато мы поняли, что на проекте автоматизировано, а что нет. Заодно привели в порядок ручные тесты. Стоило ли это того? Для нас - точно да. В итоге все стало работать понятнее и стабильнее.

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

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

Tags:
Hubs:
+17
Comments4

Articles

Change theme settings