Тестирование кода с помощью библиотеки Chai
Мне попалась переведенная с английского статья, в которой описываются 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(value, [message])- утверждает, что valueявляетсяnull; если это так, возвращаетmessage. Пример:
 
- утверждает, что 
assert.isNull(err, 'никакой ошибки не было');
- assert.isNotNull(value, [message])- утверждает, что valueне являетсяnull; если это так, возвращаетmessage. Пример:
 
- утверждает, что 
var tea = 'вкусный чай';
assert.isNotNull(tea, 'отлично, пора пить чай!');
Во все инструкции assert можно добавить второе необязательное сообщение. Оно будет включено в сообщения об ошибках, если assert не пройдет. Пример:
var tea = 'вкусный чай';
assert.isNotNull(tea, 'отлично, пора пить чай!', 'что-то пошло не так');
Проверка определения переменной или функции
- assert.isDefined(value, [message])- утверждает, что valueне являетсяundefined.
 
- утверждает, что 
var tea = 'чашка чая';
assert.isDefined(tea, 'чай уже был определен');
- assert.isUndefined(value, [message])- утверждает, что valueне определено.
 
- утверждает, что 
var tea;
assert.isUndefined(tea, 'tea не определен');
Использование assert.isOK и assert.isNotOK
- assert.isOk(object, [message])- будет проверять objectна истиное значение
 
- будет проверять 
assert.isOk('everything', 'все в порядке');
assert.isOk(false, 'это не сработает');
- assert.isNotOk(object, [message])- будет проверять на ложное значение.
 
assert.isNotOk('everything', 'это не сработает');
assert.isNotOk(false, 'это прокатит');
Тест на истиность
- assert.isTrue(value, [message])- будет тестировать на логическое значение true
 
