Karma


🧪 Introducción a Karma

Karma es un test runner para JavaScript que ejecuta pruebas en navegadores reales, permitiendo automatizar y validar el comportamiento del código en distintos entornos. Fue diseñado originalmente para funcionar junto con jasmine, pero puede integrarse también con Mocha, QUnit u otros frameworks.

Su principal objetivo es proporcionar feedback rápido a los desarrolladores mientras escriben código, ejecutando los tests automáticamente cada vez que los archivos cambian.


⚙️ Configuración básica

Karma se controla mediante un archivo karma.conf.js, donde se definen:

  • Frameworks de testing a usar (por ejemplo, jasmine o mocha).
  • Archivos a incluir (scripts fuente y tests).
  • Navegadores a lanzar (Chrome, Firefox, Edge, Headless).
  • Reporters para mostrar resultados (por consola o en HTML).
  • Plugins adicionales (coverage, webpack, typescript, etc.).
  • Preprocesadores para transpilar o instrumentar código antes de ejecutar tests.

📄 Referencia: Karma - Configuration File


💻 Ejemplo de configuración

karma.conf.js

// Karma configuration file
module.exports = function(config) {
	config.set({
		frameworks: ['jasmine'],
		files: [
			'src/**/*.js',
			'test/**/*.spec.js'
		],
		reporters: ['progress'],
		browsers: ['ChromeHeadless'],
		singleRun: true,
		autoWatch: false,
		plugins: [
			'karma-jasmine',
			'karma-chrome-launcher',
			'karma-coverage'
		],
		preprocessors: {
			'src/**/*.js': ['coverage']
		},
		coverageReporter: {
			type: 'html',
			dir: 'coverage/'
		}
	})
}

`


🔄 Integración con herramientas de desarrollo

Karma se integra fácilmente en pipelines de CI/CD y herramientas de build:

  • Gulp o Grunt para ejecutar tests como tareas automatizadas.
  • Webpack o Rollup para preprocesar módulos ES6.
  • Angular CLI usa Karma + Jasmine por defecto en su sistema de testing.
  • Docker puede ejecutar Karma en entornos aislados para garantizar consistencia.

También puede vincularse con entornos de integración continua como:

  • GitHub Actions
  • Jenkins
  • GitLab CI
  • CircleCI

🧠 Conceptos clave

  • Test Runner: ejecuta y controla los tests, lanzando navegadores y mostrando resultados.
  • Browser Launchers: adaptadores que permiten correr los tests en diferentes navegadores.
  • Reporters: definen cómo se muestran los resultados (progress, dots, junit, coverage).
  • Preprocessors: transforman los archivos antes de testearlos (por ejemplo, TypeScript o Babel).
  • Coverage: análisis de cobertura de código mediante karma-coverage.

🧩 Ejemplo de integración con Jasmine

example.spec.js

describe('Calculator', function() {
	it('should add two numbers', function() {
		expect(1 + 2).toBe(3)
	})
})

Para ejecutarlo:

npx karma start

📘 Recurso: How to write unit tests with Jasmine & Karma-how-to-write-unit-tests-with-jasmine-karma-f1908bdeb617


⚡ Características avanzadas

  • Watch Mode: Karma puede vigilar archivos y ejecutar tests automáticamente al detectar cambios (autoWatch: true).
  • Headless Testing: ejecución sin interfaz gráfica, ideal para CI (ChromeHeadless).
  • Custom Launchers: configuración de navegadores remotos o móviles.
  • Code Coverage: con karma-coverage, genera reportes visuales y métricas.
  • Parallel Execution: mejora la velocidad dividiendo los tests entre varios navegadores.

🧱 Buenas prácticas

  • Mantén los tests unitarios aislados y deterministas.
  • Usa singleRun: true en entornos de integración continua.
  • Evita dependencias globales entre tests.
  • Configura coverage thresholds para mantener calidad mínima del código.
  • Usa Headless browsers en pipelines automáticos.
  • Asegura compatibilidad con múltiples navegadores antes de despliegues.

🔗 Recursos adicionales

Karma - Fundamentos avanzados y ecosistema


🧩 Ecosistema de Karma

Karma no funciona en solitario: su potencia radica en su integración con frameworks y herramientas del ecosistema JavaScript moderno. A continuación se detallan los componentes más relevantes que amplían su alcance.

Frameworks de Testing compatibles

  • Jasmine → API sencilla y legible (describe, it, expect).
  • Mocha → Más flexible y modular; requiere aserciones externas como Chai.
  • QUnit → Popular en entornos jQuery o proyectos legacy.
  • Angular Testing → Angular CLI lo incluye por defecto junto con Jasmine y karma.conf.js autogenerado.

Preprocesadores comunes

Permiten compilar o transformar código antes de ejecutar los tests:

  • karma-webpack → Soporte para módulos ES6 y bundling.
  • karma-typescript → Transpilación directa de TypeScript.
  • karma-babel-preprocessor → Integración con Babel para compatibilidad con ESNext.
  • karma-sourcemap-loader → Mantiene trazabilidad de errores originales.

⚙️ Cobertura de código y análisis de calidad

El plugin karma-coverage genera reportes que miden qué porcentaje del código fuente es cubierto por las pruebas.

Configuración de cobertura

coverageReporter: {
	reporters: [
		{ type: 'html', dir: 'coverage/' },
		{ type: 'text-summary' }
	],
	check: {
		global: {
			statements: 80,
			branches: 70,
			functions: 80,
			lines: 80
		}
	}
}

`

