Как стать автором
Обновить
135.4

Внедрение E2E-тестирования с Puppeteer и Jest

Время на прочтение4 мин
Количество просмотров6.4K

Привет, Хабр!

Хотим поделиться краткой историей о том, как мы на одном из проектов «Рексофт» пришли к написанию автотестов, и почему сделали акцент именно на e2e-тестах.

Речь пойдет о работе с порталом крупного федерального заказчика, работающего в сфере B2B и B2C, имеющего серьезный трафик из всех регионов. Сайт писал не «Рексофт». Ресурс попал к нам на поддержку какое-то время назад. Изначально проект содержал довольно много легаси кода, тестов не было, как и документации. Требовалось сделать редизайн по новым макетам, параллельно расширяя существующую функциональность. Обычная история.

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

Перед выбором подхода к автотестам классифицировали баги по типу: их большая часть касалась именно бизнес-логики (Javascript). Багов, связанных с кроссбраузерностью или вёрсткой, было не очень много.

Итак, цель была поставлена — автоматизировать проверку бизнес-логики, т.е. заполнение и отправку форм, работу слайдеров и т.д.

В качестве базового фреймворка для тестов был выбран Jest, а для имитации действий пользователя — Puppeteer. Последний выбрали благодаря тому, что он поддерживается Google и имеет отличную документацию. Нам было вполне достаточно тестов в одном браузере (Chrome) (хотя, есть инструменты, позволяющие с помощью Puppeteer запускать тесты и в других браузерах, например, Firefox и IE). Playwright тогда ещё не было, а Selenium, чисто субъективно, казался более сложным в развертывании.

Далее кратко опишу преимущества и недостатки e2e-тестов.

Недостатки e2e-тестов

Относительно высокая сложность написания. Нужно обладать определёнными навыками, чтобы написать компактный и легкочитаемый e2e-тест.

Проблема закопаться. Я точно знаю, что желание проверить всё и вся, может привести к написанию огромного количества избыточных тестов. Как побороть эту проблему? Не стоит пытаться протестировать абсолютно все возможные кейсы, достаточно сосредоточиться на основных.

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

Ускорить прохождение тестов можно, запуская их параллельно. В этом поможет Browser Context в Puppeteer.

Пример конфига Jest + Puppeteer

Далее, вместо

page = global.__BROWSER__.newPage()

Используйте

newContext = await global.__BROWSER__.createIncognitoBrowserContext();
page = await newContext.newPage();
// example.spec.js
describe('[Домашняя страница]', () => {
  let page;

  beforeAll(async () => {
    const newContext = await global.__BROWSER__.createIncognitoBrowserContext();
    page = await newContext.newPage();

    await page.goto('https://google.com');
  });
  
  it('Страница должна называться "Google"', async () => {
    await expect(page.title()).resolves.toMatch('Google');
  });
});

Число параллельно запускаемых тестов в Jest регулируется флагом --maxWorkers.

«Хрупкость» e2e-тестов. Что я имею ввиду? Случай, когда тест падает без видимых на то причин, а при повторном запуске успешно выполняется, или же когда к падению теста приводит незначительное изменение в верстке. С хрупкостью тестов можно бороться с помощью автоматического перезапуска теста после падения. Помогут в этом раннер jest-circus и параметр retryTimes. Это практически полностью решает проблему “ложных” падений тестов.

Преимущества e2e-тестов

Гарантии. С e2e-тестами вы получаете определенные гарантии того, что система в целом работает корректно. Юниты такой гарантии не дают. Разумеется, это не значит, что вы получаете 100% гарантию того, что у вас работает абсолютно всё. Но вы будете уверены, что по крайней мере протестированные сценарии точно работают.

Снижение рабочей нагрузки. Без тестов разработчик вынужден думать — «как бы чего не сломать». Ведь не прокликивать же весь проект после очередного коммита с правками! С тестами вы узнаете о поломке еще до того, как код будет залит на стенд.

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

Ускорение рефакторинга. При рефакторинге js, e2e-тесты не придется переписывать. Да и рефакторинг в вёрстке тоже редко приводит к их переписыванию.

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

Лайфхаки

1. Для ускорения написания первых тестов можно записывать действия пользователя с помощью Headless recorder или с помощью встроенных в Chrome инструментов.

2. Если требуется проверить несколько наборов данных в рамках одного кейса и руки тянутся написать for внутри теста, используйте jest-each. Эта библиотека позволит прогнать несколько наборов данных в одном кейсе, сохранив читаемость кода:

each`
 url | selector | expectedIsVisible
 ${'/page1.html?land'} | ${'.js-order-button'} | ${true}
 ${'/page1.html'} | ${'.js-order-button'} | ${false}
 ${'/page2.html?land'} | ${'.js-order-button'} | ${true}
 ${'/page2.html'} | ${'.js-order-button'} | ${false}
`.it('Отображение кнопок заказа на странице $url', async ({ url, selector, expectedIsVisible }) => {
 await page.goto(`${SERVER_URL}${url}`, {
   waitUntil: 'networkidle2',
   timeout: 0
 });
 expect(await isVisible(page, selector)).toEqual(expectedIsVisible);
});

3. В случае возникновения ошибок, puppeteer не всегда корректно подсвечивает строку с ошибкой. Поэтому следует проверить код перед ошибочной строкой, часто ошибка кроется именно там.

4. Puppeteer позволяет запускать браузер с различными флагами, что иногда очень полезно (chrome://flags/). Ниже пример запуска браузера с отключенным флагом SameSite by default cookies

puppeteer.launch({
 headless: true,
 slowMo: 80,
 args: [
   '--disable-features=SameSiteByDefaultCookies'
 ]
});

В качестве заключения

Написание e2e-тестов занимают около 5-10% от времени написания фичи. На фиксы багов уходило сильно больше времени, так что оно того стоило. Несмотря на ряд недостатков, e2e-тесты позволяют значительно ускорить процесс разработки и обрести уверенность в том, что основная функциональность системы работает.

Разумеется, при внедрении e2e-тестов для фронтенда необходимо учитывать специфику вашего проекта. Спасибо за внимание!

Теги:
Хабы:
Всего голосов 5: ↑4 и ↓1+3
Комментарии3

Публикации

Информация

Сайт
www.reksoft.ru
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия