Тот факт, что 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()».
Пингбэк: Большой учебник по Cypress