Cobertura de código con pruebas en C#: de métricas a calidad

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Por qué las pruebas "verdes" no son aún una victoria?

\n\n

Imagine: escribió un centenar de pruebas unitarias, todas pasan con una marca verde, el pipeline de CI está feliz, el gerente está contento. Pero un mes después, una funcionalidad crítica falla en producción. ¿Le suena familiar? La mayoría de las veces, el problema es que probamos escenarios incorrectos o nos saltamos ramas enteras de código.

\n\n

La cobertura de código (code coverage) no es solo una métrica de moda para un informe. Es su linterna en la habitación oscura de la incertidumbre. Cuando empecé a trabajar con C#, pensaba que el 80% de cobertura era el ideal. Pero luego entendí: se puede tener un 100% de cobertura de líneas y aun así pasar por alto un error en la lógica de bifurcación. Por eso hoy analizaremos cómo medir correctamente la cobertura en C#, qué herramientas realmente ayudan y qué métricas vale la pena rastrear.

\n\n

¿Qué es la cobertura de código y por qué es importante para un desarrollador de C#?

\n\n

En términos simples, la cobertura de código muestra qué porcentaje del código fuente de su aplicación se ejecutó durante la ejecución de las pruebas. Si escribió una prueba que llama al método CalculateDiscount(), pero no verifica la rama if (isPremiumUser), entonces esa rama permanece "sin cubrir".

\n\n

Para un desarrollador de C#, la cobertura es un indicador de dos cosas:

\n
    \n
  • Confianza en la refactorización — ¿se puede cambiar el código sin miedo a romper algo?
  • \n
  • Integridad de las pruebas — ¿nos olvidamos de los casos límite?
  • \n
\n\n

Pero hay un matiz importante: la cobertura de código con pruebas en C# no garantiza la ausencia de errores. Solo indica que ciertas líneas fueron ejecutadas. Por eso no miramos solo el porcentaje, sino las métricas específicas.

\n\n

Métricas principales de cobertura de código en .NET

\n\n

Cuando ejecuta un análisis de cobertura en C#, se encuentra con varios tipos de métricas. Analicemos cada una con un ejemplo de código real.

\n\n

Line Coverage (cobertura de líneas)

\n

La métrica más simple. Cuenta cuántas líneas de código fueron alcanzadas por las pruebas. Ejemplo:

\n\n
public int Add(int a, int b)\n{\n    if (a < 0)          // línea 1\n        return 0;       // línea 2\n    return a + b;        // línea 3\n}
\n\n

Si su prueba llama a Add(5, 3), se ejecutarán las líneas 1 y 3. La línea 2 permanecerá sin cubrir. Line coverage mostrará un 66% (2 de 3 líneas).

\n\n

Branch Coverage (cobertura de bifurcaciones)

\n

Una métrica más honesta. Considera todas las rutas de ejecución posibles. En nuestro ejemplo, hay dos rutas: cuando a < 0 y cuando no. Si solo probó el caso con un número positivo, Branch coverage será del 50%.

\n\n

Precisamente Branch coverage a menudo revela "agujeros" en las pruebas. Recomiendo aspirar a un 80%+ específicamente en esta métrica.

\n\n

Cyclomatic Complexity y su relación con la cobertura

\n

Aunque no es una métrica de cobertura directa, la complejidad ciclomática muestra cuántas pruebas se necesitan escribir para una cobertura completa. Cuanto mayor sea la complejidad del método, más pruebas se requieren. Si ve un método con una complejidad ciclomática de 15 y una cobertura del 90%, probablemente no esté probando todos los escenarios.

\n\n

Herramientas para medir la cobertura de código en C#

\n\n

En el ecosistema .NET hay varias herramientas potentes. Hablaré de las tres más populares con las que he trabajado personalmente.

\n\n

Coverlet — gratuito e integrado en .NET

\n

Si usa .NET 6+, Coverlet ya está disponible a través de NuGet. Es mi herramienta favorita para CI/CD porque no requiere instalar programas adicionales.

\n\n

Instalación:

\n
dotnet add package coverlet.msbuild\ndotnet add package coverlet.collector
\n\n

Ejecución con informe:

\n
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
\n\n

Obtendrá un archivo coverage.opencover.xml que puede visualizar con ReportGenerator:

\n
dotnet tool install -g dotnet-reportgenerator-globaltool\nreportgenerat                

Blogs

Book Recommendations