Как ускорить тесты с помощью сypress-grep

Что такое cypress-grep

Этот плагин полезен при запуске тестов, умеет запускать их “выборочно” — по части имени, или по тегу. Например, есть возможность размечать тесты тегами (как на примере ниже):

it('loads the page', () => ...)

it('searches for items', {tags: '@search'}, () => ...)

Запускаем тест (перед тем поставив плагин и добавив в строку grep переданное из переменных окружения Cypress):

$ npx cypress run --env grep="loads"

Запускаем второй тест, уже с тегом (grepTags):

$ npx cypress run --env grepTags="@search"

Все другие тесты в файле будут “приостановлены” (со статусом “Pending” — подробнее о статусах в Cypress тут), как если бы применялся метод it.skip.

- loads the page
✓ searches for items(811ms)

1 passing (811ms)
1 pending

При этом надо учесть, что приостановка (или скорее пропуск) тестов таким способом не увеличивает для вас стоимость Cypress — тесты в статусе “Pending” не учитываются при расчете стоимости.

Сейчас разберем, как эффективно применять grep с тестами и экономить время в CI-процессах, и фильтровать тесты.

Полный код примеров — в репозитории; результаты тестов — на дашборде здесь.

Workflow на GitHub Actions

В проекте было несколько наборов и тестов с тегами разных функций. Также был Github Actions Workflow tags.yml который запускал тесты с тегами по каждой функции отдельно. Например, первый job запускает все тесты с тегом @dynamic:

tag-dynamic:
  runs-on: ubuntu-20.04
  needs: install
  steps:
    - name: Checkout ?
      uses: actions/checkout@v2

    # https://github.com/cypress-io/github-action
    - name: Run tests ?
      uses: cypress-io/github-action@v2
      with:
        start: npm run dev
        wait-on: 'http://localhost:1234'
        env: grepTags=@dynamic
        record: true
        group: '1 - @dynamic'
        tag: tags
      env:
        # pass the Dashboard record key as an environment variable
        CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}

Параллельно, второй job запускает все тесты с тестом @visible

env: grepTags=@visible
group: '2 - @visible'

Здесь есть job’ы, которые запускают только тесты с тегами @client и @intercept. В конце есть job, который выполняет все тесты untagged.

untagged:
  runs-on: ubuntu-20.04
  needs: [tag-intercept, tag-client, tag-visible, tag-dynamic]
  steps:
    - name: Checkout ?
      uses: actions/checkout@v2

    # https://github.com/cypress-io/github-action
    - name: Run tests ?
      uses: cypress-io/github-action@v2
      with:
        start: npm run dev
        wait-on: 'http://localhost:1234'
        env: grepUntagged=true
        record: true
        group: '5 - untagged'
        tag: tags
      env:
        # pass the Dashboard record key as an environment variable
        CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}

Job’ы с тегами выполняются параллельно, а без тегов —untagged выполняются в конце.

Пустые .spec-файлы (далее спеки)

У нас было 19 .spec-файлов в проекте. Когда запускались только тесты с тегами @dynamic, что случилось со .spec-файлами в которых не было тестов с таким тегом? Они показывали “ошибку” в Cypress Dashboard (на следующем скрине).

Спеки без тегов показаны как «ошибки»

Вы можете видеть, что Dashboard срабатывает не так как мы хотим — потому что он засчитывает одни и те же .spec-файлы снова и снова — tag-dynamic, затем tag-visible, затем tag-intercept, и т.д. И в большинстве из этих файлов нет тестов с тегом, который нас интересует — поэтому они отобразятся как ошибки, и просто заберут у нас дефицитное время в CI.

Можно сделать это правильнее. Плагин cypress-grep имеет опцию “предпросмотра” .spec-файла, и если нет тегов или grep-строчки которую мы сейчас ищем в названии теста, тесты из этого файла не будут выполнены. Активируем эту опцию переменной окружения:

env: grepTags=@dynamic,grepFilterSpecs=true

А чтобы случайно не забыть активировать эту опцию, можем задать ее в файле конфигурации cypress.json:

{
  "env": {
    "grepFilterSpecs": true
  }
}

После этого CI-job tag-dynamic немедленно становится намного быстрее — потому что он фильтрует все 19 .spec-файлов, и запустит только те, в которых найдется нужный тег.

Только в одной спеке есть тег «@dynamic»

Да и каждый job становится быстрее:

tag-dynamic 2m 51s => 1m 7s
tag-visible 3m 13s => 2m 26s
tag-client 1m 39s => 1m 7s
tag-intercept 2m 8s => 1m 4s

Отличный экономный подход, больше не надо открывать 18 .spec-файлов из 19, потому что там нет тестов к выполнению.

