Кастомные assertions

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

Основы создания кастомных assertions

В Cypress кастомные assertions реализуются с помощью библиотеки Chai, которая используется по умолчанию. Chai позволяет добавлять собственные методы проверки через chai.Assertion.addMethod или chai.Assertion.addProperty.

  • addMethod — добавляет метод с аргументами.
  • addProperty — добавляет проверку без аргументов, выполняющуюся как свойство.

Пример метода, проверяющего наличие текста в элементе без учета регистра:

chai.Assertion.addMethod('textIgnoreCase', function(expectedText) {
  const actualText = this._obj.text().trim().toLowerCase();
  this.assert(
    actualText === expectedText.toLowerCase(),
    `Ожидалось, что элемент будет содержать текст #{exp}, но найден #{act}`,
    `Ожидалось, что элемент не будет содержать текст #{exp}`,
    expectedText.toLowerCase(),
    actualText
  );
});

Использование в тесте:

cy.get('.notification').should('textIgnoreCase', 'успешно сохранено');

Кастомные assertions для работы с HTTP-ответами

Частая задача в тестировании — проверка API-ответов. Cypress позволяет делать cy.request(), а кастомные assertions помогают централизовать проверки структуры данных или значений полей.

Пример кастомного метода для проверки схемы JSON:

chai.Assertion.addMethod('matchSchema', function(schema) {
  const actual = this._obj;
  const Ajv = require('ajv');
  const ajv = new Ajv();
  const validate = ajv.compile(schema);
  const valid = validate(actual);
  
  this.assert(
    valid,
    `Ожидалось, что объект соответствует схеме, ошибки: #{act}`,
    `Ожидалось, что объект не соответствует схеме`,
    schema,
    validate.errors
  );
});

Применение:

const userSchema = {
  type: 'object',
  properties: {
    id: { type: 'number' },
    name: { type: 'string' },
    email: { type: 'string' }
  },
  required: ['id', 'name', 'email']
};

cy.request('/api/users/1').its('body').should('matchSchema', userSchema);

Проверка пользовательских условий элементов

Иногда нужно проверять динамичные свойства элементов, например наличие определённого атрибута или состояние чекбокса. Создание кастомного assertion упрощает повторное использование логики.

Пример проверки, что элемент видим и содержит атрибут data-active:

chai.Assertion.addMethod('activeVisible', function() {
  const el = this._obj;
  this.assert(
    el.is(':visible') && el.attr('data-active') === 'true',
    'Ожидалось, что элемент видим и активен',
    'Ожидалось, что элемент не видим или не активен'
  );
});

Использование в цепочке Cypress:

cy.get('.menu-item').should('activeVisible');

Интеграция кастомных assertions с Cypress

Для глобального использования кастомных assertions их обычно добавляют в файл cypress/support/commands.js или cypress/support/index.js. Это гарантирует, что методы будут доступны во всех тестах без дополнительного импорта.

// cypress/support/index.js
import './customAssertions';

В файле customAssertions.js находятся все определения:

chai.Assertion.addMethod('textIgnoreCase', function(expectedText) {
  const actualText = this._obj.text().trim().toLowerCase();
  this.assert(
    actualText === expectedText.toLowerCase(),
    `Ожидалось, что элемент будет содержать текст #{exp}, но найден #{act}`,
    `Ожидалось, что элемент не будет содержать текст #{exp}`,
    expectedText.toLowerCase(),
    actualText
  );
});

Такой подход обеспечивает единое место для поддержки и расширения кастомных проверок, облегчая сопровождение тестового набора.

Рекомендации по использованию

  • Повторное использование: кастомные assertions делают тесты короче и читаемее, особенно при сложных проверках элементов или API.
  • Сообщения об ошибках: важно указывать информативные сообщения, чтобы при падении теста сразу было понятно, какая проверка не прошла.
  • Соблюдение цепочек Cypress: кастомные assertions должны корректно работать с объектами jQuery или объектами Cypress, чтобы их можно было использовать в .should() без дополнительных оберток.
  • Тестируемость самих assertions: желательно отдельно проверять кастомные assertions в небольших unit-тестах, чтобы убедиться, что логика работает корректно.

Кастомные assertions позволяют создавать выразительные, легко читаемые тесты, интегрированные с цепочками Cypress и Chai. Это повышает качество тестирования, делает тестовый код более поддерживаемым и гибким в условиях сложных бизнес-логик и динамических интерфейсов.