Karma — это тестовый раннер для JavaScript, спроектированный для запуска тестов в реальных браузерах. Одной из ключевых особенностей его архитектуры является плагинная система, которая обеспечивает гибкость и расширяемость. Плагины позволяют интегрировать разные фреймворки, запускать тесты в различных браузерах, управлять отчетностью и настраивать поведение Karma без изменения ядра.
Архитектура Karma построена на нескольких типах плагинов:
Framework plugins Отвечают за интеграцию с тестовыми фреймворками, такими как Jasmine, Mocha или QUnit. Framework plugin предоставляет Karma API информацию о том, как запускать тесты и как собирать результаты.
// пример простого framework plugin
module.exports = {
'framework:custom': ['factory', function() {
return {
initialize: function(files) {
// обработка файлов тестов
}
};
}]
};Launcher plugins Управляют запуском браузеров для тестирования. Включают поддержку Chrome, Firefox, Safari, Edge и Headless-браузеров. Каждый launcher реализует интерфейс с методами запуска, завершения и перезапуска браузера.
module.exports = {
'launcher:ChromeHeadless': ['type', require('karma-chrome-launcher')]
};Reporter plugins Отвечают за вывод результатов тестов. Reporter может генерировать текстовый вывод в консоль, HTML-отчеты или интеграцию с CI/CD системами. Karma поддерживает плагины для JUnit, coverage, dot, spec и других форматов.
Preprocessor plugins Обрабатывают файлы перед запуском тестов. Это могут быть транспиляторы (Babel, TypeScript), сборщики модулей (Webpack) или генераторы исходного кода. Preprocessor получает путь к файлу, возвращает содержимое, готовое к выполнению в браузере.
Каждый плагин в Karma представляет собой объект, экспортируемый через
module.exports, где ключи описывают тип и название плагина,
а значения — реализацию. Основные элементы структуры:
framework, launcher,
reporter, preprocessor,
middleware.factory)
или класс с методами для взаимодействия с ядром Karma.Пример интеграции с системой зависимостей Karma:
module.exports = {
'preprocessor:custom': ['factory', function(config, logger) {
const log = logger.create('preprocessor.custom');
return function(content, file, done) {
log.info('Обработка файла: %s', file.originalPath);
// модификация содержимого
done(content.toUpperCase());
};
}]
};
Karma использует Dependency Injection (DI) для управления плагинами. При старте тестового раннера:
karma.conf.js.plugins или
автоматически найденные в node_modules.config, logger,
emitter и другие).DI обеспечивает слабую связанность между компонентами: любой новый launcher или reporter можно подключить без модификации ядра Karma.
Плагинная архитектура Karma позволяет:
Все плагины взаимодействуют с ядром через события,
передаваемые через объект emitter:
file_list_modified — изменение списка файлов
тестов.browser_start, browser_complete — запуск и
завершение браузера.run_start, run_complete — начало и
окончание тестового прогона.Это позволяет плагинам реагировать на события и управлять процессом тестирования динамически.
Для обеспечения совместимости и предсказуемого поведения плагинов рекомендуется:
logger.preprocessor:имя, reporter:имя и т.д.).Плагины могут комбинироваться и выстраивать цепочки обработки:
Такое взаимодействие делает архитектуру Karma модульной и расширяемой, позволяя построить сложные пайплайны тестирования без изменения ядра.
Архитектура плагинов Karma сочетает модульность, слабую связанность и событийную модель, что делает систему гибкой для различных сценариев тестирования JavaScript. Любой плагин можно подключить, заменить или расширить, не затрагивая внутренние механизмы раннера, что обеспечивает стабильность и предсказуемость при масштабировании тестовой инфраструктуры.