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

Ольга Змерзла

Существует три способа фронтенд-тестирования веб-приложений в JavaScript.

Вот они:

  • интеграционное;
  • функциональное или end-to-end (тестирование пользовательского интерфейса);
  • модульное.

Но если интеграционное и функциональное тестирования требуют полного разворачивания системы и настройки практически всех конфигураций, юнит-тесты позволяют проверять отдельные компоненты (модули) кода.

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

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

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

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

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

Проведем разработку приложения «Калькулятор» с модульным тестированием с помощью 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 + +y


module.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 + +y

const subtract = (x, y) => +x - +y

const multiply = (x, y) => +x * +y

const divide = (x, y) => +x / +y

module.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 used

7 passing (12ms)

1 failing
1) 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 used


8 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 globally

npm install mocha -g


# installs in the current directory

npm 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  и при тестировании в браузере код может вести себя иначе.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023