Módulo 15: Métricas de Calidad y Reportes

Objetivos del módulo

  • Comprender las métricas clave de testing
  • Medir y analizar la cobertura de código
  • Generar reportes profesionales con diferentes herramientas
  • Interpretar dashboards de calidad
  • Definir umbrales y criterios de aceptación

1. ¿Por qué medir?

📘 Concepto: “Lo que no se mide, no se puede mejorar” — Peter Drucker

Las métricas de testing nos permiten:

  • Conocer la salud real del proyecto
  • Tomar decisiones basadas en datos
  • Demostrar el valor del testing al equipo
  • Detectar tendencias (mejora o deterioro)

2. Métricas fundamentales

Métricas de ejecución

Métrica Fórmula Objetivo
Pass Rate Tests pasados / Total × 100 > 95%
Fail Rate Tests fallidos / Total × 100 < 5%
Tests ejecutados Ejecutados / Planificados × 100 100%
Tiempo de ejecución Duración total del suite Lo menor posible

Métricas de defectos

Métrica Descripción Objetivo
Defect Density Defectos / líneas de código (KLOC) < 5 por KLOC
Defect Removal Efficiency Defectos encontrados antes de producción / Total > 90%
Defect Leakage Defectos encontrados en producción / Total < 10%
Defect Aging Tiempo medio para resolver un defecto < 3 días
Reopen Rate Defectos reabiertos / Cerrados × 100 < 5%

Métricas de cobertura

Tipo Descripción
Line Coverage % de líneas ejecutadas por tests
Branch Coverage % de ramas (if/else) cubiertas
Method Coverage % de métodos ejecutados
Class Coverage % de clases con al menos un test
Condition Coverage % de condiciones booleanas evaluadas

3. Cobertura de código en .NET

Configurar Coverlet

# Coverlet viene integrado con dotnet test
dotnet test --collect:"XPlat Code Coverage"

Resultado: archivo coverage.cobertura.xml en la carpeta de resultados.

ReportGenerator

# Instalar
dotnet tool install -g dotnet-reportgenerator-globaltool

# Generar reporte HTML
reportgenerator \
  -reports:"**/coverage.cobertura.xml" \
  -targetdir:"CoverageReport" \
  -reporttypes:"Html;Badges;TextSummary"

Interpretar el reporte

Color Cobertura Significado
🟢 Verde > 80% Buena cobertura
🟡 Amarillo 60-80% Mejorable
🔴 Rojo < 60% Insuficiente

Ejemplo: salida de texto

Summary
  Generated on: 2024-12-15
  Assemblies:   3
  Classes:      25
  Files:        18
  Line coverage:    85.3%
  Branch coverage:  72.1%
  Method coverage:  91.2%

Excluir código de la cobertura

using System.Diagnostics.CodeAnalysis;

[ExcludeFromCodeCoverage]
public class Program
{
    // Main y configuración - no necesitan tests
}

[ExcludeFromCodeCoverage]
public class MigracionDatos
{
    // Código de migración one-time
}

4. Umbrales de calidad

Definir reglas del equipo

# quality-gates.yml (ejemplo de configuración de equipo)
coverage:
  minimum_line: 80           # % mínimo de líneas
  minimum_branch: 70         # % mínimo de ramas
  new_code_minimum: 90       # % mínimo en código nuevo

defects:
  max_critical_open: 0       # Cero críticos abiertos
  max_high_open: 3           # Máximo 3 altos abiertos
  max_defect_leakage: 5      # Máximo 5% fuga a producción

tests:
  pass_rate_minimum: 98      # % mínimo de pass
  max_execution_time: 300    # Segundos máximo para todo el suite

Quality Gate en CI/CD

# En GitHub Actions
- name: Verificar Quality Gate
  run: |
    COVERAGE=$(cat coverage-summary.txt | grep "Line coverage" | grep -oP '[\d.]+')
    PASS_RATE=$(dotnet test --no-build -v q 2>&1 | grep -oP 'Passed.*?(\d+)' | tail -1)

    echo "Cobertura: $COVERAGE%"

    if (( $(echo "$COVERAGE < 80" | bc -l) )); then
      echo "❌ QUALITY GATE FAILED: Cobertura < 80%"
      exit 1
    fi

    echo "✅ Quality Gate pasado"

5. Reportes con TRX (formato .NET)

# Generar reporte TRX
dotnet test --logger "trx;LogFileName=resultados.trx"

