Karma — гибкий тестовый раннер для JavaScript, который изначально поставляется с базовым функционалом и поддержкой множества фреймворков и браузеров. Важным аспектом расширяемости Karma является возможность разработки собственных плагинов. Плагин может добавлять новые браузерные запускатели, препроцессоры, фреймворки, репортеры или middleware.
Плагин в Karma представляет собой обычный Node.js модуль, который
экспортирует объект или функцию через module.exports. Karma
использует систему dependency injection, поэтому любой плагин должен
быть зарегистрирован через механизм
module.exports = { 'name:type': factory }.
Структура объекта плагина:
module.exports = {
'type:name': ['factory', factoryFunction]
};
reporter, preprocessor, launcher,
framework, middleware).config, logger).Репортер отвечает за вывод информации о тестах. Минимальный пример:
const MyReporter = function(baseReporterDecorator, config, logger, helper) {
baseReporterDecorator(this);
this.onRunSt art = function(browsers) {
this.write('Тестирование началось\n');
};
this.onSpecCompl ete = function(browser, result) {
if (result.success) {
this.write(`Тест ${result.description} пройден\n`);
} else {
this.write(`Тест ${result.description} не пройден\n`);
}
};
this.onRunCompl ete = function(browsers, results) {
this.write(`Тестирование завершено: ${results.success} успешных, ${results.failed} неудачных\n`);
};
};
MyReporter.$inject = ['baseReporterDecorator', 'config', 'logger', 'helper'];
module.exports = {
'reporter:my-reporter': ['type', MyReporter]
};
Ключевые моменты:
baseReporterDecorator позволяет использовать
стандартные методы Karma для вывода и форматирования.onRunStart, onSpecComplete,
onRunComplete вызываются автоматически в ходе
тестирования.$inject определяет зависимости для DI, чтобы Karma
корректно передала необходимые объекты.Препроцессоры выполняют трансформацию файлов перед их подачей в браузер. Пример простого препроцессора для добавления комментария в каждый файл:
const myPreprocessor = function(logger, config, helper) {
const log = logger.create('preprocessor.my-preprocessor');
return function(content, file, done) {
log.debug(`Обработка файла: ${file.originalPath}`);
const processedContent = `// Добавлен комментарий\n${content}`;
done(processedContent);
};
};
myPreprocessor.$inject = ['logger', 'config', 'helper'];
module.exports = {
'preprocessor:my-preprocessor': ['factory', myPreprocessor]
};
Особенности:
Launcher отвечает за запуск браузеров. Пример простого headless-старта Chrome:
const MyLauncher = function(baseLauncherDecorator, args, logger) {
baseLauncherDecorator(this);
this._start = function() {
this._execCommand('google-chrome-headless', [
'--no-sandbox',
'--disable-gpu',
'--remote-debugging-port=9222'
]);
};
};
MyLauncher.$inject = ['baseLauncherDecorator', 'args', 'logger'];
module.exports = {
'launcher:my-chrome': ['type', MyLauncher]
};
Особенности:
baseLauncherDecorator предоставляет базовый функционал
для управления процессом._execCommand запускает процесс браузера с указанными
аргументами.package.json как обычный модуль Node.js.plugins:module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
files: ['test/**/*.spec.js'],
reporters: ['my-reporter'],
preprocessors: {
'src/**/*.js': ['my-preprocessor']
},
plugins: [
'karma-jasmine',
'karma-chrome-launcher',
require('./karma-my-plugin')
]
});
};
Особенности подключения:
reporter,
launcher, preprocessor) и регистрирует их по
имени.config.debug, info, warn,
error.Для проверки плагина создается отдельный тестовый проект с
минимальной конфигурацией Karma. Рекомендуется использовать стандартные
фреймворки тестирования (Jasmine, Mocha) для
написания unit-тестов, проверяющих:
onRunStart,
_start, препроцессор).Разработка собственного плагина позволяет полностью контролировать процесс тестирования и интегрировать Karma с уникальными инструментами сборки, браузерами и форматами отчетов. Правильная архитектура плагина обеспечивает легкость поддержки и расширяемость на годы вперед.