Integraciones útiles

  • SonarQube → lectura de reportes para control de calidad continua.
  • Istanbul → motor subyacente para instrumentación del código.
  • Allure Reports → reportes visuales avanzados.

🚀 Integración continua (CI/CD)

Karma se integra perfectamente en pipelines automatizados. Ejemplo básico para GitHub Actions:

name: Run Unit Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: npm ci
      - name: Run Karma Tests
        run: npx karma start --single-run --browsers ChromeHeadless

🔁 En Jenkins o GitLab CI se usa de forma análoga, ajustando el entorno y navegador.


⚡ Ejecución distribuida y rendimiento

Karma puede ejecutar tests en paralelo o en múltiples navegadores a la vez:

  • karma-parallel → divide tests entre procesos paralelos.
  • karma-sauce-launcher → ejecuta tests en navegadores reales de Sauce Labs.
  • karma-browserstack-launcher → integración con BrowserStack.

Esto permite validar compatibilidad multiplataforma sin necesidad de infraestructura propia.


🧠 Debugging y desarrollo local

Herramientas y técnicas

  • karma run → ejecuta tests sin reiniciar el servidor.
  • autoWatch: true → recompila y ejecuta automáticamente.
  • browserConsoleLogOptions → redirige logs del navegador a la terminal.
  • karma-spec-reporter → muestra resultados detallados por test.

💡 Consejo: usar Chrome normal (no Headless) durante el desarrollo permite depurar directamente con las DevTools.


🧱 Patrones de arquitectura de tests

  • AAA (Arrange, Act, Assert):

    1. Arrange: configurar entorno y dependencias.
    2. Act: ejecutar la función o acción.
    3. Assert: verificar los resultados esperados.
  • Fakes y Mocks: crear objetos simulados para aislar dependencias.
  • Test Pyramid: prioriza los unit tests (rápidos) sobre los E2E (lentos).
  • Fixture data: usar datos de prueba consistentes en distintos archivos.

🧰 Extensiones y plugins útiles

Plugin Descripción
karma-html-reporter Genera reportes navegables en HTML
karma-junit-reporter Exporta resultados en formato XML
karma-spec-reporter Muestra test por test en consola
karma-chrome-launcher Ejecución en Chrome/Headless
karma-firefox-launcher Ejecución en Firefox
karma-phantomjs-launcher Ejecución legacy sin GUI
karma-ng-html2js-preprocessor Compila templates de AngularJS
karma-json-reporter Exporta resultados como JSON

🧠 Casos de uso reales

  • Angular CLI: ejecuta ng test → Karma + Jasmine en ChromeHeadless.
  • Bibliotecas UI: testeo visual rápido con Storybook y Karma.
  • Proyectos híbridos: combinar Karma (unit) con Playwright o Cypress (E2E).
  • Microfrontends: ejecutar tests por módulo o componente de forma aislada.

🧩 Alternativas modernas

Aunque Karma sigue siendo útil, existen herramientas más modernas según el contexto:

  • Vitest → reemplazo ligero, compatible con Vite y Jest.
  • Jest → entorno completo, sin necesidad de navegador.
  • Playwright Test → pruebas E2E y de componentes en browsers reales.
  • Mocha + Chai → setups más flexibles para proyectos no basados en Angular.

📘 Aun así, Karma sigue siendo ideal en entornos que requieran compatibilidad multiplataforma y ejecución real en navegadores.


🔗 Recursos recomendados

Karma - Temas avanzados y optimización


🧩 Integración con TypeScript

Aunque Karma fue creado originalmente para JavaScript, su ecosistema soporta TypeScript mediante el plugin karma-typescript.
Esto permite compilar, ejecutar y generar cobertura sin necesidad de un bundler adicional.

Ejemplo de configuración

frameworks: ['jasmine', 'karma-typescript'],
files: [
	'src/**/*.ts',
	'tests/**/*.spec.ts'
],
preprocessors: {
	'**/*.ts': ['karma-typescript']
},
reporters: ['progress', 'karma-typescript'],
browsers: ['ChromeHeadless'],
singleRun: true

