Ускорьте Cypress тесты с помощью функции .clock()

Тот факт, что Cypress работает в том же контексте, что и тестируемое приложение, является одним из его главных преимуществ. Об этом писалось в предыдущей статье Page Objects против App Actions. Такая архитектура позволяет нам рассмотреть функции, которое выполняет наше приложение. Кроме того, она позволяет настроить контекст приложения, например, предпочтения браузера и время. Последнее и является темой данной статьи.

Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ

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

Принцип работы этого приложения заключается в том, что внутри него имеется функция setInterval(). Это JS-функция, которая принимает два аргумента. Первый аргумент – это функция, которую мы хотим запустить, а второй – это время в миллисекундах, которое указывает нашей функции, как часто она должна запускать эту функцию.

setInterval(updateTime, 1000);

Всю работу в этом приложении выполняет функция updateTime(). Принцип ее работы довольно прост. В нашем приложении есть два Date объекта. Один из них получает наше время в момент открытия приложения, а второй создается при каждом вызове нашей функции   updateTime(). Затем эти два значения сравниваются, и каждую секунду мы получаем информацию о новом времени. Потом мы берем элемент <div class="timer"></div>  и обновляем текст, указывая новое время.

Функция .clock() в Cypress позволяет нам обращаться ко всем объектам Date и функциям обработки времени и перемещать их по своему усмотрению. Допустим, при открытии приложения мы хотим переместить время на 10 секунд вперед. Это можно сделать с помощью следующего кода:

it('move timer', () => {

  const now = new Date()

  cy
    .visit('index.html')

  cy
    .clock(now)

  cy
    .tick(10000)

});

Передача переменной now в нашу команду.clock() приведет к установке часов Cypress на текущий момент. Без этого аргумента отсчет начнется с начала эпохи UNIX, что отбросит часы более чем на 50 лет назад.

Использование функции .tick() Cypress переводит наше время на 10 секунд вперед. Чтобы восстановить время и вернуть все на круги своя, достаточно вызвать функцию восстановления .clock() следующим образом:

it('move timer', () => {

  const now = new Date()

  cy
    .visit('index.html')

  cy
    .clock(now)

  cy
    .tick(10000)

  cy.clock().invoke('restore')

});

Это отличный инструмент для повышения скорости выполнения тестов. В приложении-клоне Trello есть сообщение об ошибке, которое появляется, когда мы получаем от сервера ответ не 200. Это сообщение об ошибке использует setTimeout() функцию, так что через 4 секунды оно автоматически исчезает. Для проверки используется команда .intercept().

it('error message works', () => {

  cy
    .intercept('POST', '/api/boards', {
      forceNetworkError: true
    })
    .as('boardCreate')

  cy
    .visit('/');

  cy
    .get('[data-cy=create-board]')
    .click()

  cy
    .get('[data-cy=new-board-input]')
    .type('new garden{enter}')

  cy
    .get('#errorMessage')
    .should('be.visible')

  cy
    .get('#errorMessage')
    .should('not.be.visible')

})

В этом тесте проверяется не только то, что элемент #errorMessage появляется, но также и то, что он исчезает. Поскольку по умолчанию таймаут повторной попытки в Cypress установлен на 4000 мс, этот тест прекрасно работает.

За исключением одного момента.

В данном тесте мы ждем 4 секунды, пока сообщение об ошибке исчезнет. Это 4 секунды ожидания. Кажется, что это не так уж и много, но если ваш тестовый набор состоит из сотен тестов, то, возможно, следует провести оптимизацию. С таким тестом, как этот, это точно нужно сделать.

Мы можем сделать то же самое, что и с нашим тестом на таймере. Мы можем сдвинуть время вперед и пропустить ожидание:

it('error message works', () => {

  cy
    .intercept('POST', '/api/boards', {
      forceNetworkError: true
    })
    .as('boardCreate')

  cy
    .clock();

  cy
    .visit('/');

  cy
    .get('[data-cy=create-board]')
    .click()

  cy
    .get('[data-cy=new-board-input]')
    .type('new garden{enter}')

  cy
    .get('#errorMessage')
    .should('be.visible')

  cy
    .tick(4000)

  cy
    .get('#errorMessage')
    .should('not.be.visible')

})

В данном случае нам не нужно передавать объект Date в функцию .clock(), поскольку мы работаем с функцией setTimeout(), которая будет просто перенесена с помощью функции.tick(), и нам не важна точная дата. Теперь наш тест проходит сразу же.

Мы ускорили работу нашей функции на 4 секунды и убрали время простоя.

Надеюсь, что данная статья вам понравилась. Другие интересные материалы по Cypress вы можете найти на этом сайте в разделе “Похожие записи” в нижней части этой статьи

Перевод статьи «Make your Cypress tests faster with .clock()».

1 комментарий к “Ускорьте Cypress тесты с помощью функции .clock()”

  1. Пингбэк: Большой учебник по Cypress

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *