Yeda AI Tips · #085

English

100% de cobertura de tests es una señal de alerta, no una medalla

Cien por ciento de cobertura de tests es una señal de alerta, no una medalla. Martin Fowler lo dijo sin rodeos: sospecharía "de cualquier cosa cercana al 100% — olería a alguien escribiendo tests para dejar contentos los números de cobertura, sin pensar en lo que está haciendo". Cuando el número se vuelve la meta, los equipos escriben tests para getters, código de configuración y código generado — esfuerzo gastado exactamente donde no viven los bugs.

Qué mide la cobertura en realidad

La cobertura te dice qué líneas (o ramas) ejecutaron tus tests. No dice nada sobre si verificaron algo útil. Un test que llama a una función y no comprueba nada igual pinta sus líneas de verde. Por eso la cobertura sirve mejor como detector de código sin tests, no como puntaje de calidad: un número bajo es una advertencia real; un número alto prueba muy poco.

La división 80 / casi-100

En vez de una sola meta para toda la suite, divide tu código en dos niveles:

NivelMetaMétricaEjemplos
Todo~80%cobertura de sentenciashandlers, capa de UI, utilidades
Rutas críticascasi 100%cobertura de ramasauth, pagos, mutación de datos

El ~80% global mantiene la suite honesta sin forzar tests sobre código trivial. La meta de casi 100% de ramas va solo donde un caso borde perdido cuesta dinero real o datos reales: decisiones de autenticación y autorización, todo lo que mueve dinero, y cualquier código que muta estado persistente. El rango que el propio Fowler considera razonable para código bien probado es "80s altos o 90s" — alcanzado como consecuencia de testear bien, nunca impuesto como cuota.

Haz cumplir la división en CI, no en code review

Las herramientas modernas soportan umbrales por nivel directamente, así que la política es un archivo de configuración y no la memoria de un revisor. Jest acepta umbrales por glob — piso global, exigencia por ruta:

coverageThreshold: {
  global: { statements: 80 },
  './src/auth/':     { branches: 100 },
  './src/payments/': { branches: 100 },
}

Jest falla la corrida si cualquier nivel no llega a su propio número; los patrones se evalúan de forma independiente del piso global.

Python (coverage.py): activa la medición de ramas con coverage run --branch (o branch = true bajo [run] en la configuración), y define fail_under en la sección [report] — coverage sale con código 2 si el total queda por debajo. Corre una segunda configuración más estricta, acotada a tus paquetes críticos vía include, para exigir el nivel de casi 100%.

Movidas de usuario avanzado

La conclusión

La cobertura es una herramienta, no un trofeo. Apunta a aproximadamente 80% de cobertura de sentencias en toda la suite, exige casi 100% de cobertura de ramas en auth, pagos y mutación de datos, y conecta ambos niveles a CI para que el estándar se haga cumplir solo. Tus tests se concentran donde un bug de verdad duele — y dejas de inflar un número global en el que nadie debería confiar.

Recursos

Read this article in English

¿Construyendo una funcionalidad con IA? Yeda AI diseña, audita y entrega sistemas LLM en producción.

Habla con nosotros · Lee el blog