Orquesta Agentes IA que desarrollan por ti
Verificando...
36-flaky-tests-detection
Procedimiento: Flaky Tests Detection
Calidad de Codigo
1 plugin(s)
Editor
Preview
Tareas
1
Info
Titulo
Identifica tests flaky (intermitentes). Analiza patrones de fallos aleatorios, sugiere correcciones, y prioriza tests a estabilizar.
Descripcion
Contenido Markdown
9720 caracteres
Guardar
# Procedimiento: Flaky Tests Detection ## Metadata - **ID**: PROC-36 - **Frecuencia**: Semanal - **Duraci├│n estimada**: 20-30 min - **Requiere**: Acceso a historial de CI/CD - **Dependencias**: PROC-23 (Pipeline Health) - **Bloquea**: Ninguno (pero afecta confianza en CI) - **Agentes**: dotnet-architect --- ## Objetivo Detectar y corregir tests inestables (flaky): 1. Identificar tests que fallan intermitentemente 2. Analizar causas ra├¡z (timing, orden, estado compartido) 3. Priorizar correcciones 4. Mejorar confiabilidad del pipeline --- ## ┬┐Qu├® es un Flaky Test? Test que **a veces pasa y a veces falla** con el mismo c├│digo. **Causas comunes:** - Race conditions / timing issues - Dependencia del orden de ejecuci├│n - Estado compartido entre tests - Dependencias externas (red, BD, tiempo) - Tests que dependen de datos de otros tests --- ## Umbrales | M├®trica | Aceptable | Warning | Cr├¡tico | |---------|-----------|---------|---------| | Flaky rate | <1% | 1-5% | >5% | | Tests flaky | <3 | 3-10 | >10 | | Reruns necesarios | 0 | 1 | >1 | --- ## Checklist Ejecutable ### 1. Recopilar Historial de Tests #### GitLab CI ```bash # Obtener resultados de tests de ├║ltimos 20 pipelines for pipeline in $(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/pipelines?status=success&per_page=20" | \ jq -r '.[].id'); do # Obtener job de tests test_job=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/pipelines/$pipeline/jobs" | \ jq -r '.[] | select(.name | contains("test")) | .id') # Descargar artifacts con resultados curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/jobs/$test_job/artifacts" \ -o "results_$pipeline.zip" done ``` - [ ] Historial recopilado: ___ pipelines ### 2. Analizar Resultados de Tests (.NET) ```bash # Si usas TRX (Visual Studio Test Results) for trx in results/*.trx; do # Extraer tests fallidos grep -E "<UnitTestResult.*outcome=\"Failed\"" "$trx" | \ grep -oE "testName=\"[^\"]+\"" | \ cut -d'"' -f2 >> failed_tests.txt done # Contar ocurrencias de cada test fallido sort failed_tests.txt | uniq -c | sort -rn | head -20 ``` **Formato de salida:** ``` 5 OrderService_WhenConcurrent_ShouldHandle 4 PaymentTests_ProcessAsync_Timeout 3 IntegrationTests_Database_Connection ``` - [ ] Tests fallidos frecuentemente identificados ### 3. Calcular Flaky Rate ```bash # Para cada test, calcular tasa de fallo total_runs=20 while read count test; do rate=$(echo "scale=2; $count * 100 / $total_runs" | bc) echo "$rate% - $test ($count/$total_runs)" done < <(sort failed_tests.txt | uniq -c | sort -rn) ``` **Clasificaci├│n:** | Test | Fallos | Rate | Tipo | |------|--------|------|------| | ___ | ___ | ___% | Flaky / Siempre falla | - [ ] Flaky rate calculado ### 4. Identificar Patrones de Flakiness ```bash # Patr├│n 1: Tests que fallan en paralelo # Buscar tests que fallan juntos # Correlacionar por pipeline # Patr├│n 2: Tests que fallan en ciertos d├¡as/horas # Analizar timestamps de fallos # Patr├│n 3: Tests que fallan despu├®s de otros # Verificar orden de ejecuci├│n ``` **Patrones comunes:** | Patr├│n | S├¡ntoma | Causa Probable | |--------|---------|----------------| | Falla solo en CI | Pasa local, falla CI | Diferencia de entorno | | Falla intermitente | 10-50% rate | Race condition | | Falla en paralelo | Solo con -parallel | Estado compartido | | Falla por orden | Depende de otros tests | Setup/teardown | | Falla por tiempo | M├ís en horarios pico | Recursos externos | - [ ] Patrones identificados ### 5. Analizar Tests Sospechosos ```csharp // Indicadores de flakiness en c├│digo // ƒÜ® Thread.Sleep - timing arbitrario Thread.Sleep(1000); // ƒÜ® DateTime.Now en asserts Assert.True(result.CreatedAt > DateTime.Now.AddMinutes(-1)); // ƒÜ® Random sin seed var random = new Random(); // ƒÜ® Acceso a recursos compartidos private static List<string> _sharedState = new(); // ƒÜ® Dependencia de orden [TestMethod] public void Test1_CreateUser() { } // ÔåÉ Crea user [TestMethod] public void Test2_GetUser() { } // ÔåÉ Depende de Test1 ``` ```bash # Buscar patrones de riesgo grep -rn "Thread.Sleep\|Task.Delay" tests --include="*.cs" grep -rn "DateTime.Now\|DateTime.UtcNow" tests --include="*.cs" | grep -i "assert" grep -rn "static\s\+\w\+\s\+_" tests --include="*.cs" grep -rn "new Random()" tests --include="*.cs" ``` - [ ] C├│digo sospechoso identificado ### 6. Priorizar Correcciones | Prioridad | Criterio | |-----------|----------| | P0 - Cr├¡tico | Falla >20% o bloquea otros | | P1 - Alta | Falla 10-20% | | P2 - Media | Falla 5-10% | | P3 - Baja | Falla <5% | **Template de fix:** ```markdown ## Fix Flaky Test: [Nombre del test] ### S├¡ntoma - Falla rate: X% - Patr├│n: [describir] ### Causa Ra├¡z [Descripci├│n del problema] ### Soluci├│n ```csharp // Antes (flaky) Thread.Sleep(1000); Assert.True(result.IsReady); // Despu├®s (estable) await WaitForConditionAsync(() => result.IsReady, timeout: TimeSpan.FromSeconds(5)); ``` ### Verificaci├│n - [ ] Test pasa 10/10 localmente - [ ] Test pasa 5/5 en CI ``` - [ ] Fixes priorizados ### 7. Implementar Mejoras **Estrategias de fix:** | Problema | Soluci├│n | |----------|----------| | Timing | Usar polling/retry en lugar de Sleep | | Estado compartido | Aislamiento con setup/teardown | | Orden dependiente | Hacer tests independientes | | Recursos externos | Mocks o containers | | Paralelismo | Lockeo o colecciones thread-safe | ```csharp // Ejemplo: Polling en lugar de Sleep public async Task WaitForConditionAsync(Func<bool> condition, TimeSpan timeout) { var deadline = DateTime.UtcNow.Add(timeout); while (!condition() && DateTime.UtcNow < deadline) { await Task.Delay(100); } Assert.True(condition(), "Condition not met within timeout"); } ``` - [ ] Fixes implementados - [ ] Tests verificados ### 8. Configurar Detecci├│n Autom├ítica ```yaml # GitLab CI - Retry autom├ítico para flaky tests test: script: - dotnet test retry: max: 2 when: script_failure # O mejor: Quarantine de tests flaky test: script: - dotnet test --filter "Category!=Flaky" test:flaky: script: - dotnet test --filter "Category=Flaky" allow_failure: true ``` - [ ] Retry/quarantine configurado --- ## Output Esperado ``` ====== PROC-36 COMPLETADO [TIMESTAMP] ====== Proyecto: [nombre] Per├¡odo analizado: ├║ltimos X pipelines RESUMEN: - Total tests: X - Tests ├║nicos fallidos: Y - Tests flaky identificados: Z - Flaky rate global: W% TESTS FLAKY (por frecuencia): | Test | Fallos | Rate | Causa | Prioridad | |------|--------|------|-------|-----------| | OrderService_Concurrent | 5 | 25% | Race condition | P0 | | PaymentTests_Timeout | 4 | 20% | Timing | P1 | | DbTests_Connection | 2 | 10% | Network | P2 | PATRONES DETECTADOS: - Tests con Thread.Sleep: X - Tests con estado est├ítico: Y - Tests sin cleanup: Z FIXES APLICADOS: - [test1]: Sleep -> Polling - [test2]: Aislamiento de estado QUARANTINE: - Tests movidos a @Flaky: X - Permitir fallo: S├¡ PR├ôXIMOS PASOS: 1. Corregir P0 tests antes de release 2. Planificar P1/P2 para pr├│ximo sprint ``` --- ## Criterios de ├ëxito - [ ] Flaky rate < 1% - [ ] 0 tests P0 sin fix - [ ] Detecci├│n autom├ítica configurada - [ ] Tests flaky en quarantine documentados --- ## Alertas y Escalaci├│n | Severidad | Condici├│n | Acci├│n | |-----------|-----------|--------| | CRITICAL | Flaky rate > 10% | Pipeline no confiable - fix urgente | | WARNING | >5 tests flaky | Planificar correcciones | | INFO | Nuevo test flaky | A├▒adir a backlog | --- ## Automatizaci├│n En ejecuci├│n no-interactiva: 1. Obtener historial de CI 2. Parsear resultados de tests 3. Calcular tasas de fallo 4. Identificar flaky tests 5. Generar reporte --- --- ## Output Estructurado (Nexus) Al finalizar, el agente DEBE generar un bloque JSON con el siguiente formato para que Nexus pueda procesarlo automaticamente: ```json { "result": "success", "summary": "Ejecucion de PROC-36 completada. [Descripcion breve de resultados]", "metrics": { "issues_found": 0, "issues_resolved": 0, "tests_passed": 100, "tests_failed": 0, "coverage_percent": 78, "custom": { "procedure_specific_metric": "value" } }, "backlog_items": [ { "title": "Titulo del item de seguimiento", "description": "Descripcion detallada si se requiere accion futura", "priority": "medium", "type": "improvement", "tags": ["proc-36"] } ], "next_steps": [ "Accion recomendada 1", "Accion recomendada 2" ], "warnings": [ "Advertencias encontradas durante la ejecucion" ] } ``` **Campos requeridos:** - `result`: `"success"` | `"partial"` | `"failed"` - `summary`: Resumen ejecutivo en 1-3 lineas **Metricas especificas de este procedure:** - tests_analyzed, flaky_tests, flaky_fixed **Criterios de resultado:** - `success`: Procedimiento completado sin errores criticos - `partial`: Completado con algunos problemas menores o items pendientes - `failed`: Error critico o no se pudo completar ## Historial de Ejecuciones | Fecha | Proyecto | Tests Totales | Flaky | Rate | Corregidos | |-------|----------|---------------|-------|------|------------| | | | | | | |
H1
H2
H3
Bold
Italic
Code
Lista
Num
Task
Code Block
Link
Nexus Platform
Reconectando
Recuperando la conexion
Se ha interrumpido la conexion con el servidor. Estamos reconectando automaticamente.
Reconectando...
Manten esta pestana abierta, volvemos enseguida.
No hemos podido reconectar
El servidor puede estar reiniciandose o tu conexion a internet es inestable.
Reintentar
La sesion ha expirado
Recarga la pagina para iniciar una nueva sesion.
Recargar
Si no vuelve en 30 segundos, recarga la pagina.