Тестирование кода с помощью библиотеки Chai

Создано: 22-04-2020

Мне попалась переведенная с английского статья, в которой описываются 11 инструментов и библиотек для тестирования React-компонентов. Не лишнем будет прочитать ее прежде, чем продолжать читать далее.

Источниками для данной статьи послужили: chaijs, freecodecamp и nodejs.

Chai – это библиотека, предоставляющая различные функции для проверки утверждений. Chai - это библиотека утверждений BDD/TDD для node и браузера, которая может прекрасно сочетаться с любым тестовым фреймворком JavaScript, например, таким как, Mocha или Jest.

Chai имеет несколько интерфейсов, которые позволяют разработчику выбрать наиболее удобный. Цепочечные стили BDD обеспечивают выразительный язык и читаемый стиль, в то время как стиль TDD assert обеспечивает более классическое ощущение.

Пакет Chai устанавливается из npm:

npm install chai

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

Изучение работы assert'ов JavaScript

assert.isNull(err, 'никакой ошибки не было');

var tea = 'вкусный чай';
assert.isNotNull(tea, 'отлично, пора пить чай!');

Во все инструкции assert можно добавить второе необязательное сообщение. Оно будет включено в сообщения об ошибках, если assert не пройдет. Пример:

var tea = 'вкусный чай';
assert.isNotNull(tea, 'отлично, пора пить чай!', 'что-то пошло не так');

Проверка определения переменной или функции

var tea = 'чашка чая';
assert.isDefined(tea, 'чай уже был определен');

var tea;
assert.isUndefined(tea, 'tea не определен');

Использование assert.isOK и assert.isNotOK

assert.isOk('everything', 'все в порядке');
assert.isOk(false, 'это не сработает');

assert.isNotOk('everything', 'это не сработает');
assert.isNotOk(false, 'это прокатит');

Тест на истиность

var teaServed = true;
assert.isTrue(teaServed, 'чай уже подан');

еще примеры

assert.isTrue(true, 'тест пройдет с логическим значением true');
assert.isTrue('true', 'тест не пройдет со строковым значением 'true');
assert.isTrue(1, 'тест не пройдет с числовым значением 1');

var tea = 'вкусный чай';
assert.isNotTrue(tea, 'отлично, пора пить чай!');

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

assert.equal(3, '3', '== преобразует значения в строки');

assert.notEqual(3, 4, 'эти числа не равны');

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

assert.strictEqual(true, true, 'эти логические значения строго равны');

assert.notStrictEqual(3, '3', 'не является строгим равенством');

Глубокое сравнение с помощью .deepEqual и .notDeepEqual

assert.deepEqual({ tea: 'green' }, { tea: 'green' });

assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
assert.deepEqual(
  { a: '1', b: 5 },
  { b: 5, a: '1' },
  'порядок ключей не имеет значения'
);
assert.notDeepEqual(
  { a: [5, 6] },
  { a: [6, 5] },
  'положение элементов массива имеет значение !!'
);

Сравнение свойств двух элементов

assert.isAbove(5, 2, '5 строго больше чем 2');
assert.isAbove(Math.PI, 3, число ПИ больше чем 3);

assert.isBelow(3, 6, '3 меньше, чем 6');

assert.isAtMost(3, 6, '3 меньше или равно 6');
assert.isAtMost(4, 4, '4 меньше или равно 4');
assert.isAtMost('hello'.length, 5);
assert.isAtMost(1 - Math.random(), 1);

assert.isAtLeast(5, 2, '5 больше или равно 2');
assert.isAtLeast(3, 3, '3 больше или равно 3');

Проверка на попадание значения в определенный диапазон

assert.approximately(1.5, 1, 0.5, 'числа в диапазоне');
function weirdNumbers(delta) {
  return 1 + delta - Math.random();
}

assert.approximately(weirdNumbers(0.5), 1, 0.5);
assert.approximately(weirdNumbers(0.2), 1, 0.8);

Проверка значения на массив

var menu = ['зеленый', 'чай', 'длинный'];
assert.isArray(menu, 'какой чай нам нужен?');

assert.isArray(
  'isThisAnArray?'.split(''),
  'String.prototype.split() возвращает массив'
);

var menu = 'зеленый|чай|длинный';
assert.isNotArray(menu, 'какой чай нам нужен?');

assert.isNotArray([1, 2, 3].indexOf(2), 'indexOf возвращает число.');

Нахождение значения в массиве, строке или объекте

assert.include([1, 2, 3], 2, 'массив содержит значение');
assert.include('лесной', 'лес', 'строка содержит подстроку');
assert.include(
  { foo: 'bar', hello: 'universe' },
  { foo: 'bar' },
  'объект содержит свойство'
);

Используется строгое равенство (===). Если утверждается, что значение включено в массив, выполняется поиск элемента, строго равного данному значению. Если утверждается подмножество свойств в объекте производится поиск объекта по заданным ключам свойств, проверяя, что каждый из них присутствует и строго равен заданному значению свойства. Например:

var obj1 = { a: 1 },
  obj2 = { b: 2 };
assert.include([obj1, obj2], obj1);
assert.include({ foo: obj1, bar: obj2 }, { foo: obj1 });
assert.include({ foo: obj1, bar: obj2 }, { foo: obj1, bar: obj2 });
assert.notInclude([1, 2, 3], 4, 'массив не содержит значение');
assert.notInclude('foobar', 'baz', 'строка не содержит подстроку');
assert.notInclude(
  { foo: 'bar', hello: 'universe' },
  { foo: 'baz' },
  'объект не содержит свойство'
);

Проверка значения на строку

var teaOrder = 'чай';
assert.isString(teaOrder, 'размещенный заказ');

var teaOrder = 4;
assert.isNotString(teaOrder, 'размещенный заказ');

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

assert.match('foobar', /^foo/, 'регулярное выражение совпадает');

assert.notMatch('foobar', /^foo/, 'регулярное выражение не совпадает');
var formatPeople = function (name, age) {
  return '# name: ' + name + ', age: ' + age + '\n';
};

var regex = /^#\sname\:\s[\w\s]+,\sage\:\s\d+\s?$/;
assert.match(formatPeople('John Doe', 35), regex);
assert.notMatch(formatPeople('Paul Smith III', 'twenty-four'), regex);

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

assert.property({ tea: { green: 'matcha' } }, 'tea');
assert.property({ tea: { green: 'matcha' } }, 'toString');
assert.notProperty({ tea: { green: 'matcha' } }, 'coffee');

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

assert.typeOf({ tea: 'chai' }, 'object', 'мы имеем объект');
assert.typeOf(['chai', 'jasmine'], 'array', 'мы имеем массив');
assert.typeOf('tea', 'string', 'мы имеем строка');
assert.typeOf(/tea/, 'regexp', 'мы имеем регулярное выражение');
assert.typeOf(null, 'null', 'мы имеем нуль');
assert.typeOf(undefined, 'undefined', 'мы имеем undefined');

assert.notTypeOf('tea', 'number', 'строки не являются числами');

Проверка, является ли объект экземпляром конструктора

var Tea = function (name) {
    this.name = name;
  },
  chai = new Tea('chai');

assert.instanceOf(chai, Tea, 'chai является экземпляром tea');

var Tea = function (name) {
    this.name = name;
  },
  chai = new String('chai');

assert.notInstanceOf(chai, Tea, 'chai не является экземпляром tea');

Есть и другие assert'ы, например: .isNaN(), .isBoolean(), и многие другие. Почти все assert'ы в библиотеке chai имеют свой отрицательный аналог - например: .isNotBoolean(). Более полная информация по API assert'ам находится здесь.