`

Ventajas:

  • Soporte completo para tsconfig.json.
  • Mapas de fuente (source maps) automáticos.
  • Reportes de cobertura adaptados a TypeScript.
  • Integración con Angular y Webpack sin configuración redundante.

🔒 Tests seguros y sandboxing

Karma ejecuta el código en navegadores reales, lo cual introduce posibles riesgos de acceso a recursos locales o APIs. Para mitigar esto:

  • Usa navegadores headless con configuraciones limitadas (--no-sandbox, --disable-gpu).
  • Configura customLaunchers con flags de seguridad.
  • Evita cargar archivos externos o dependencias no controladas.
  • Si se testean librerías que manipulan el DOM, restringe accesos con sandboxed iframes.

Ejemplo:

customLaunchers: {
	ChromeSandboxed: {
		base: 'ChromeHeadless',
		flags: ['--no-sandbox', '--disable-setuid-sandbox']
	}
}

🧠 Optimización del rendimiento de los tests

Karma puede volverse lento con grandes bases de código o múltiples navegadores. Buenas prácticas para acelerar:

  • Ejecutar en Headless Chrome o Firefox.
  • Desactivar autoWatch y singleRun: true en CI.
  • Usar karma-parallel para dividir tests entre procesos.
  • Reducir files y preprocessors a lo estrictamente necesario.
  • Ejecutar los tests más críticos primero (grep o fdescribe).
  • Combinar Karma con Vitest o Jest para aislar pruebas unitarias rápidas.

🔍 Depuración avanzada

Estrategias de debugging

  • browser: Chrome → abre ventana interactiva para inspeccionar errores.
  • debug.html → ejecuta los tests manualmente en http://localhost:9876/debug.html.
  • Breakpoints en DevTools → pausa en tests específicos.
  • console.log + Reporters detallados → trazabilidad paso a paso.
  • karma-mocha-reporter → visualización jerárquica y legible.

Configuración útil

logLevel: config.LOG_DEBUG,
colors: true,
browserConsoleLogOptions: {
	level: 'debug',
	format: '%b %T: %m',
	terminal: true
}

🧪 Testeo de componentes UI

Karma puede ejecutarse junto con librerías de UI:

  • Angular Testing Library → renderizado de componentes con DOM real.
  • React Testing Library → pruebas visuales con Webpack + Babel.
  • Vue Test Utils → integración con karma-webpack y vue-loader.

Ventajas:

  • Renderizado real del DOM.
  • Simulación de eventos de usuario (click, input, etc.).
  • Validación de estilos o layouts.

Ejemplo:

it('debería renderizar el botón con el texto correcto', () => {
	const button = document.querySelector('button')
	expect(button.textContent).toBe('Enviar')
})

🧰 Configuración modular y compartida

En proyectos grandes, es útil dividir la configuración de Karma por entorno:

  • karma.base.conf.js → Configuración común (frameworks, preprocessors).
  • karma.dev.conf.js → Para desarrollo (autoWatch, Chrome normal).
  • karma.ci.conf.js → Para integración continua (headless, cobertura).
  • karma.e2e.conf.js → Para pruebas de integración ligeras.
// karma.ci.conf.js
const baseConfig = require('./karma.base.conf')
module.exports = function(config) {
	config.set({
		...baseConfig,
		browsers: ['ChromeHeadless'],
		singleRun: true,
		reporters: [...baseConfig.reporters, 'coverage']
	})
}

🧮 Métricas y reporting avanzado

Karma permite generar múltiples tipos de reportes simultáneamente:

  • text → salida en consola.
  • html → exploración visual.
  • json o xml → integración con herramientas de análisis.
  • lcov → compatibilidad con Codecov y Coveralls.
  • junit → integración con Jenkins.

Configuración ejemplo:

reporters: ['progress', 'coverage', 'junit'],
junitReporter: {
	outputDir: 'test-results',
	outputFile: 'results.xml',
	useBrowserName: false
}

🔄 Testing multiplataforma

Karma puede integrarse con servicios en la nube para ejecutar pruebas en diferentes dispositivos y navegadores.

Ejemplos

  • BrowserStack → ejecución en navegadores móviles y de escritorio reales.
  • Sauce Labs → grid distribuido con logs, vídeos y screenshots.
  • LambdaTest → integración rápida con CI/CD para validación visual.

Configuración

browsers: ['Chrome', 'Firefox', 'Safari'],
customLaunchers: {
	BS_Chrome_Desktop: {
		base: 'BrowserStack',
		browser: 'chrome',
		os: 'Windows',
		os_version: '11'
	}
}

🧩 Karma en proyectos monorepo

Karma puede ejecutarse de forma aislada por paquete:

  • Integración con Nx o Lerna.
  • Configuración individual por paquete (packages/*/karma.conf.js).
  • Uso compartido de dependencias comunes (karma-base.conf.js).
  • Reportes consolidados mediante karma-merge-reports.

Esto facilita pruebas paralelas y modulares en entornos grandes.


🧠 Evolución y estado actual

Aunque Karma fue una herramienta central en la era de AngularJS, su rol ha evolucionado:

  • En entornos modernos (Vite, Next.js, Nuxt) tiende a ser reemplazado por Vitest o Jest.
  • Sigue siendo clave para entornos browser-first, como librerías UI o frameworks clásicos.
  • Angular (v17+) lo mantiene compatible, aunque ofrece soporte opcional para Jest.

💬 Conclusión técnica: Karma sigue siendo relevante cuando se requiere testing real en navegadores, soporte multiplataforma y reportes detallados, especialmente en entornos empresariales o CI robustos.


🔗 Enlaces complementarios