Карма родилась в эпоху AngularJS. Это было значительным улучшением существующих инструментов тестирования в Интернете и стало одной из причин распространения TDD в сообществе JavaScript. Karma по-прежнему лучшее средство запуска тестов для веб-JavaScript спустя почти 10 лет благодаря архитектуре и принципам, на которых она основана.

Давайте настроим его для тестового проекта и попробуем понять, как он работает. Первый шаг — установить его через NPM.

npm install karma

После успешной установки у нас будет бинарный файл Karma в локальной папке node_modules. Теперь давайте создадим файл конфигурации Karma для нашего проекта с помощью команды init

npx karma init

Здесь мы можем выбрать фреймворк для тестирования из списка популярных фреймворков, таких как Jasmine, Mocha и т. д. В нашем примере мы будем использовать Jasmine», поэтому просто нажмите [ Enter] для перехода к следующему вопросу.

Do you want to use Require.js ?
no

Require.js был популярен 10 лет назад для управления зависимостями, когда у нас не было Webpack. Сейчас это в основном рудимент, поэтому здесь мы выбираем [нет]

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome

Мы будем использовать Chrome в качестве браузера по умолчанию для наших тестов, потому что в настоящее время это один из популярных браузеров, который работает на большинстве операционных систем.

What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> src/**/*.test.js
> src/**/*.js

Здесь мы должны указать Karma, где мы храним исходный и тестовый файлы. В нашем примере мы будем использовать шаблон src/**/*.test.js для тестовых файлов, которые сейчас широко распространены, и src/**/*.js для исходных файлов.

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>

Оставляет его пустым

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes

Карму можно запускать в двух режимах: «одиночный запуск» или «наблюдение». Одиночный запуск означает, что когда тесты будут завершены, карма остановится, и для повторного запуска наших тестов мы должны снова запустить тесты вручную. В режиме «наблюдать» Karma автоматически перезапускала наши тесты, когда мы изменяли исходный или тестовый файлы. Эта очень удобная функция экономит наше время, поэтому здесь мы выбираем [да]

Config file generated at "/<project>/karma.conf.js".

Мы закончили настройку, и Карма говорит, что в результате получается файл karma.conf.js. Но это еще не все. Karma также установила необходимые зависимости на основе нашего выбора и обновила package.json.

+    "karma-chrome-launcher": "^3.1.0",
+    "karma-jasmine": "^4.0.1",

В нашем случае это были

  • karma-chrome-launcher плагин, который помогает запускать тесты в Chrome
  • karma-jasmine адаптер для жасмина

Karma имеет архитектуру плагинов. Большая часть специфичных для языка и фреймворков функций предоставляется плагинами. Сама Karma как бегун предоставляет только функциональность для запуска произвольного JavaScript в браузере через HTTP-сервер Karma. Кроме того, Karma дает вам возможность обрабатывать ваши тестовые и исходные файлы до того, как они будут отправлены в браузер. Грубо говоря, Karma является посредником между вашими тестовыми/исходными файлами, фреймворками, браузерами и операционной системой. Таким образом, эта архитектура позволяет карме делать только одну вещь, но делать это хорошо и быть открытой для расширения без изменения самого источника кармы. Я настоятельно рекомендую вам посмотреть это видео и посмотреть на сам Исходный код Karma как на пример хорошего продукта, выдержавшего испытание временем.

Вернемся к нашему тестовому проекту и завершим настройку Karma. Поскольку мы решили использовать Jasmine в качестве тестового фреймворка, мы должны установить и его.

npm install jasmine

karma-jasmine — это всего лишь адаптер Karma для самого Jasmine, поэтому мы должны установить Jasmine вместе с karma-jasmine.

Теперь мы готовы написать наш первый тест. Давайте создадим файл src/foo.test.js и напишем тестовый пример

describe('My first Karma test', function() {
  it('should be true', function() {
    expect(true).toEqual(true);
  });
});

Перед запуском Karma убедитесь, что у вас установлен Chrome, который мы выбираем в качестве браузера по умолчанию для тестов. Теперь мы готовы запустить наши тесты

npx karma start

Эта команда запустит сервер Karma, откроет браузер Chrome и запустит наши тесты. Результат тестов будет напечатан в терминале