Publicar en GitHub Actions

      - name: Ejecutar tests
        run: dotnet test --logger "trx;LogFileName=resultados.trx" --results-directory TestResults

      - name: Publicar resultados
        uses: dorny/test-reporter@v1
        if: always()
        with:
          name: Test Results
          path: TestResults/*.trx
          reporter: dotnet-trx

Resultado: Un tab “Test Results” aparece en el Pull Request con los tests detallados.


6. Reportes con Allure

Configurar Allure con NUnit

dotnet add package Allure.NUnit
using Allure.NUnit;
using Allure.NUnit.Attributes;

[AllureNUnit]
[AllureSuite("Login")]
public class LoginTests
{
    [Test]
    [AllureFeature("Autenticación")]
    [AllureSeverity(SeverityLevel.Critical)]
    [AllureDescription("Verifica que un usuario válido puede iniciar sesión")]
    public void Login_CredencialesValidas_Acceso()
    {
        // Arrange
        var servicio = new AuthService();

        // Act
        var resultado = servicio.Login("admin", "Pass123!");

        // Assert
        Assert.That(resultado.Exito, Is.True);
    }

    [Test]
    [AllureFeature("Autenticación")]
    [AllureSeverity(SeverityLevel.Normal)]
    [AllureIssue("BUG-123")]
    [AllureLink("REQ-456", "https://jira.example.com/REQ-456")]
    public void Login_PasswordVacia_Error()
    {
        var servicio = new AuthService();
        var resultado = servicio.Login("admin", "");
        Assert.That(resultado.Exito, Is.False);
    }
}

Generar reporte Allure

# Instalar Allure CLI (con npm)
npm install -g allure-commandline

# Ejecutar tests (genera archivos en allure-results/)
dotnet test

# Generar y abrir reporte HTML
allure generate allure-results -o allure-report --clean
allure open allure-report

Secciones del reporte Allure

Sección Contenido
Overview Resumen general, gráfico de tendencia
Suites Tests organizados por suite/clase
Behaviors Tests por funcionalidad (Features/Stories)
Categories Agrupación de errores por tipo
Timeline Ejecución temporal de los tests
Graphs Gráficos de severidad, duración, estado
Packages Tests por paquete/namespace

7. Dashboard de métricas

Ejemplo de dashboard de equipo

┌──────────────────────────────────────────────────────┐
│              DASHBOARD DE CALIDAD - Sprint 15         │
├──────────────────────────────────────────────────────┤
│                                                      │
│  Tests Totales: 342    Pass Rate: 97.4%              │
│  ████████████████████░░  (333/342)                   │
│                                                      │
│  Cobertura Líneas: 84.2%                             │
│  ██████████████████░░░░                              │
│                                                      │
│  Cobertura Ramas: 71.8%                              │
│  ████████████████░░░░░░                              │
│                                                      │
│  Defectos Abiertos: 7 (2 High, 5 Medium)            │
│  Defect Leakage: 3.2%                                │
│  Tiempo Suite: 2m 34s                                │
│                                                      │
│  Tendencia (últimos 5 sprints):                      │
│  Pass Rate:  95% → 96% → 97% → 96% → 97.4% ↑       │
│  Cobertura:  78% → 80% → 82% → 83% → 84.2% ↑       │
│                                                      │
└──────────────────────────────────────────────────────┘

Métricas por tipo de test

Tipo Tests Pass Fail Skip Tiempo
Unit 280 278 2 0 45s
Integration 35 33 1 1 1m 20s
API 20 19 0 1 30s
UI 7 3 4 0 2m
Total 342 333 7 2 4m 35s

8. Antipatrones en métricas

Antipatrón Problema Solución
100% cobertura a toda costa Tests sin valor real Medir calidad, no solo cantidad
Ignorar tests fallidos Confianza falsa Arreglar o eliminar, nunca ignorar
Métricas de vanidad “Tenemos 1000 tests” pero no cubren lo importante Medir cobertura de requisitos críticos
No medir tendencia Un snapshot no dice nada Comparar sprint a sprint
Cobertura sin assertions Código ejecutado pero no verificado Revisar que los tests validen algo

9. Ejercicios

Ejercicio 1

Configura un proyecto .NET con tests unitarios y genera un reporte de cobertura HTML con ReportGenerator. Identifica las clases con menor cobertura.

Ejercicio 2

Añade anotaciones de Allure a un conjunto de tests existentes (Suite, Feature, Severity, Description). Genera el reporte y navega por las diferentes secciones.

Ejercicio 3

Define un Quality Gate para tu equipo con:

  • Cobertura mínima de líneas: 80%
  • Cobertura mínima de ramas: 70%
  • Pass rate: > 98%
  • Cero defectos críticos abiertos

Implementa la verificación en un workflow de GitHub Actions.

Ejercicio 4

Crea un dashboard (puede ser en Markdown) que muestre las métricas de un sprint ficticio. Incluye: pass rate, cobertura, defectos abiertos por severidad, y tendencia de los últimos 3 sprints.


Resumen

Concepto Descripción
Pass Rate % de tests que pasan
Line/Branch Coverage % de código ejecutado por tests
Defect Leakage Defectos que llegan a producción
ReportGenerator Genera reportes HTML de cobertura .NET
Allure Framework de reportes con dashboards ricos
Quality Gate Umbrales mínimos para aprobar un build
TRX Formato de resultados de tests de .NET