Skip to content

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:

bash
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:

bunfig.toml
toml
[test]
# Habilitar cobertura siempre
coverage = true

Por 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.

bunfig.toml
toml
[test]
coverageSkipTestFiles = true  # por defecto false

Umbrales 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

bunfig.toml
toml
[test]
# Para requerir 90% de cobertura a nivel de línea y función
coverageThreshold = 0.9

Umbrales detallados

bunfig.toml
toml
[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.

bunfig.toml
toml
[test]
coverageReporter = ["text", "lcov"]  # por defecto ["text"]
coverageDir = "path/to/somewhere"    # por defecto "coverage"

Reportes disponibles

ReporteDescripción
textImprime un resumen textual de la cobertura en la consola
lcovGuarda 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.

bunfig.toml
toml
[test]
coverageReporter = "lcov"
bash
# O vía CLI
bun test --coverage --coverage-reporter=lcov

El 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

.github/workflows/test.yml
yaml
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.info

Excluir archivos de la cobertura

Omitir archivos de prueba

Por defecto, los archivos de prueba se incluyen en los informes de cobertura. Puedes excluirlos con:

bunfig.toml
toml
[test]
coverageSkipTestFiles = true  # por defecto false

Esto 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:

bunfig.toml
toml
[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

bunfig.toml
toml
[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.

bunfig.toml
toml
[test]
coverageIgnoreSourcemaps = true  # por defecto false

Valores 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

bunfig.toml
toml
[test]
coverageDir = "coverage-reports"  # por defecto "coverage"

Múltiples reportes

bunfig.toml
toml
[test]
coverageReporter = ["text", "lcov"]

Cobertura con patrones de prueba específicos

bash
# 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

.github/workflows/coverage.yml
yaml
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: true

Ejemplo de GitLab CI

.gitlab-ci.yml
yaml
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.info

Interpretar 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

test.ts
ts
// 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.ts
ts
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

bash
# 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.ts

Combinar 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.

test.ts
ts
// 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:

  1. Verifica que los source maps estén funcionando correctamente
  2. Verifica los patrones de archivos en coveragePathIgnorePatterns
  3. 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:

bunfig.toml
toml
[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.

Bun por www.bunjs.com.cn editar