30 01 2021 14:59:09.329:WARN [karma]: No captured browser, open http://localhost:9876/
30 01 2021 14:59:09.353:INFO [karma-server]: Karma v6.0.3 server started at http://localhost:9876/
30 01 2021 14:59:09.353:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
30 01 2021 14:59:09.358:INFO [launcher]: Starting browser Chrome
30 01 2021 14:59:10.799:INFO [Chrome 88.0.4324.96 (Mac OS 11.1.0)]: Connected on socket kj6wu3FYg7XPKEKCAAAB with id 15222593
Chrome 88.0.4324.96 (Mac OS 11.1.0): Executed 1 of 1 SUCCESS (0.002 secs / 0.002 secs)
TOTAL: 1 SUCCESS

Здесь можно заметить несколько интересных моментов

  1. Карма запускает сервер
  2. Откройте http://localhost:9876 в Chrome
  3. Запустите тесты и распечатайте результат

Когда тесты заканчивались, Karma не останавливалась и не ждала изменений, чтобы автоматически перезапускать тесты. Давайте изменим наш тест, чтобы увидеть, как он работает

it('should be true', function() {
  expect(true).toEqual(false);
});

А теперь посмотрите на результат

30 01 2021 15:02:37.443:INFO [filelist]: Changed file "/playground/src/foo.test.js".
Chrome 88.0.4324.96 (Mac OS 11.1.0) My first Karma test should be true FAILED
        Error: Expected true to equal false.
            at <Jasmine>
            at UserContext.<anonymous> (src/foo.test.js:3:18)
            at <Jasmine>
Chrome 88.0.4324.96 (Mac OS 11.1.0): Executed 1 of 1 (1 FAILED) (6.226 secs / 0.001 secs)
TOTAL: 1 FAILED, 0 SUCCESS

Вы можете видеть, что Karma автоматически перезапустила тест и сообщила нам, что теперь у нас есть 1 неудачный тест. Также результат содержит полезную информацию об ошибке. Сообщение об ошибке содержит

  • Имя набора тестов. В нашем случае My first Karma test
  • Имя тестового случая — test should be true
  • Сообщение об ошибке ожидания/подтверждения — Expected true to equal false
  • Трассировка стека исключений

Поскольку Karma запускает тесты внутри браузера, вы можете использовать инструменты разработчика браузера для отладки своих тестов. Для этого вы можете установить точку останова в тесте и открыть инструменты разработчика в Chrome. Также вы можете открыть страницу http://localhost:9876/debug, на которой тесты будут запускаться в главном окне и не выдавать результат в терминале. Если вы хотите запустить свои тесты в другом браузере, вы можете легко сделать это, не останавливая тесты и не изменяя конфигурацию, открыв http://localhost:9876/ в интересующем вас браузере. Он подключал браузер к серверу Karma и запускал на нем тесты. Этот подход также позволяет запускать тесты на любом устройстве и в любом браузере, просто открыв URL-адрес сервера Karma.

В порядке. Давайте исправим наш тест, вернувшись к предыдущему изменению. Чтобы остановить тесты, нажмите [Ctrl-C] в терминале, где работает Karma. Теперь давайте изменим конфигурационный файл Karma, чтобы тест по умолчанию запускался без «отслеживания». Для этого откройте karma.conf.js и измените singleRun с false на true

singleRun: true,

Теперь, если мы снова запустим тесты к npx karma start, вы увидите, что карма останавливается после завершения тестов. Для запуска тестов в режиме просмотра необходимо передать параметр --no-single-run

npx karma start --no-single-run

Когда карма работает в режиме наблюдения, вы можете перезапустить тесты без изменения исходных и тестовых файлов командой run. Для этого мы должны открыть новое окно терминала, не прерывая karma start процесса, и запустить

npx karma run

Эта команда в основном полезна для интеграции различных инструментов с Karma.

Теперь поговорим об исходных файлах. В примере выше мы добавили тестовый файл, который содержит всю логику внутри себя. Создадим файл src/foo.js и напишем функцию multiply

function multiply(x, y) {
  return x * y;
}

теперь изменим добавление теста внутри src/foo.test.js так, чтобы он проверял результат умножения функции

it('should multiply 2 on 2', function() {
  expect(multiply(2, 2)).toEqual(4);
});

Если вы не остановите сервер Karma, вы увидите, что он автоматически обнаруживает новый файл и тестирует его.

Chrome 88.0.4324.96 (Mac OS 11.1.0): Executed 2 of 2 SUCCESS (0.006 secs / 0 secs)
TOTAL: 2 SUCCESS

Теперь у нас есть два теста. Вы можете видеть, что функция multiply доступна в тестовом файле, потому что все файлы загружаются и выполняются в одном контексте (на одной странице). Мы не ограничивали видимость нашей функции multiply, поэтому она доступна глобально, и мы можем использовать ее в нашем тесте.

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