Back

Lo que realmente te dice la cobertura de código

Lo que realmente te dice la cobertura de código

Tu suite de pruebas pasa. Tu reporte de cobertura muestra 85%. El dashboard está verde. Pero, ¿ese número realmente significa que tu código funciona correctamente?

La cobertura de código es una de las métricas más visibles en las pruebas de frontend, pero frecuentemente se malinterpreta. Este artículo explica qué miden realmente las métricas de cobertura, por qué los porcentajes altos pueden ocultar brechas serias, y cómo interpretar estos números en proyectos JavaScript reales.

Puntos clave

  • La cobertura de código mide qué líneas se ejecutaron durante las pruebas, no si el código se comporta correctamente
  • La cobertura de ramas revela brechas que la cobertura de líneas no detecta, especialmente en lógica condicional
  • Los porcentajes altos de cobertura pueden crear falsa confianza cuando las pruebas carecen de aserciones significativas
  • Diferentes proveedores de cobertura (Istanbul vs V8) pueden reportar números distintos para código idéntico
  • Usa la cobertura como herramienta de diagnóstico para encontrar puntos ciegos, no como indicador de calidad

Lo que realmente mide la cobertura de código

La cobertura de código te dice una cosa: qué partes de tu código fuente se ejecutaron durante tu ejecución de pruebas. Eso es todo.

No te dice si el código se comportó correctamente. No confirma que tus aserciones detectaron bugs. No verifica que se manejaron casos extremos. Las herramientas de cobertura simplemente instrumentan tu código y rastrean lo que se ejecutó.

Cuando ejecutas jest --coverage o habilitas la cobertura en Vitest, la herramienta monitorea la ejecución y reporta porcentajes. Esos porcentajes representan ejecución, no corrección.

Entendiendo las métricas de cobertura de pruebas

La mayoría de las herramientas de cobertura de pruebas en JavaScript reportan varias métricas distintas. Cada una mide algo diferente.

La cobertura de líneas rastrea si cada línea de código fuente se ejecutó. La cobertura de sentencias cuenta las sentencias ejecutadas—lo cual difiere de las líneas cuando múltiples sentencias aparecen en una sola línea. La cobertura de funciones reporta si cada función fue llamada al menos una vez.

La cobertura de ramas va más profundo. Rastrea si cada ruta a través de la lógica condicional se ejecutó. Un bloque if/else tiene dos ramas. La cobertura de ramas requiere que ambas rutas se ejecuten.

Aquí es donde la distinción importa:

function getDiscount(user) {
  if (user.isPremium || user.hasPromo) {
    return 0.2
  }
  return 0
}

Una prueba con user.isPremium = true logra 100% de cobertura de líneas. Cada línea se ejecuta. Pero la cobertura de ramas revela la brecha: nunca probaste cuando isPremium es false pero hasPromo es true, o cuando ambos son false.

Por esto importa la diferencia entre cobertura de ramas vs cobertura de líneas. La cobertura de líneas puede alcanzar 100% mientras deja rutas lógicas completamente sin probar.

Por qué la cobertura alta puede ser engañosa

Una prueba que ejecuta código sin aserciones significativas infla la cobertura sin detectar bugs. Considera:

test('processes order', () => {
  processOrder(mockOrder)
  // No assertions
})

Esta prueba podría ejecutar docenas de líneas, aumentando tu porcentaje de cobertura. Pero no verifica nada. El código podría devolver valores incorrectos, lanzar errores capturados silenciosamente, o corromper el estado—y esta prueba aún pasaría.

Las herramientas de cobertura no pueden distinguir entre una prueba que valida exhaustivamente el comportamiento y una que simplemente ejecuta código. Ambas cuentan igual hacia tu porcentaje.

Proveedores de cobertura: por qué los números cambian

La cobertura de pruebas en JavaScript moderno depende de diferentes enfoques de instrumentación. Jest usa por defecto instrumentación estilo Istanbul, que transforma tu código antes de la ejecución. Vitest soporta tanto Istanbul como cobertura nativa basada en V8.

