Для работы с React компонентами с помощью Cypress используется комбинация Cypress, Cypress Testing Library и, при необходимости, @cypress/react. Cypress позволяет запускать тесты как в браузере, так и в headless-режиме, обеспечивая высокую стабильность и наглядность.
npm install cypress @testing-library/cypress @cypress/react --save-dev
npx cypress open
Это создаст структуру папок cypress/, где будут
храниться тесты, фикстуры и конфигурация.
В файле cypress/support/e2e.js необходимо импортировать
функции библиотеки:
import '@testing-library/cypress/add-commands';
Для тестирования React компонентов через @cypress/react
используется отдельная конфигурация:
import { mount } from '@cypress/react';
Изоляция компонентов. Каждый тест должен проверять отдельный компонент без зависимости от состояния всего приложения. Использование моков и стаба функций позволяет контролировать поведение зависимостей.
Селекторы и доступность. Cypress Testing Library поощряет использование селекторов на основе текста, ролей и атрибутов ARIA, а не CSS-классов. Это делает тесты более устойчивыми к изменениям стилей.
Пример:
cy.findByRole('button', { name: /добавить/i }).click();
cy.findByText(/элемент добавлен/i).should('exist');
Метод mount позволяет рендерить компонент в
изолированной среде Cypress. Это аналог unit-тестирования компонентов в
Jest, но с возможностью взаимодействия через браузер.
import MyButton from '../. ./src/components/MyButton';
it('клик по кнопке вызывает коллбек', () => {
const onCl ick = cy.stub();
mount(<MyButton onCl ick={onClick}>Нажми меня</MyButton>);
cy.findByText(/Нажми меня/i).click().then(() => {
expect(onClick).to.have.been.calledOnce;
});
});
Особенности:
mount создает полноценный DOM для компонента.useState,
useEffect) и контексты (useContext).React компоненты часто содержат внутреннее состояние. Cypress позволяет отслеживать изменения через DOM и имитацию пользовательских действий.
Пример теста формы:
import LoginForm from '../. ./src/components/LoginForm';
it('отображает ошибку при пустом вводе', () => {
mount(<LoginForm />);
cy.findByRole('button', { name: /войти/i }).click();
cy.findByText(/поле не может быть пустым/i).should('exist');
});
it('вызывает onSubmit при корректном вводе', () => {
const onSub mit = cy.stub();
mount(<LoginForm onSub mit={onSubmit} />);
cy.findByLabelText(/логин/i).type('user');
cy.findByLabelText(/пароль/i).type('12345');
cy.findByRole('button', { name: /войти/i }).click().then(() => {
expect(onSubmit).to.have.been.calledWith({ username: 'user', password: '12345' });
});
});
Компоненты React часто зависят от внешних API. Cypress позволяет
создавать стабы и моки через
cy.intercept.
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [{ id: 1, name: 'Иван' }],
}).as('getUsers');
mount(<UserList />);
cy.wait('@getUsers');
cy.findByText(/Иван/i).should('exist');
Преимущества:
Можно тестировать полный сценарий компонента:
cy.intercept('POST', '/api/login', {
statusCode: 200,
body: { token: 'abc123' },
}).as('login');
mount(<LoginForm />);
cy.findByLabelText(/логин/i).type('user');
cy.findByLabelText(/пароль/i).type('12345');
cy.findByRole('button', { name: /войти/i }).click();
cy.wait('@login');
cy.findByText(/успешный вход/i).should('exist');
Такой подход объединяет проверку UI, состояния и сетевых взаимодействий в одном тесте.
Cypress легко интегрируется с системами непрерывной интеграции.
Использование headless-режима (cypress run --headless)
позволяет запускать тесты автоматически при сборке. Дополнительно можно
сохранять видео и скриншоты при падении теста для удобного анализа.
npx cypress run --headless --record --key <project-record-key>
custom commands, например:Cypress.Commands.add('login', (username, password) => {
cy.findByLabelText(/логин/i).type(username);
cy.findByLabelText(/пароль/i).type(password);
cy.findByRole('button', { name: /войти/i }).click();
});
Эти команды сокращают повторяющийся код и делают тесты более читаемыми.
Тщательное использование этих инструментов обеспечивает надёжное тестирование React компонентов на всех уровнях — от отдельных элементов до интеграционных сценариев с API и состоянием приложения.