Структура теста: describe, context, it

В Cypress, как и в других JavaScript-тестовых фреймворках (Mocha, Jest), ключевым элементом организации тестов является иерархическая структура с блоками describe, context и it. Понимание их роли обеспечивает удобное, читаемое и поддерживаемое тестирование.


Блок describe

describe используется для группировки связанных тестов. Он создаёт логическую единицу, которая объединяет сценарии вокруг общей функциональности или компонента приложения.

describe('Авторизация пользователя', () => {
  // тесты и дополнительные блоки внутри
});

Особенности блока describe:

  • Может содержать другие блоки describe, создавая вложенные группы.
  • Используется для структурирования и логической организации тестов.
  • Позволяет подключать хуки (before, beforeEach, after, afterEach) для подготовки и очистки состояния перед тестами.

Пример использования хуков:

describe('Авторизация пользователя', () => {
  before(() => {
    cy.visit('/login');
  });

  beforeEach(() => {
    cy.reload();
  });

  it('Проверка успешного входа', () => {
    cy.get('#username').type('user');
    cy.get('#password').type('password');
    cy.get('button[type=submit]').click();
    cy.url().should('include', '/dashboard');
  });
});

Блок context

context является синонимом describe, но используется для повышения читаемости, когда требуется подчеркнуть определённое условие или состояние системы.

context('Существующий пользователь', () => {
  it('Может войти с корректными данными', () => {
    // тест
  });
});

Разница между describe и context:

  • describe больше акцентирует на функциональности или модуле.
  • context выделяет конкретные сценарии или состояния, например «Когда пользователь неактивен» или «Если сессия истекла».
  • Семантическая разница облегчает чтение отчётов тестирования и структуру кода в больших проектах.

Блок it

it описывает отдельный тестовый сценарий. Он отвечает за конкретное поведение, которое необходимо проверить.

it('Показывает сообщение об ошибке при неверном пароле', () => {
  cy.get('#username').type('user');
  cy.get('#password').type('wrongpassword');
  cy.get('button[type=submit]').click();
  cy.contains('Неверный пароль').should('be.visible');
});

Характерные особенности блока it:

  • Должен быть коротким и проверять одно поведение.
  • Название теста должно быть осмысленным и описывать ожидаемый результат.
  • Можно использовать асинхронные действия Cypress, такие как cy.get, cy.visit, cy.request, благодаря цепочкам команд (chaining).

Вложенные блоки

Структура может быть многослойной: describecontextit. Вложенность позволяет разделять подготовку тестовой среды и конкретные сценарии.

describe('Авторизация пользователя', () => {
  context('Существующий пользователь', () => {
    it('Может войти с корректными данными', () => {
      cy.login('user', 'password');
      cy.url().should('include', '/dashboard');
    });

    it('Не может войти с некорректным паролем', () => {
      cy.login('user', 'wrongpassword');
      cy.contains('Неверный пароль').should('be.visible');
    });
  });

  context('Новый пользователь', () => {
    it('Не может войти без регистрации', () => {
      cy.login('newuser', 'password');
      cy.contains('Пользователь не найден').should('be.visible');
    });
  });
});

Организация хуков в структуре тестов

Cypress поддерживает хуки Mocha, которые можно применять на любом уровне вложенности:

  • before — выполняется один раз перед всеми тестами блока.
  • beforeEach — выполняется перед каждым тестом блока.
  • after — выполняется один раз после всех тестов блока.
  • afterEach — выполняется после каждого теста блока.

Пример:

describe('Авторизация пользователя', () => {
  before(() => {
    cy.task('resetDatabase');
  });

  beforeEach(() => {
    cy.visit('/login');
  });

  it('Успешный вход', () => {
    cy.login('user', 'password');
    cy.url().should('include', '/dashboard');
  });

  afterEach(() => {
    cy.clearCookies();
  });

  after(() => {
    cy.task('cleanupTestUsers');
  });
});

Правила написания чистой структуры тестов

  1. Одна логическая единица на describe — все тесты внутри должны относиться к одному компоненту или функциональности.
  2. Одно состояние на context — фокус на условиях, например «когда данные корректны» или «когда токен истёк».
  3. Один сценарий на it — тест должен проверять только одно поведение.
  4. Использование хуков вместо повторяющихся команд — делает код лаконичным и поддерживаемым.
  5. Чёткие имена тестов — они должны быть понятны без необходимости смотреть реализацию.

Структура describecontextit обеспечивает модульность, читаемость и поддерживаемость тестов в больших проектах. Правильное использование этих блоков вместе с хуками позволяет создавать надёжные и предсказуемые автоматизированные тесты.