Estos proveedores pueden reportar números diferentes para código y pruebas idénticos. La cobertura V8 opera a nivel del motor y a veces cuenta la cobertura de manera diferente al enfoque de transformación de código de Istanbul.

Cambiar de proveedor, actualizar herramientas, o modificar la configuración puede alterar tu cobertura reportada sin ningún cambio de código. Esto no significa que un enfoque esté equivocado—miden cosas ligeramente diferentes en diferentes niveles.

Trata los números de cobertura como señales direccionales, no como mediciones precisas.

Dónde ayuda la cobertura y dónde engaña

La cobertura es útil para:

  • Identificar archivos o funciones completamente sin probar
  • Detectar código muerto que nunca se ejecuta
  • Encontrar ramas que olvidaste probar
  • Rastrear tendencias a lo largo del tiempo (cobertura que disminuye en código nuevo)

La cobertura engaña cuando:

  • Los equipos persiguen porcentajes en lugar de probar comportamientos
  • Las pruebas ejecutan código sin afirmar resultados
  • Los números altos crean falsa confianza en la calidad de las pruebas
  • Los umbrales presionan a los desarrolladores a escribir pruebas superficiales

Interpretando la cobertura en proyectos reales

Usa los reportes de cobertura como herramienta de diagnóstico, no como indicador de calidad. Cuando veas líneas sin cubrir, pregunta: ¿importa esta ruta de código? Si maneja errores, casos extremos, o lógica crítica, escribe pruebas para ella. Si es genuinamente inalcanzable o trivial, considera si el código debería existir en absoluto.

Revisa la cobertura junto con tus pruebas, no en lugar de ellas. Un archivo con 60% de cobertura y aserciones sólidas a menudo proporciona más confianza que uno con 95% de cobertura y pruebas débiles.

En revisiones de código, los diffs de cobertura ayudan a identificar si el código nuevo incluye pruebas. Pero la revisión en sí debe evaluar si esas pruebas verifican comportamiento significativo.

Haciendo que la cobertura funcione para tu equipo

Establece umbrales de cobertura de manera reflexiva. Un piso de 70-80% previene brechas obvias sin empujar a los equipos hacia teatro de cobertura. Más importante aún, enfócate en la cobertura de ramas para código con mucha lógica—detecta brechas que la cobertura de líneas no ve.

Ejecuta la cobertura en CI para rastrear tendencias, pero no falles builds por pequeñas caídas. La refactorización a menudo reduce temporalmente la cobertura cuando el código probado se elimina o reestructura.

Conclusión

El objetivo no es un número. Es la confianza de que tus pruebas detectan bugs reales antes de que lo hagan los usuarios. La cobertura te ayuda a encontrar puntos ciegos. El buen diseño de pruebas, las aserciones significativas, y las revisiones reflexivas determinan si realmente los llenas.

Preguntas frecuentes

La mayoría de los equipos apuntan a 70-80% como un piso razonable. Sin embargo, el porcentaje importa menos que lo que estás probando. Enfócate en cubrir rutas críticas, manejo de errores, y lógica de negocio. Un porcentaje menor con aserciones sólidas a menudo supera una cobertura alta con pruebas superficiales que carecen de verificación significativa.

Evita fallar builds por pequeñas caídas de cobertura. La refactorización a menudo reduce temporalmente la cobertura cuando el código probado se elimina o reestructura. En su lugar, usa las tendencias de cobertura para identificar patrones y revisa los diffs de cobertura en pull requests para asegurar que el código nuevo incluye pruebas apropiadas.

Diferentes proveedores de cobertura usan diferentes enfoques de instrumentación. Istanbul transforma el código antes de la ejecución mientras que V8 opera a nivel del motor. Estos enfoques miden cosas ligeramente diferentes, así que cambiar de proveedor o actualizar herramientas puede alterar los números reportados sin ningún cambio real de código.

Revisa tus aserciones, no solo tus números de cobertura. Las pruebas sin aserciones o con solo verificaciones triviales inflan la cobertura sin detectar bugs. Las herramientas de mutation testing pueden ayudar introduciendo pequeños cambios de código para verificar que tus pruebas realmente fallan cuando el comportamiento cambia inesperadamente.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay