Shared context и состояние

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


Контекст между тестами: this и Mocha hooks

Cypress основан на Mocha, поэтому в его тестах доступны привычные хуки: before, beforeEach, after, afterEach. Переменные, присвоенные в this внутри этих хуков, могут использоваться в тестах того же блока describe.

Пример:

describe('Проверка пользовательского профиля', function () {
  before(function () {
    cy.fixture('user').then((user) => {
      this.user = user;
    });
  });

  it('Авторизация пользователя', function () {
    cy.visit('/login');
    cy.get('#username').type(this.user.username);
    cy.get('#password').type(this.user.password);
    cy.get('button[type=submit]').click();
  });

  it('Проверка данных профиля', function () {
    cy.visit('/profile');
    cy.get('.profile-name').should('contain', this.user.name);
  });
});

Ключевой момент: this работает только с обычными функциями function() {}, а не со стрелочными функциями. Стрелочные функции фиксируют контекст лексически и не смогут получить this из Mocha.


Хранение состояния через Cypress.env

Cypress предоставляет глобальный объект Cypress.env для хранения данных, доступных в любом тесте или файле. Это особенно удобно для хранения токенов, ключей или конфигурационных значений:

Cypress.env('authToken', '1234567890abcdef');

describe('Тест API с токеном', () => {
  it('Получение данных пользователя', () => {
    cy.request({
      url: '/api/user',
      headers: { Authorization: `Bearer ${Cypress.env('authToken')}` }
    }).then((response) => {
      expect(response.status).to.eq(200);
    });
  });
});

Особенность: Cypress.env сохраняет данные только на время выполнения тестового прогона, их нужно повторно устанавливать при каждом запуске.


Shared Context через алиасы (as)

Cypress поддерживает механизм алиасов, который позволяет сохранять результат команды и использовать его в последующих шагах с помощью @alias.

Пример:

describe('Работа с элементами и API', () => {
  beforeEach(() => {
    cy.fixture('user').as('userData');
  });

  it('Использование данных из fixture', function () {
    cy.get('@userData').then((user) => {
      cy.visit('/login');
      cy.get('#username').type(user.username);
      cy.get('#password').type(user.password);
      cy.get('button[type=submit]').click();
    });
  });
});

Преимущество алиасов:

  • Возможность повторного использования значений без глобальных переменных.
  • Четкая привязка к конкретной цепочке команд Cypress.
  • Поддержка асинхронного характера Cypress команд.

Управление состоянием приложения

Состояние веб-приложения часто нужно не только хранить, но и сбрасывать между тестами для обеспечения изоляции. Cypress предлагает несколько подходов:

  1. Очистка localStorage и sessionStorage
beforeEach(() => {
  cy.clearLocalStorage();
  cy.clearCookies();
});
  1. Использование API для подготовки данных

Для сложных сценариев полезно выполнять прямые запросы к backend перед тестом:

beforeEach(() => {
  cy.request('POST', '/api/reset-database');
});
  1. Тесты с сохранением состояния через cookies
Cypress.Cookies.preserveOnce('session_id', 'auth_token');

it('Сохраняет сессию между тестами', () => {
  cy.visit('/dashboard');
});

Вывод: правильная организация состояния позволяет избежать фликеров тестов, повышает стабильность и ускоряет прогон тестов.


Совмещение методов: гибридный подход

Оптимальная стратегия обычно комбинирует:

  • алиасы для временных данных внутри describe;
  • Cypress.env для глобально доступных значений;
  • Mocha hooks для подготовки и очистки состояния;
  • прямые API-запросы для контроля данных на сервере.

Такой подход обеспечивает:

  • полную изоляцию тестов;
  • возможность параллельного прогона;
  • удобство чтения и поддержки тестов.

Практические рекомендации

  • Использовать this и алиасы только внутри одного блока describe.
  • Глобальные переменные избегать, чтобы не нарушать изоляцию тестов.
  • Всегда сбрасывать состояние после теста, особенно для сессий и localStorage.
  • Для повторного использования данных между тестами использовать Cypress.env или fixture + алиасы.
  • Сохранять логическую последовательность хуков: сначала before, потом beforeEach, затем тесты, после — afterEach и after.

Эффективное использование shared context и управление состоянием позволяют Cypress тестам оставаться надежными, быстрыми и легко масштабируемыми.