Юнит-тесты в JavaScript: инструменты и платформы

Юнит-тесты в JavaScript: инструменты и платформы

KOD

Главное преимущество юнит-тестов в том, что они делают проект более гибким. При добавлении новой функции старый код каждый раз необходимо редактировать и изменять. Изменение уже протестированного кода — дело затратное и достаточно рискованное. Модульные тесты позволяют исключить поломку старых функций при добавлении новых строк в код. Юнит-тест способен обнаружить ошибку в коде еще до того, как она попадет в продакшн. Вот почему модульное тестирование является одним из важных этапов веб-разработки.

Юниты в приложении

Юнит-тесты создаются для тестирования небольших участков кода. Такой участок не должен быть больше класса. Чаще всего тестам подвергаются отдельные методы класса или даже части методов.

Главная задача юнит-теста — проверить входные данные на соответствие ожидаемому результату работы. Юнит-тестирование обеспечивает стабильную работу каждой из частей программы. Очень желательно покрыть юнит-тестами весь код.

Проведем разработку приложения «Калькулятор» с модульным тестированием с помощью Node.js и Mocha.

Что приложение должно уметь:

  • делить, умножать, складывать и вычитать;
  • отображать предупреждения, если введенные значения не являются числовыми.

На старте разработки и тестирования необходимо настроить Node.js и npm. 

Создайте папку с именем calc. В командной строке создайте новый проект с помощью npm init. Здесь же создастся автоматически файл package.json.

$ npm init

Далее система предложит ввести имя, описание и другие сведения. Назовем файл calc.js, а в test command укажем mocha.

$ test command: mocha

Остальные значения можно оставить по умолчанию. В этом случае файл package.json будет иметь вид:

{ "name": "calc.js", "version": "1.0.0", "description": "A simple calculator application built with Node.js", "main": "index.js", "scripts": { "test": "mocha" }, "author": "", "license": "ISC"}

Далее произведем настройку Mocha. Команда для установки среды:

$ npm install --save-dev mocha

Добавятся директория node_modules и файл package-lock.json, а также код к package.json:

"devDependencies": { "mocha": "^4.0.1"}

Среда тестирования создана.

Теперь создадим файл test.js:

const assert = require('assert')it('should return true', () => { assert.equal(true, true)})

И запустим его в командной строке:

$ npm test

Результат:

> mocha ✓ should return true 1 passing (8ms)

Тест прошел. Значит, все сделано правильно. Из файла test.js необходимо удалить все, кроме первой строки:

const assert = require('assert')

Этот файл будет использоваться для тестирования приложения. Следует также создать два файла operations.js и calc.js.

Список файлов для работы, который в итоге должен получиться:

  • test.js;
  • package.json;
  • operations.js;
  • calc.js;
  • node_modules;
  • package-lock.json.

Тест для сложения:

const assert = require('assert')it('correctly calculates the sum of 1 and 3', () => { assert.equal(add(1, 3), 4)})

Тест проверяет, правда ли, что 1+3=4, в функции add(). В npm test получаем:

> mocha 0 passing (9ms) 1 failing 1) correctly calculates the sum of 1 and 3: ReferenceError: add is not defined at Context.it (test.js:5:16)npm ERR! Test failed. See above for more details.

В тестируемой функции add() ошибка — ReferenceError: add is not defined. Это логично, поскольку этой функции в коде еще не было.

В файле operations.js необходимо также создать функцию add():

const add = (x, y) => +x + +y

Для экспорта кода используется module.exports.

const add = (x, y) => +x + +ymodule.exports = { add }

Далее в начало файла test.js следует импортировать код operations.js с расширением require(). Поскольку функция внедряется через переменную operations, меняем add() на operations.add().

const operations = require('./operations.js')const assert = require('assert')it('correctly calculates the sum of 1 and 3', () => { assert.equal(operations.add(1, 3), 4)})

Запускаем тест:

$ npm test

Результат:

> mocha ✓ correctly calculates the sum of 1 and 3 1 passing (8ms)

Теперь все работает.

Принцип остальных арифметических функций тот же.

it('correctly calculates the sum of 1 and 3', () => { assert.equal(operations.add(1, 3), 4)})it('correctly calculates the sum of -1 and -1', () => { assert.equal(operations.add(-1, -1), -2)})it('correctly calculates the difference of 33 and 3', () => { assert.equal(operations.subtract(33, 3), 30)})it('correctly calculates the product of 12 and 12', () => { assert.equal(operations.multiply(12, 12), 144)})it('correctly calculates the quotient of 10 and 2', () => { assert.equal(operations.divide(10, 2), 5)})

