Разделы портала

Онлайн-тренинги

.
Использование тегов для фильтрации тестов Cypress
17.06.2020 00:00

Автор: Мэри Дрейк (Marie Drake)
Оригинал статьи
Перевод: Ольга Алифанова

На этой неделе я помогала коллегам переносить существующие тесты WebdriverIO в Cypress. Если вы хотите знать, что такое Cypress, и чем он отличается от Selenium – посмотрите этот вебинар от Гила Тайара. Перенося некоторые тесты, я вспомнила, что существующий тест-набор использовал теги Cucumber для фильтрации того, какие тесты в каких окружениях прогоняются. Фильтрация тестов – полезная для нас фича, потому что на проде мы прогоняем только часть наших тестов. В имеющемся у нас сейчас фреймворке Cypress мы решили пользоваться стандартным подходом – писать тесты с использованием Mocha в качестве прогонщика, а не Cucumber. У Mocha есть способ фильтрации тестов с использованием паттерна –grep, но он сейчас не поддерживается в Cypress, и о его внедрении просят пользователи. Мне не очень-то хотелось использовать плагин Cypress Cucumber исключительно для использования функции тегов, поэтому я решила внедрить простенький обходной путь, который планирую предложить коллегам, пока мы ждем внедрения фичи от Cypress.

Первым делом я создала модуль по имени test-filter.ts, который по сути фильтрует Cypress-тесты на основании предоставленного тега или тегов. Он принимает два параметра – теги, определенные в файле спецификации, и функцию, которая будет запущена при нахождении тегов. Если переменная окружения 'TEST_TAGS' существует, мы просто разбиваем ее на значения и храним в переменной-массиве по имени tags. Затем используется функция Array.some() – она вернет истину, если в массиве definedTags есть хотя бы один тег из массива tags. Если это верно, тест запускается.

/// <reference types="Cypress" />
 
const TestFilter = (definedTags: string[], runTest: Function) => {
if (Cypress.env('TEST_TAGS')) {
const tags = Cypress.env('TEST_TAGS').split(',');
const isFound = definedTags.some(definedTag => tags.includes(definedTag));
 
if (isFound) {
runTest();
}
} else {
runTest();
}
};
 
export default TestFilter;

Следующий шаг – импорт этого модуля в мои файлы спецификаций. Ниже пример кода показывает, что для этого теста я добавила два тега (smoke и test). Функция, которую я передаю в TestFilter – это полный describe-блок, содержащий мой тест.

/// <reference types="Cypress" />
 
import TestFilter from '../../test-filter';
 
TestFilter(['smoke', 'test'], () => {
describe('Taboola', () => {
beforeEach(() => {
cy.viewport('macbook-13');
});
 
it('should exist on an article page', () => {
cy.visit(Cypress.env('TEST_ARTICLE'));
cy.waitForAdRequest();
 
cy.get('div[data-mode="Feeder"]').should('exist');
cy.get('div[data-mode="alternating-thumbnails-a"]').should('exist');
});
});
});

Для запуска тестов с функциональностью тегов мне пришлось экспортировать в Cypress переменную окружения, названную 'TEST_TAGS'. К примеру, если у нас 4 файла спецификации, и 3 из них помечены тегом "regression", а один – "smoke", запуск команды ниже выполнит только тест с тегом "smoke".

CYPRESS_TEST_TAGS=smoke npm run cy:run:local:dev

 

Тест, отмеченный тегом "smoke", прогоняется, а другие тесты – нет.

Множественные теги тоже поддерживаются, это можно реализовать при помощи, например, такой команды:

CYPRESS_TEST_TAGS=testA,testB npm run cy:run:local:dev

На скриншоте ниже можно видеть, что запущено было два теста – один, отмеченный тегом testA, и другой с тегом testB.

 

Два теста запущено, а остальные тесты – нет.

У этого подхода, однако, есть ограничение, и он не настолько мощный, как теги Cucumber. К примеру, если мы посмотрим на код ниже, и нам нужно прогнать только "Test B", запуск команды CYPRESS_TEST_TAGS=testB npm run cy:run:local:dev все равно будет прогонять "Test A", так как он не обернут в TestFilter. Так как я не хочу тегать "Test A" в этом примере, то для корректной работы мне пришлось обернуть этот тест в TestFilter и передавать как пустой массив.

/// <reference types="Cypress" />
 
import TestFilter from '../../test-filter';
 
describe('My Test with tags', () => {
it('Test A', () => console.log('test A'));
 
TestFilter(['testB'], () => it('Test B', () => console.log('test B')));
});

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

Обсудить в форуме