Знакомство с разработкой через тестирование в JavaScript
В этой статье мы научимся проводить юнит-тестирование в JavaScript, создав свой калькулятор. Тестировать будем с помощью фреймворка Mocha.
24К открытий25К показов
В этой статье мы познакомимся с разработкой через тестирование на примере простого приложения-калькулятора на Node.js. Тестировать будем с помощью фреймворка Mocha.
Что должно уметь наше приложение:
- Складывать, вычитать, делить и умножать любые два числа;
- Показывать предупреждение и завершать работу, если было введено что-то отличное от числа;
- Также должен быть интерфейс командной строки, чтобы конечный пользователь мог воспользоваться приложением.
Что нам потребуется:
- Node.js и npm;
- Знание JavaScript: синтаксис и структура кода, типы данных, математические операции и условные выражения.
С целями разобрались, можно приступать к настройке среды для тестирования и разработки.
Настраиваем среду
Так как мы используем Node.js, нужно создать локальное окружение для файлов и зависимостей.
Создайте новую папку calc. В командной строке перейдите в эту директорию и создайте новый проект командой npm init
, которая создаст новый файл package.json для нашей программы.
Вам предложат ввести имя пакета, версию, описание и прочую информацию о пакете. Вы можете ввести имя calc.js и дальше жать Enter для присвоения значений по умолчанию. Когда вы дойдёте до test command
, введите mocha
— это фреймворк для тестирования, который мы будем использовать:
После ввода всей информации скрипт создаст файл package.json, который выглядит примерно так:
Последний шаг на данном этапе — установка Mocha. Введите следующую команду для установки:
После применения этой команды появится папка node_modules, файл package-lock.json, а в файле package.json появятся следующие строки:
Мы добавили в наш проект тестирующий скрипт и зависимость. Пора убедиться, что тестирующий фреймворк работает как надо.
Создайте файл test.js. Мы воспользуемся встроенным в Node.js модулем assert, чтобы проверить верность равенства true
и true
. Так как оно верно, тест должен пройти успешно:
Теперь запустите тест из командной строки:
Тест прошёл как и ожидалось, поэтому с настройкой среды покончено. Удалите из test.js всё, кроме строки const assert = require('assert');
.
Мы будем использовать файл test.js на протяжении всего процесса создания приложения. Создайте ещё два файла: operations.js для арифметических и валидационных функций и calc.js для самого приложения. Мы используем так много файлов, чтобы они не становились слишком длинными и сложными. Вот наш текущий список файлов:
- calc.js;
- node_modules;
- operations.js;
- package-lock.json;
- package.json;
- test.js;
Давайте добавим первый настоящий тест для нашего приложения.
Добавляем математические операции
Прежде всего, наше приложение должно уметь складывать, вычитать, делить и умножать любые два числа. Значит, для каждой из этих операций мы должны создать отдельную функцию.
Начнём со сложения. Мы напишем тест, в котором однозначно получится ожидаемая сумма двух чисел. В коде ниже мы проверяем, равняется ли сумма 1 и 3 с помощью функции add()
4:
После запуска теста с помощью команды npm test
мы видим следующее:
Тест провалился с сообщением ReferenceError: add is not defined
. Мы тестируем функцию add()
, которой ещё нет, поэтому такой результат вполне ожидаем.
Создадим функцию add()
в файле operations.js:
Эта функция принимает два аргумента x
и y
и возвращает их сумму. Вы могли заметить, что мы пишем (+x) + (+y)
, а не x + y
. Мы используем унарный оператор для приведения аргумента к числу, на случай, если ввод будет строкой.
Примечание Здесь используется добавленная в ES6 стрелочная функция и неявный возврат.
Так как мы используем Node.js и разбиваем код на множество файлов, нужно воспользоваться module.exports
, чтобы экспортировать код:
В начале файла test.js мы импортируем код из operations.js с помощью require()
. Так как мы используем функцию через переменную operations
, нужно поменять add()
на operations.add()
:
Запускаем тест:
Теперь у нас есть работающая функция, и тесты проходят успешно. Так как функции других операций работают схожим образом, добавить тесты для subtract()
, multiply()
и divide()
не составит труда:
Теперь создадим и экспортируем все функции в test.js:
И запустим новые тесты:
Все тесты проходят успешно, поэтому теперь мы можем быть уверены, что основные функции нашего приложения будут работать корректно. Теперь можно заняться дополнительной валидацией.
Добавляем валидацию
На данный момент, когда пользователь вводит число и выбирает нужную операцию, всё работает нормально. Однако что случится, если попытаться найти сумму числа и строки? Приложение попытается выполнить операцию, но из-за того, что оно ожидает числа, оно вернёт NaN
.
Вместо того чтобы возвращать какие-то непонятные значения, пора выполнить вторую задачу — сделать так, чтобы приложение показывало предупреждение и завершало свою работу, если введённый аргумент не является числом.
Сначала нужно написать функцию, которая будет проверять, является ли ввод числом или нет. Приложение должно работать только с числами, поэтому мы будем обрабатывать три ситуации:
- Оба ввода — числа.
- Один ввод — число, а другой — строка.
- Оба ввода — строки.
Функция validateNumbers()
будет проверять оба параметра. Функция isNaN()
проверяет, не является ли параметр числом, и если нет, то возвращает false
. В противном случае она возвращает true
, что означает успешную валидацию.
Не забудьте добавить validateNumbers
в module.exports
в конце файла. Теперь можно запускать новые тесты:
Два теста прошли, но один провалился. Проверка на ввод двух чисел прошла успешно, так же как и проверка на ввод двух строк. Чего нельзя сказать о проверке на ввод строки и числа.
Если взглянуть на нашу функцию ещё раз, то можно заметить, что оба параметра должны быть NaN
, чтобы функция вернула false
. Если мы хотим добиться того же эффекта, когда хотя бы один из параметров равен NaN
, нужно заменить &&
на ||
:
Если после этих изменений снова запустить npm test
, то все тесты пройдут успешно:
Мы протестировали всю функциональность нашего приложения. Функции успешно выполняют математические операции и проверяют ввод. Финальный этап — создание пользовательского интерфейса.
Создаём интерфейс
Нужные функции у нас уже есть, но пользователь пока что никак не может ими воспользоваться. Поэтому нам нужен интерфейс. Для нашего приложения мы создадим интерфейс командной строки.
На данный момент файл calc.js должен быть пуст. Здесь и будет храниться наше приложение. Сначала нужно импортировать функции из operations.js:
Сам интерфейс будет использовать встроенный в Node.js CLI-модуль Readline:
После импортирования всего, что нужно, можно приступить к созданию приложения. Для создания интерфейса мы будем использовать readline
, доступный через переменную rl
:
Первое, что пользователь должен видеть после запуска программы, — приветственное сообщение и инструкции по использованию. Для этого мы воспользуемся console.log()
:
Прежде чем мы займёмся самими функциями калькулятора, давайте проверим, что console.log()
работает как надо. Мы сделаем так, чтобы программа выводила сообщение и завершала работу. Для этого добавьте в конце вызов метода rl.close()
.
Чтобы запустить приложение, введите node
и имя файла:
Программа выводит приветственное сообщение и завершает свою работу. Теперь нужно добавить пользовательский ввод. От пользователя требуется следующее: выбрать два числа и одну операцию. Каждый ввод будет запрашиваться методом rl.question()
:
Переменной x
присваивается первое число, y
— второе, а choice
— выбранная операция. Теперь наша программа запрашивает ввод, но ничего не делает с полученными данными.
После третьего ввода нужно проверить, что были введены только числа. Для этого воспользуемся функцией validateNumbers()
. С помощью оператора НЕ мы проверим, были ли введены числа, и, если это не так, завершим работу программы:
Если всё введено верно, то теперь нужно запустить соответствующий операции метод, созданный ранее. Для обработки четырёх возможных вариантов выбора мы воспользуемся выражением switch и выведем результат операции. Если была выбрана несуществующая операция, будет выполнен блок default
, сообщающий пользователю о необходимости повторить попытку:
Примечание Здесь в функциях console.log()
используются шаблонные строки, допускающие использование выражений.
Теперь наше приложение готово. Проверим его работу напоследок. Введём 999 и 1 и выберем операцию вычитания:
Программа успешно завершила свою работу, выведя правильный результат. Поздравляем, вы написали простой калькулятор с помощью Node.js и изучили основы TDD-разработки.
Исходный код приложения доступен на GitHub.
24К открытий25К показов