Матричное тестирование

Основы матричного тестирования

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

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

Пример матричного тестирования

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

const assert = require('assert');

function isEven(n) {
  return n % 2 === 0;
}

describe('isEven', function() {
  const testCases = [
    { input: 2, expected: true },
    { input: 3, expected: false },
    { input: 4, expected: true },
    { input: 5, expected: false }
  ];

  testCases.forEach(function(testCase) {
    it(`должен вернуть ${testCase.expected} для числа ${testCase.input}`, function() {
      assert.strictEqual(isEven(testCase.input), testCase.expected);
    });
  });
});

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

Использование параметризованных тестов

Mocha не имеет встроенной функции для параметризованных тестов, как, например, в других тестовых фреймворках. Однако можно использовать различные подходы для достижения этого функционала. Одним из способов является использование внешних библиотек, таких как mocha-param, которая позволяет создавать матричные тесты с параметрами.

Пример с использованием mocha-param:

const assert = require('assert');
const param = require('mocha-param');

function isEven(n) {
  return n % 2 === 0;
}

describe('isEven', function() {
  param([
    { input: 2, expected: true },
    { input: 3, expected: false },
    { input: 4, expected: true },
    { input: 5, expected: false }
  ], function(testCase) {
    it(`должен вернуть ${testCase.expected} для числа ${testCase.input}`, function() {
      assert.strictEqual(isEven(testCase.input), testCase.expected);
    });
  });
});

Здесь используется метод param, который автоматически создает тесты для каждой комбинации входных данных и ожидаемого результата, предоставленных в массиве.

Матричное тестирование с асинхронными функциями

В случае асинхронных функций тестирование с помощью матричного подхода не изменяется. Важно помнить, что Mocha позволяет работать с асинхронными тестами как с использованием колбэков, так и с использованием промисов и async/await.

Пример для асинхронной функции:

const assert = require('assert');

function asyncIsEven(n) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(n % 2 === 0), 100);
  });
}

describe('asyncIsEven', function() {
  const testCases = [
    { input: 2, expected: true },
    { input: 3, expected: false },
    { input: 4, expected: true },
    { input: 5, expected: false }
  ];

  testCases.forEach(function(testCase) {
    it(`должен вернуть ${testCase.expected} для числа ${testCase.input}`, async function() {
      const result = await asyncIsEven(testCase.input);
      assert.strictEqual(result, testCase.expected);
    });
  });
});

В данном случае для каждого теста создается асинхронная проверка с использованием await и Promise, что позволяет тестировать асинхронную логику с матричным подходом.

Использование матричного тестирования для проверки разных условий

Матричное тестирование полезно не только для проверки стандартных данных, но и для тестирования различных сценариев, например, при изменении внешних условий. Пример:

function calculatePrice(price, discount, tax) {
  return price * (1 - discount) * (1 + tax);
}

describe('calculatePrice', function() {
  const testCases = [
    { price: 100, discount: 0.1, tax: 0.2, expected: 108 },
    { price: 200, discount: 0.2, tax: 0.15, expected: 184 },
    { price: 150, discount: 0.05, tax: 0.18, expected: 160.35 },
    { price: 250, discount: 0, tax: 0.1, expected: 275 }
  ];

  testCases.forEach(function(testCase) {
    it(`должен вернуть правильную цену для цены ${testCase.price}, скидки ${testCase.discount} и налога ${testCase.tax}`, function() {
      const result = calculatePrice(testCase.price, testCase.discount, testCase.tax);
      assert.strictEqual(result, testCase.expected);
    });
  });
});

Здесь проверяются различные сочетания входных данных: цена, скидка и налог. Такой подход позволяет протестировать сложные функции, которые зависят от нескольких факторов.

Преимущества матричного тестирования

  • Снижение дублирования кода. Вместо написания множества похожих тестов для разных значений входных данных можно использовать один шаблон с параметризованными значениями.
  • Удобство при добавлении новых тестов. Для того чтобы добавить новые параметры, достаточно просто расширить массив тестовых случаев.
  • Увеличение покрытия тестами. Матричное тестирование позволяет охватить большее количество вариантов входных данных без необходимости создавать отдельные тесты для каждого случая.

Заключение

Матричное тестирование в Mocha — это мощный инструмент для повышения эффективности и удобства написания тестов. Оно позволяет легко управлять большим количеством тестов, уменьшить объем повторяющегося кода и повысить читаемость тестов. Использование различных подходов, таких как параметризованные тесты или асинхронные функции, дает гибкость и делает процесс тестирования более удобным и масштабируемым.