Тестирование очень важно для поиска ошибок, проверки функциональности и повышения общей стабильности программного обеспечения. Почти все (если не все) разработчики тем или иным образом тестируют свой код. Один из способов тестирования - запустить программу вручную и опробовать все функции, чтобы убедиться, что все работает должным образом. Другой (и лучший) способ - написать автоматические тесты, которые запускаются каждый раз при изменении кода.

В Onsen UI мы проводим сквозное тестирование всех директив AngularJS с помощью Protractor, а также тестируем внутреннюю логику компонентов с помощью Karma test runner. Это помогает нам быстро находить и исправлять ошибки, а также значительно упрощает рефакторинг кода, не беспокоясь о том, что что-то сломается.

Недавно мы повторно реализовали все компоненты пользовательского интерфейса Onsen, используя ES6 (недавно переименованный в ES2015). Это создает некоторые проблемы при тестировании, поскольку большинство браузеров в настоящее время не поддерживают запуск кода ES6 напрямую, поэтому нам необходимо перенести его в ES5, чтобы браузер мог понять. В этой статье мы рассмотрим, как можно протестировать код ES6 с помощью Mocha, а также как сгенерировать покрытие для кода ES6 с помощью Istanbul. Chai.js используется для утверждений, но, конечно, вы можете использовать любую библиотеку утверждений, которая вам нравится. Для модульных тестов пользовательского интерфейса Onsen мы используем Chai.js, и нам это нравится!

Код, использованный в этой статье, доступен на моей странице GitHub.

Код для тестирования

Я предполагаю, что у вас уже установлены Node.js и npm. Если вы этого не сделаете, скачайте и установите их, прежде чем продолжить. Вы можете найти их на официальном сайте Node.js.

Начнем с создания нового проекта. Создайте пустой каталог и выполните следующую команду:

$ npm init

Он попросит вас ответить на кучу вопросов. Когда вы ответите на все вопросы, в текущем каталоге для вас будет создано package.json. Файл package.json содержит метаданные о модуле Node.js.

Следующим шагом будет написание кода для тестирования. Как упоминалось ранее, мы напишем его на ES6, поэтому люди, не знакомые с новыми дополнениями к языку JavaScript, могут почувствовать себя немного растерянными. Не волнуйтесь, я объясню новые ключевые слова в комментариях по ходу дела.

Мы создадим простой класс, описывающий прямоугольник, поэтому запустите ваш любимый редактор и создайте файл с именем rectangle.js.

Сохраните файл после того, как закончите его редактировать. Если на этом этапе вы попытаетесь выполнить его с помощью узла, вы получите сообщение об ошибке:

Если вы не получаете эту ошибку, вероятно, вы из будущего, где все функции ES6 уже реализованы. Как видно из сообщения об ошибке, он жалуется на использование ключевого слова class. В текущей реализации V8 class - зарезервированное слово, но функциональность еще не реализована. Это сделано для того, чтобы избежать поломки старого кода при окончательном добавлении классов в интерпретатор.

Написание модульных тестов с помощью Chai.js

Прежде чем мы начнем писать тесты, нам нужно установить Mocha и Chai.js. Нам также необходимо установить Babel, транспилятор, который переводит код ES6 в ES5, чтобы его можно было запускать в Node.js.

$ npm install --save-dev mocha chai babel

Mocha - это программа, которую мы используем для запуска тестов, а Chai.js - это библиотека, которую мы используем для написания тестовых утверждений. Chai.js реализует три разных стиля утверждения:

Должен

let chai = require('chai'); 
chai.should(); 
1.should.be.a('number');

Ожидать

var expect = require('chai').expect; 
expect(1).to.be.a('number');

Утверждать

let assert = require('chai').assert; 
assert.typeOf(1, 'number');

Какой из них вы выберете, - это вопрос ваших предпочтений. В этом руководстве я буду использовать should, так как считаю, что именно он дает самые чистые тесты.

Начнем с написания простого теста для атрибута width. Мы также будем писать тесты на ES6. Создайте каталог с именем test, создайте новый файл с именем rectangle.spec.js и введите следующий код.

Проведение тестов с Mocha

