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

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

.
Тестирование ссылок в Cypress
25.05.2021 00:00

Автор: Филип Рик (Filip Hric)
Оригинал статьи
Перевод: Ольга Алифанова

Я часто сталкиваюсь с необходимостью протестировать панель навигации, дабы убедиться, что все ссылки в ней правильно работают. Это симпатичный тестовый случай, к которому можно применять разнообразные подходы. В этой статье я хочу их осветить и показать, как применять их в Cypress.

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


<nav>
<a href="/blog">Blog</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>

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

it('click all links', () => {
 
cy.visit('/')
 
// blog page
cy.contains('blog').click()
cy.location('pathname').should('eq', '/blog')
cy.go('back')
 
// about page
cy.contains('about').click()
cy.location('pathname').should('eq', '/about')
cy.go('back')
 
// contact page
cy.contains('contact').click()
cy.location('pathname').should('eq', '/contact')
cy.go('back')
 
});

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

Вместо этого мы можем создать цикл:

it('click all links with loop', () => {
 
const pages = ['blog', 'about', 'contact']
 
cy.visit('/')
 
pages.forEach(page => {
 
cy.contains(page).click()
cy.location('pathname').should('eq', `/${page}`)
cy.go('back')
 
})
 
});

В этом тесте мы создаем массив (строка 3), а затем цикл forEach, который проходит по массиву и повторяет действия для каждого элемента. Это особенно полезно в случаях, когда наша навигационная панель меняется по какой-то причине. Мы просто добавляем в массив новый элемент, и тест продолжает работать.

Это, конечно, делает наш тест чище, но есть небольшая проблема с подходом .go('back'). Мы не ждем, что страница полностью загрузится. Убедившись, что имя пути верное, мы бежим назад. Хотя суть нашего теста в проверке навигационной панели, мы все же хотим убедиться, что ссылки открывают правильную страницу, и что мы не устраиваем гонок. Глеб Бахмутов написал отличную статью на эту тему. Нам не нужно тестировать чересчур быстро – мы можем упустить ошибки.

И мы их упускаем! Заметьте, что страницы About не существует! Клик по ссылке перенаправит нас на страницу 404! Может показаться, что панель навигации работает, а по сути в ней битая ссылка. Нехорошо получается.

Можно выбрать другой подход, используя команду .request() вместо открытия ссылки. Возможно, это звучит странно – зачем выполнять API-запрос к сайту? Но http-запрос – это то, что выполняется, когда вы вводите адрес сайта в браузере. Разница в том, что в качестве ответа вы получаете не JSON, а HTML-документ. Вы будете получать код статуса, 200 или 404, поэтому принцип тут точно такой же. Теперь вместо того, чтобы вводить адрес в браузере, мы просто выполним запрос и убедимся, что ссылки на самом деле работают.

it('use requests to navigation bar links', () => {
 
const pages = ['blog', 'about', 'contact']
 
cy.visit('/')
 
pages.forEach(page => {
 
cy
.contains(page)
.then((link) => {
cy.request(link.prop('href'))
})
 
})
 
});

Это поможет нам выявить ошибку – мы получим ошибку 404. В качестве бонуса можно протестировать ссылки, ведущие вовне вашего сайта, и преодолеть ограничение Cypress. Вы не можете посещать несколько доменов, но к другим доменам можно делать запросы, и для вашего сценария их может и хватить. Я писал об этом в статье о том, как тестировать открытие вкладок в Cypress.

Для последнего примера предположим, что мы не уверены, сколько ссылок содержит наша панель навигации, однако хотим убедиться, что все до единой работают. Для этого мы можем выбрать все <a>-элементы и пройтись по ним:

it('check all links on page', () => {
 
cy.visit('/')
cy.get('a').each(page => {
cy.request(page.prop('href'))
})
 
});

Тест, конечно, споткнется на ссылках, ведущих на адреса почты – чтобы пропустить их, измените селектор:

it('check all links to sites', () => {
 
cy.visit('/')
cy.get("a:not([href*='mailto:'])").each(page => {
cy.request(page.prop('href'))
})
 
});

Надеюсь, статья была вам полезной! Подписаться на меня можно в Twitter и LinkedIn.

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