Все функции экспортируем в operations.js.

const add = (x, y) => +x + +yconst subtract = (x, y) => +x - +yconst multiply = (x, y) => +x * +yconst divide = (x, y) => +x / +ymodule.exports = { add, subtract, multiply, divide,}

Запускаем эти тесты:

$ npm test

Результат:

> mocha ✓ correctly calculates the sum of 1 and 3 ✓ correctly calculates the sum of -1 and -1 ✓ correctly calculates the difference of 33 and 3 ✓ correctly calculates the product of 12 and 12 ✓ correctly calculates the quotient of 10 and 2 5 passing (8ms)

Все работает.

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

it('indicates failure when a string is used instead of a number', () => { assert.equal(operations.validateNumbers('sammy', 5), false)})it('indicates failure when two strings is used instead of numbers', () => { assert.equal(operations.validateNumbers('sammy', 'sammy'), false)})it('successfully runs when two numbers are used', () => { assert.equal(operations.validateNumbers(5, 5), true)})

Приложение принимает два числа и тест выполнит проверку, являются ли оба ввода числовыми. Функция isNaN() проверит введенные значения и при нечисловом вводе вернет false. Проверка считается успешной, если в итоге функция вернет true.

const validateNumbers = (x, y) => { if (isNaN(x) && isNaN(y)) { return false } return true}

Следует также убедиться, что validateNumbers добавлен в нижнюю часть module.exports, и запустить новые тесты.

$ npm test

Результат:

1) indicates failure when a string is used instead of a number✓ indicates failure when two strings is used instead of numbers✓ successfully runs when two numbers are used7 passing (12ms)1 failing1) indicates failure when a string is used instead of a number: AssertionError [ERR_ASSERTION]: true == false + expected - actual -true +false

Как видим, один из тестов не прошел. Изменим && на ||.

const validateNumbers = (x, y) => { if (isNaN(x) || isNaN(y)) { return false } return true}

И снова запустим npm test тест:

✓ indicates failure when a string is used instead of a number✓ indicates failure when two strings is used instead of numbers✓ successfully runs when two numbers are used8 passing (9ms)

Все прошло успешно.

Инструменты и платформы для модульного тестирования в JavaScript

  • Unit.js — фреймворк или библиотека утверждений для JS, которая работает как в браузере, так и в Node.js.
  • Mocha — многофункциональная среда тестирования JavaScript, которая применяется для асинхронного тестирования.
  • Jasmine — среда с чистым синтаксисом. Применяется для написания тестов без применения DOM.
  • Karma — среда для запуска тестов на реальных устройствах.
  • Jest — простой фреймворк для тестирования JavaScript. Не требует дополнительных настроек конфигураций и загрузки библиотек.
  • AVA — среда модульного тестирования и выполнения тестов в Node.js.
  • QUnit — универсальный фреймворк для проведения тестов в браузере, Node.js и даже внутри Web Worker.

Использование Node.js для модульного тестирования

Использование фреймворков позволяет упростить процесс создания юнит-тестов. Вот некоторые из таких фреймворков, которые используются в Node.js для запуска модульных тестов:

  • Mocha. Для установки этого фреймворка необходимо ввести в командной строке:

# Installs globallynpm install mocha -g# installs in the current directorynpm install mocha --save-dev

Для использования Mocha в приложении необходимо:

1. Создать папку с именем test в корневом разделе проекта.

2. В папке test создать файл test.js. Файл содержит код тестирования.

3. Открыть package.json и добавить строку в блоке скриптов:

"scripts": {"test": "mocha --recursive --exit"}

  • Jasmine. Фреймворк совместим с другими средами тестирования — Chai и Sinon. Его установка осуществляется с помощью команды:

npm install jasmine-node

Примечание. тестовые файлы должны быть с суффиксом *spec.js.

  • AVA. Минималистичный фреймворк со встроенной поддержкой асинхронных функций. Установка осуществляется с использованием команды:

npm init ava

  • Jest. Поддерживает параллельное выполнение тестов. Для максимизации производительности каждый тест здесь запускается в собственных процессах. Для установки фреймворка необходимо воспользоваться командой:

npm install --save-dev jest

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

Выполнение юнит-тестов в браузере

В браузере можно запускать юнит-тесты при использовании тестовых фреймворков, например, Karma или Mocha.

Важно понимать, что тесты обязательно нужно запускать в браузере. Это нужно для того, чтобы понимать, будет ли код корректно в нем работать. К тому же, при тестировании в Node.js и при тестировании в браузере код может вести себя иначе.


Report Page