Давайте проведем тест и посмотрим, работает ли он! Сделайте это, набрав

# We have installed mocha locally in the project
.$ ./node_modules/.bin/mocha

Поскольку мы помещаем тестовый файл в каталог с именем test, Mocha найдет его автоматически. Однако тесты не сработают, и Node.js выдаст следующую ошибку:

Тесты написаны на ES6, и Node.js не может их выполнить. По этой причине мы установили Babel ранее. Mocha принимает параметр --compilers, чтобы мы могли указать ему использовать Babel для транспиляции кода перед запуском тестов:

Попробуем запустить его еще раз:

Большой! На этот раз тесты сработали. Однако еще не время праздновать. Нам также нужно добавить генерацию покрытия кода.

Создание покрытия с использованием Стамбула

Покрытие кода - это метрика, используемая для оценки того, насколько хорошо ваш код протестирован. Если часть программного обеспечения имеет 100% тестовое покрытие, это означает, что каждая строка выполняется хотя бы один раз в тестах. Один из самых популярных способов создания покрытия на JavaScript - использование библиотеки под названием Istanbul. Он выводит информацию о покрытии кода в командную строку, а также генерирует подробный отчет в формате HTML.

Начнем с установки Стамбула:

$ npm install --save-dev istanbul

Теперь мы можем создать отчет о покрытии кода, запустив:

Как видим, покрыто 80% линий в проекте. Стамбул также создает HTML-отчет в coverage/lcov-report/index.html. Откройте его в своем браузере, и мы увидим, какие строки не были закрыты.

Ну вот и бардак! Оказывается, поскольку мы используем параметр --compilers для переноса кода в ES5, код, для которого Стамбул генерирует покрытие, на самом деле является перенесенным кодом. Несмотря на то, что освещение было успешно создано, это не совсем то, что нам нужно.

Покрытие исходного кода ES6

Так как же нам получить покрытие для исходного кода ES6? Для этого мы хотим, чтобы сам Node.js мог выполнять код ES6. К счастью, с Babel есть простой способ сделать это. Когда вы устанавливаете Babel, он также добавляет скрипт с именем babel-node, который работает так же, как обычный исполняемый файл node, но перед его выполнением передает весь код через Babel. Однако этого недостаточно, поскольку Стамбул также должен понимать ES6. Для этого нам нужно установить модуль под названием isparta, который будет заменять команду istanbul.

$ npm install --save-dev isparta

Используя это, мы можем изменить команду запуска теста:

Это выводит неприятное сообщение об ошибке, но если мы посмотрим на код Mocha, это на самом деле не проблема, поскольку программа все равно завершалась на этой строке. Причина ошибки в том, что при использовании babel-node операторы возврата разрешены только внутри функций, тогда как в исходном коде Mocha есть оператор возврата во внешней области.

Несмотря на ошибку, похоже, что тесты были запущены, и отчет о покрытии был успешно сгенерирован. Давайте посмотрим на это!

Большой! Используя isparta и babel-node, мы смогли создать отчет о покрытии для кода ES6. Это значительно упрощает чтение отчета о покрытии.

Команда, используемая для запуска тестов, становится довольно длинной и запутанной. Чтобы не писать его каждый раз при запуске тестов, вы можете добавить его в свой package.json файл. Отредактируйте файл и добавьте следующую строку:

Таким образом, тесты можно запустить, просто выполнив:

$ npm test

Завершим тестирование, увеличив покрытие до 100%.

После добавления этих тестов мы рассмотрели каждую строку в наших тестах, поэтому мы получим следующее резюме.

Наконец, каждая строка покрыта, и мы создали хороший отчет о покрытии для кода ES6!

Заключение

Мы надеемся, что это руководство будет полезно для людей, которые начинают писать проекты с использованием ES6 и хотят иметь простой способ модульного тестирования и создания покрытия для своего кода. Пока мы рассмотрели только то, как это сделать для модуля Node.js, но в ближайшие недели мы также опубликуем статью о том, как тестировать код ES6 в браузере, что немного сложнее, но определенно выполнимо.

Удачного тестирования!

Первоначально опубликовано на сайте onsen.io 4 августа 2015 г.