Архитектура Karma основывается на идее автоматизированного запуска тестов в реальных браузерах и получения результатов через канал обратной связи. Ключевым элементом выступает сервер, координирующий взаимодействие тестового окружения, браузеров и инфраструктуры сборки.
Karma Server управляет жизненным циклом тестового прогона: загрузкой файлов, конфигурацией, запуском браузеров и сбором результатов. Взаимодействие происходит через WebSocket-каналы и HTTP-эндпоинты. После запуска сервер открывает порты для подключения браузеров, которые превращаются в «агентов», исполняющих спецификации.
Браузерный агент представляет собой страницу, загружаемую в запущенный браузер. Она получает список тестовых файлов и скриптов раннера (например, Jasmine, Mocha или QUnit), исполняет тесты и отправляет результаты обратно на сервер. Благодаря такой архитектуре обеспечивается тестирование в реальных окружениях, включая особенности движков JavaScript и доменные ограничения.
Test Runner задаёт правила исполнения тестов.
Примером служит Jasmine, предоставляющий функции describe,
it, beforeEach и afterEach. Karma
не навязывает конкретный раннер, что делает систему гибкой.
Reporters формируют человекочитаемый вывод
результатов. Их набор и формат могут быть настроены в конфигурации.
Популярны progress, dots, junit и
другие.
Launchers отвечают за запуск браузеров. Есть встроенные лаунчеры для Chrome, Firefox и Edge, а также внешние адаптеры для Sauce Labs, BrowserStack и Headless-решений.
Karma полагается на WebSocket-соединение между сервером и браузерным агентом. Сообщения включают команды запуска тестов, события выполнения, статистику и ошибки. Двусторонний поток обеспечивает оперативное обновление статуса прогона.
Ключевые события:
Сервер получает список файлов из конфигурации
karma.conf.js. Они могут быть статическими или
генерируемыми через сборщики. Порядок подключения влияет на контекст
выполнения. Бандлеры, такие как Webpack, используются для подготовки
модулей перед отправкой браузеру. Karma принимает на вход уже собранный
пакет или участвует в pipeline через промежуточные плагины.
Пример конфигурации с Webpack:
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
files: ['spec/**/*.spec.js'],
preprocessors: {
'spec/**/*.spec.js': ['webpack']
},
webpack: {
mode: 'development'
},
browsers: ['ChromeHeadless']
});
};
Критичный аспект архитектуры — контроль таймингов. Karma отслеживает:
browserNoActivityTimeout);При превышении лимитов браузер может быть перезапущен, а прогон помечается как неуспешный. Это важно при CI-запусках и тестировании в распределённых средах.
Сервер запускается в headless-режиме, браузеры — через лаунчеры без UI. Результаты передаются репортерами в формате JUnit или аналогичном, что облегчает анализ. Архитектура Karma позволяет запускать несколько браузеров параллельно, что полезно для кросс-браузерной проверки.
Функциональность организована через систему плагинов. Каждый компонент — раннер, репортер, лаунчер, препроцессор — регистрируется как модуль. Это даёт возможность подключать сторонние решения и адаптироваться к нестандартным workflow.
Основные типы плагинов:
Исполнение тестов происходит в песочнице браузера. Переменные глобального контекста существуют отдельно для каждого агента. Это исключает взаимное влияние тестов из разных файлов, кроме случаев намеренного использования глобального состояния.
Karma обеспечивает детерминированность на уровне загрузки и запуска,
но не вмешивается в внутренние процессы браузера. Например, асинхронные
операции, связанные с таймерами или сетевыми запросами, зависят от
среды. Для контроля используют fake timers, mock-объекты и
interception уровнем раннера.
Сервер Karma не выполняет тесты сам и не интерпретирует JavaScript-код. Его задача — оркестрация, проксирование, синхронизация и сбор данных. Исполнение всегда происходит в браузере. Это позволяет моделировать реальные пользовательские сценарии и выявлять проблемы рендеринга, таймингов и совместимости.
Архитектура поддерживает режимы с открытыми браузерами, когда возможно подключение к DevTools. Агент тестов остаётся активным, а результаты отправляются после завершения раннера. Важный аспект — возможность ручной навигации или паузы в момент выполнения.
Основные стадии:
Эта модель применяется как для единичного запуска, так и для режима
watch, когда сервер отслеживает изменения файлов и
инициирует повторный прогон.
При большом количестве тестов важна оптимизация:
В распределённых CI-средах возможно вынесение браузеров на удалённые машины или сервисы совместимости, сохранив при этом модель двустороннего обмена сообщениями.
Такое устройство обеспечивает гибкий и воспроизводимый процесс тестирования, адаптируемый под различные проекты и инфраструктуры.