Дешборд до и после фильтрации

Примечание: job’ы c меткой untagged не подвергаются фильтрации, поскольку опция grepUntagged=true (пока) несовместима с опцией grepFilterSpecs=true.

Пропуск отфильтрованных тестов

Если у нас есть .spec-файл с несколькими тестами it, и мы применяем grep, фильтрованные тесты исключаются при помощи it.skip. Это может создать непонятки в Command Log и в тестовой аналитике. Например, в этом .spec-файле больше фильтрованных тестов чем выполняемых, если применить grep=”works 2”

Отфильтрованные тесты

А можем применить другую опцию, полного обхода фильтрованных тестов. Она “прячет” тесты которые не выполняются:

{
  "env": {
    "grepFilterSpecs": true,
    "grepOmitFiltered": true
  }
}

В Command Log и аналитике теперь видим только выполняемые тесты: 

Только отфильтрованные тесты

В нашем примере todo-graphql-example удалены из рассмотрения все “скипнутые” тесты. Например, перед тем как мы отфильтровали тесты с тегом “@visible”:

TodoMVC with GraphQL cy.intercept
  - completes the first todo
  ✓ stubs todos query (518ms)
  ✓ shows loading indicator (490ms)
  - adds and deletes todo
  - stubs by checking operation name
  ✓ spies on adding todos (499ms)
  - intercepts operations using custom header


3 passing (2s)
4 pending

После того как добавили опцию grepOmitFiltered=true, в выводе будут только тесты с тегом:

TodoMVC with GraphQL cy.intercept
  ✓ stubs todos query (515ms)
  ✓ shows loading indicator (491ms)
  ✓ spies on adding todos (493ms)


3 passing (2s)

Это уже намного лучше.

Ручной workflow

Можно добавить новый workflow в проект; который мы будем активировать вручную в любое время когда запускаем отдельный тест или группу тестов. Пример такого workflow в файле grep.yml.

name: grep
on:
  workflow_dispatch:
    inputs:
      grep:
        description: Part of the test title
        required: false
      grepTags:
        description: Test tags
        required: false
      burn:
        description: Number of times to repeat the tests
        required: false
jobs:
  grep:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout ?
        uses: actions/checkout@v2

      # https://github.com/cypress-io/github-action
      - name: Run filtered tests ?
        uses: cypress-io/github-action@v2
        with:
          start: npm run dev
          wait-on: 'http://localhost:1234'
          env: grep=${{ github.event.inputs.grep }},grepTags=${{ github.event.inputs.grepTags }},burn=${{ github.event.inputs.burn }}
          record: true
          group: 'grep=${{ github.event.inputs.grep }},grepTags=${{ github.event.inputs.grepTags }},burn=${{ github.event.inputs.burn }}'
          tag: grep
        env:
          # pass the Dashboard record key as an environment variable
          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}

Давайте проверим, надежен ли тест в “cors-spec.js”. Запустим его 5 раз подряд. Из GitHub-интерфейса запустим workflow со следующими параметрами:

Вручную

Параметры grep, grepTags и burn передаются в Cypress через env: … . Только один .spec-файл имеет название отвечающее строке в grep. И этот тест был выполнен пять раз подряд.

GitHub Action 

Cypress Dashboard показывает один .spec-файл с 5 выполненными тестами, в названии видим наши параметры:

Результаты на Cypress Dashboard

На этом все.

Какой была ваша первая зарплата в QA и как вы искали первую работу?

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

1 КОММЕНТАРИЙ

Подписаться
Уведомить о
guest

1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
aviator
aviator
2 лет назад

Про cypress-grep ничего до этой статьи не слышал. Прикольная штука, но зашёл на гитхаб — всего лишь 64 звёзды. Рановато ещё его на реальных проектах использовать

Мы в Telegram

Наш официальный канал
Полезные материалы и тесты
Готовимся к собеседованию
Project- и Product-менеджмент

? Популярное

? Telegram-обсуждения

Наши подписчики обсуждают, как искали первую работу в QA. Некоторые ищут ее прямо сейчас.
Наши подписчики рассказывают о том, как не бояться задавать тупые вопросы и чувствовать себя уверенно в новой команде.
Обсуждаем, куда лучше податься - в менеджмент или по технической ветке?
Говорим о конфликтных ситуациях в команде и о том, как их избежать
$1100*
медианная зарплата в QA в июне 2023

*по результатам опроса QA-инженеров в нашем телеграм-канале

Собеседование

19%*
IT-специалистов переехало или приняло решение о переезде из России по состоянию на конец марта 2022

*по результатам опроса в нашем телеграм-канале

live

Обсуждают сейчас