El ejecutor de pruebas de Bun ahora admite informes de cobertura de código integrados. Esto facilita ver cuánto del código está cubierto por las pruebas y encontrar áreas que actualmente no están bien probadas.
Habilitar cobertura
bun:test admite ver qué líneas de código están cubiertas por las pruebas. Para usar esta función, pasa --coverage a la CLI. Imprimirá un informe de cobertura en la consola:
bun test --coverage
-------------|---------|---------|-------------------
File | % Funcs | % Lines | Uncovered Line #s
-------------|---------|---------|-------------------
All files | 38.89 | 42.11 |
index-0.ts | 33.33 | 36.84 | 10-15,19-24
index-1.ts | 33.33 | 36.84 | 10-15,19-24
index-10.ts | 33.33 | 36.84 | 10-15,19-24
index-2.ts | 33.33 | 36.84 | 10-15,19-24
index-3.ts | 33.33 | 36.84 | 10-15,19-24
index-4.ts | 33.33 | 36.84 | 10-15,19-24
index-5.ts | 33.33 | 36.84 | 10-15,19-24
index-6.ts | 33.33 | 36.84 | 10-15,19-24
index-7.ts | 33.33 | 36.84 | 10-15,19-24
index-8.ts | 33.33 | 36.84 | 10-15,19-24
index-9.ts | 33.33 | 36.84 | 10-15,19-24
index.ts | 100.00 | 100.00 |
-------------|---------|---------|-------------------Habilitar por defecto
Para habilitar siempre los informes de cobertura por defecto, agrega la siguiente línea a tu bunfig.toml:
[test]
# Habilitar cobertura siempre
coverage = truePor defecto, los informes de cobertura incluirán archivos de prueba y excluirán los sourcemaps. Esto es usualmente lo que deseas, pero puede configurarse de otra manera en bunfig.toml.
[test]
coverageSkipTestFiles = true # por defecto falseUmbrales de cobertura
Es posible especificar un umbral de cobertura en bunfig.toml. Si tu suite de pruebas no alcanza o supera este umbral, bun test saldrá con un código de salida distinto de cero para indicar el fallo.
Umbral simple
[test]
# Para requerir 90% de cobertura a nivel de línea y función
coverageThreshold = 0.9Umbrales detallados
[test]
# Para establecer diferentes umbrales para líneas y funciones
coverageThreshold = { lines = 0.9, functions = 0.9, statements = 0.9 }Establecer cualquiera de estos umbrales habilita fail_on_low_coverage, haciendo que la ejecución de pruebas falle si la cobertura está por debajo del umbral.
Reportes de cobertura
Por defecto, los informes de cobertura se imprimirán en la consola.
Para informes de cobertura persistentes en entornos CI y para otras herramientas, puedes pasar una opción --coverage-reporter=lcov a la CLI o la opción coverageReporter en bunfig.toml.
[test]
coverageReporter = ["text", "lcov"] # por defecto ["text"]
coverageDir = "path/to/somewhere" # por defecto "coverage"Reportes disponibles
| Reporte | Descripción |
|---|---|
text | Imprime un resumen textual de la cobertura en la consola |
lcov | Guarda la cobertura en formato lcov |
Reporte de cobertura LCOV
Para generar un informe lcov, puedes usar el reporte lcov. Esto generará un archivo lcov.info en el directorio de cobertura.
[test]
coverageReporter = "lcov"# O vía CLI
bun test --coverage --coverage-reporter=lcovEl formato LCOV es ampliamente soportado por varias herramientas y servicios:
- Editores de código: Las extensiones de VS Code pueden mostrar la cobertura en línea
- Servicios CI/CD: GitHub Actions, GitLab CI, CircleCI
- Servicios de cobertura: Codecov, Coveralls
- IDEs: WebStorm, IntelliJ IDEA
Usando LCOV con GitHub Actions
name: Prueba con cobertura
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun test --coverage --coverage-reporter=lcov
- name: Subir cobertura a Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.infoExcluir archivos de la cobertura
Omitir archivos de prueba
Por defecto, los archivos de prueba se incluyen en los informes de cobertura. Puedes excluirlos con:
[test]
coverageSkipTestFiles = true # por defecto falseEsto excluirá los archivos que coincidan con patrones de prueba (por ejemplo, *.test.ts, *.spec.js) del informe de cobertura.
Ignorar rutas y patrones específicos
Puedes excluir archivos específicos o patrones de archivos de los informes de cobertura usando coveragePathIgnorePatterns:
[test]
# Patrón único
coveragePathIgnorePatterns = "**/*.spec.ts"
# Múltiples patrones
coveragePathIgnorePatterns = [
"**/*.spec.ts",
"**/*.test.ts",
"src/utils/**",
"*.config.js"
]Esta opción acepta patrones glob y funciona de manera similar a los patrones de omisión de collectCoverageFrom de Jest. Los archivos que coincidan con cualquiera de estos patrones se excluirán del cálculo e informe de cobertura tanto en salidas de texto como LCOV.
Casos de uso comunes
[test]
coveragePathIgnorePatterns = [
# Excluir archivos de utilidad
"src/utils/**",
# Excluir archivos de configuración
"*.config.js",
"webpack.config.ts",
"vite.config.ts",
# Excluir patrones de prueba específicos
"**/*.spec.ts",
"**/*.e2e.ts",
# Excluir artefactos de compilación
"dist/**",
"build/**",
# Excluir archivos generados
"src/generated/**",
"**/*.generated.ts",
# Excluir código de terceros/vendor
"vendor/**",
"third-party/**"
]Sourcemaps
Internamente, Bun transpila todos los archivos por defecto, así que Bun genera automáticamente un mapa de origen interno que mapea líneas de tu código fuente original a la representación interna de Bun. Si por alguna razón deseas deshabilitar esto, establece test.coverageIgnoreSourcemaps a true; esto raramente será deseable fuera de casos de uso avanzados.
[test]
coverageIgnoreSourcemaps = true # por defecto falseValores por defecto de cobertura
Por defecto, los informes de cobertura:
- Excluyen directorios
node_modules - Excluyen archivos cargados mediante loaders que no sean JS/TS (por ejemplo,
.css,.txt) a menos que se especifique un loader JS personalizado - Incluyen los archivos de prueba mismos (puede deshabilitarse con
coverageSkipTestFiles = true) - Pueden excluir archivos adicionales con
coveragePathIgnorePatterns
Configuración avanzada
Directorio de cobertura personalizado
[test]
coverageDir = "coverage-reports" # por defecto "coverage"Múltiples reportes
[test]
coverageReporter = ["text", "lcov"]Cobertura con patrones de prueba específicos
# Ejecutar cobertura solo en archivos de prueba específicos
bun test --coverage src/components/*.test.ts
# Ejecutar cobertura con patrón de nombre
bun test --coverage --test-name-pattern="API"Integración CI/CD
Ejemplo de GitHub Actions
name: Informe de cobertura
on: [push, pull_request]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Instalar dependencias
run: bun install
- name: Ejecutar pruebas con cobertura
run: bun test --coverage --coverage-reporter=lcov
- name: Subir a Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
fail_ci_if_error: trueEjemplo de GitLab CI
test:coverage:
stage: test
script:
- bun install
- bun test --coverage --coverage-reporter=lcov
coverage: '/Lines\s*:\s*(\d+.\d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/lcov.infoInterpretar informes de cobertura
Explicación de salida de texto
-------------|---------|---------|-------------------
File | % Funcs | % Lines | Uncovered Line #s
-------------|---------|---------|-------------------
All files | 85.71 | 90.48 |
src/ | 85.71 | 90.48 |
utils.ts | 100.00 | 100.00 |
api.ts | 75.00 | 85.71 | 15-18,25
main.ts | 80.00 | 88.89 | 42,50-52
-------------|---------|---------|-------------------- % Funcs: Porcentaje de funciones que fueron llamadas durante las pruebas
- % Lines: Porcentaje de líneas ejecutables que fueron ejecutadas durante las pruebas
- Uncovered Line #s: Números de línea específicos que no fueron ejecutados
Qué objetivo tener
- 80%+ de cobertura general: Generalmente considerado como bueno
- 90%+ rutas críticas: La lógica de negocio importante debe estar bien probada
- 100% funciones de utilidad: Las funciones puras y utilidades son fáciles de probar completamente
- Menor cobertura para componentes UI: A menudo aceptable ya que pueden requerir pruebas de integración
Mejores prácticas
Enfocarse en la calidad, no solo en la cantidad
// Bueno: Probar funcionalidad real
test("calculateTax debería manejar diferentes tasas de impuesto", () => {
expect(calculateTax(100, 0.08)).toBe(8);
expect(calculateTax(100, 0.1)).toBe(10);
expect(calculateTax(0, 0.08)).toBe(0);
});
// Evitar: Solo tocar líneas para cobertura
test("calculateTax existe", () => {
calculateTax(100, 0.08); // ¡Sin aserciones!
});Probar casos borde
test("validación de entrada de usuario", () => {
// Probar caso normal
expect(validateEmail("user@example.com")).toBe(true);
// Probar casos borde que mejoran significativamente la cobertura
expect(validateEmail("")).toBe(false);
expect(validateEmail("invalid")).toBe(false);
expect(validateEmail(null)).toBe(false);
});Usar cobertura para encontrar pruebas faltantes
# Ejecutar cobertura para identificar código no probado
bun test --coverage
# Ver archivos específicos que necesitan atención
bun test --coverage src/critical-module.tsCombinar con otras métricas de calidad
La cobertura es solo una métrica. También considera:
- Calidad de revisión de código
- Cobertura de pruebas de integración
- Pruebas de manejo de errores
- Pruebas de rendimiento
- Seguridad de tipos
Solución de problemas
La cobertura no se muestra para algunos archivos
Si los archivos no aparecen en los informes de cobertura, puede que no estén siendo importados por tus pruebas. La cobertura solo rastrea archivos que son realmente cargados.
// Asegúrate de importar los módulos que deseas probar
import { myFunction } from "../src/my-module";
test("mi función funciona", () => {
expect(myFunction()).toBeDefined();
});Informes de cobertura falsos
Si ves informes de cobertura que no coinciden con tus expectativas:
- Verifica que los source maps estén funcionando correctamente
- Verifica los patrones de archivos en
coveragePathIgnorePatterns - Asegúrate de que los archivos de prueba estén realmente importando el código a probar
Problemas de rendimiento con bases de código grandes
Para proyectos grandes, la recopilación de cobertura puede ralentizar las pruebas:
[test]
# Excluir directorios grandes que no necesitas cubrir
coveragePathIgnorePatterns = [
"node_modules/**",
"vendor/**",
"generated/**"
]Considera ejecutar la cobertura solo en CI o ramas específicas en lugar de cada ejecución de pruebas durante el desarrollo.