var teaServed = true;
assert.isTrue(teaServed, 'чай уже подан');
еще примеры
assert.isTrue(true, 'тест пройдет с логическим значением true');
assert.isTrue('true', 'тест не пройдет со строковым значением 'true');
assert.isTrue(1, 'тест не пройдет с числовым значением 1');
- assert.isNotTrue(value, [message])
- тест пройдет, если задано что угодно, кроме логического значения true.
var tea = 'вкусный чай';
assert.isNotTrue(tea, 'отлично, пора пить чай!');
Использование нестрогого равенства и неравенства
- assert.equal(actual, expected, [message])- утверждает, что объекты actual и expected нестрого равны (==).
 
- утверждает, что объекты actual и expected нестрого равны (
assert.equal(3, '3', '== преобразует значения в строки');
- assert.notEqual(actual, expected, [message])- утверждает, что объекты actualиexpectedнестрого неравны (!=).
 
- утверждает, что объекты 
assert.notEqual(3, 4, 'эти числа не равны');
Использование строгого равенства и неравенства
- assert.strictEqual(actual, expected, [message])- утверждает, что объекты actualиexpectedстрого равны===.
 
- утверждает, что объекты 
assert.strictEqual(true, true, 'эти логические значения строго равны');
- assert.notStrictEqual(actual, expected, [message])- утверждает, что объекты actualиexpectedстрого неравны!==.
 
- утверждает, что объекты 
assert.notStrictEqual(3, '3', 'не является строгим равенством');
Глубокое сравнение с помощью .deepEqual и .notDeepEqual
- assert.deepEqual(actual, expected, [message])- утверждает, что объекты actualиexpectedполностью равны.
 
- утверждает, что объекты 
assert.deepEqual({ tea: 'green' }, { tea: 'green' });
- assert.notDeepEqual(actual, expected, [message])- утверждает, что объекты actualиexpectedполностью неравны.
 
- утверждает, что объекты 
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(valueToCheck, valueToBeAbove, [message])- утверждает, что valueToCheckбольше (>), чемvalueToBeAbove.
 
- утверждает, что 
assert.isAbove(5, 2, '5 строго больше чем 2');
assert.isAbove(Math.PI, 3, число ПИ больше чем 3);
- assert.isBelow(valueToCheck, valueToBeBelow, [message])- утверждает, что valueToCheckменьше (<), чемvalueToBeBelow.
 
- утверждает, что 
assert.isBelow(3, 6, '3 меньше, чем 6');
- assert.isAtMost(valueToCheck, valueToBeAtMost, [message])- утверждает, что valueToCheckменьше или равен (<=)valueToBeAtMost.
 
- утверждает, что 
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(valueToCheck, valueToBeAtLeast, [message])- утверждает, что valueToCheckбольше или равен (>=)valueToBeAtLeast.
 
- утверждает, что 
assert.isAtLeast(5, 2, '5 больше или равно 2');
assert.isAtLeast(3, 3, '3 больше или равно 3');
Проверка на попадание значения в определенный диапазон
- assert.approximately(actual, expected, delta, [message])- утверждает, что actualравенexpected, в пределах диапазона +/-delta.
 
- утверждает, что 
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);
Проверка значения на массив
- assert.isArray(value, [message])- утверждает, что value является массивом.
 
var menu = ['зеленый', 'чай', 'длинный'];
assert.isArray(menu, 'какой чай нам нужен?');
assert.isArray(
  'isThisAnArray?'.split(''),
  'String.prototype.split() возвращает массив'
);
- assert.isNotArray(value, [message])- утверждает, что value не является массивом.
 
var menu = 'зеленый|чай|длинный';
assert.isNotArray(menu, 'какой чай нам нужен?');
assert.isNotArray([1, 2, 3].indexOf(2), 'indexOf возвращает число.');
Нахождение значения в массиве, строке или объекте
- assert.include(haystack, needle, [message])- утверждает, что haystackвключает в себяneedle. Может использоваться для утверждения, что значение содержится в массиве, подстрока содержится в строке или подмножество свойств содержится в объекте.
 
- утверждает, что 
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(haystack, needle, [message])- утверждает, что haystackне включает в себяneedle. Может использоваться для утверждения отсутствия значения в массиве, подстроки в строке или подмножества свойств в объекте.
 
- утверждает, что 
assert.notInclude([1, 2, 3], 4, 'массив не содержит значение');
assert.notInclude('foobar', 'baz', 'строка не содержит подстроку');
assert.notInclude(
  { foo: 'bar', hello: 'universe' },
  { foo: 'baz' },
  'объект не содержит свойство'
);
Проверка значения на строку
- assert.isString(value, [message])- утверждает, что valueявляется строкой.
 
- утверждает, что 
var teaOrder = 'чай';
assert.isString(teaOrder, 'размещенный заказ');
- assert.isNotString(value, [message])- утверждает, что valueне является строкой.
 
- утверждает, что 
var teaOrder = 4;
assert.isNotString(teaOrder, 'размещенный заказ');
Использование регулярных выражений для проверки строк
- assert.match(value, regexp, [message])- утверждает, что valueсоответствует регулярному выражениюregexp.
 
- утверждает, что 
assert.match('foobar', /^foo/, 'регулярное выражение совпадает');
- assert.notMatch(value, regexp, [message])- утверждает, что valueне соответствует регулярному выражениюregexp.
 
- утверждает, что 
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(object, property, [message])- утверждает, что objectимеет прямое или наследуемое свойствоproperty.
 
- утверждает, что 
assert.property({ tea: { green: 'matcha' } }, 'tea');
assert.property({ tea: { green: 'matcha' } }, 'toString');
- assert.notProperty(object, property, [message])- утверждает, что objectне имеет прямого или наследуемого свойстваproperty.
 
- утверждает, что 
assert.notProperty({ tea: { green: 'matcha' } }, 'coffee');
Проверка значения на соответствие определенному типу структуры данных
- 
assert.typeOf(value, name, [message])- 
утверждает, что тип value- этоname, как определеноObject.prototype.toString.
- 
#typeOf утверждает, что тип значения - это заданная строка, определяемая Object.prototype.toString.
 
- 
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(value, name, [message])- утверждает, что тип value- это неname, как определеноObject.prototype.toString.
 
- утверждает, что тип 
assert.notTypeOf('tea', 'number', 'строки не являются числами');
Проверка, является ли объект экземпляром конструктора
- assert.instanceOf(object, constructor, [message])- утверждает, что objectявляется экземпляромconstructor.
 
- утверждает, что 
var Tea = function (name) {
    this.name = name;
  },
  chai = new Tea('chai');
assert.instanceOf(chai, Tea, 'chai является экземпляром tea');
- assert.notInstanceOf(object, constructor, [message])- утверждает, что objectне является экземпляромconstructor.
 
- утверждает, что 
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'ам находится здесь.
