Repository navigation
Software testing Sprint 2
Esta página recoge los casos de prueba diseñados para validar las historias de usuario del Sprint 2. La idea es tener un inventario claro que cualquier integrante del equipo pueda revisar, ejecutar y entender, sin importar si la prueba es manual o automatizada.
Tomamos el backlog del Sprint 2 y por cada historia de usuario derivamos uno o más casos de prueba pensando en dos cosas: el camino feliz que tiene que funcionar siempre, y al menos un camino alternativo donde algo sale mal o el usuario hace algo inesperado. Esto nos dio un total de 15 casos.
De esos 15, automatizamos 13 (los que se pueden ejecutar sin intervención humana) y dejamos 2 como manuales: el flujo end to end con un contenedor Docker real, y la prueba de login con credenciales inválidas, que ya se ejecutó en Sprint 1 y se mantiene como regresión.
Al cierre del sprint pasamos 14 de los 15 casos. El único pendiente es el caso end to end (CP-14), que se ejecutará durante la sustentación porque requiere levantar el stack completo de Docker más Supabase.
Vinculado a la historia US-03. La precondición es que el backend esté corriendo y Supabase accesible. Los pasos son enviar un POST a /api/alerts con un payload típico de Alertmanager en estado firing, alertname ContainerCrashed y un label name=app-demo. Después de eso, consultar la tabla incidents de Supabase.
El resultado esperado es que la respuesta sea 200, y que en Supabase exista un incidente con target app-demo, severity high, status detected, container_runtime docker y source_type container.
Este caso está automatizado en test_alert_processor.py::test_process_firing_alert_creates_incident y pasa.
También de US-03. La idea es que cuando Prometheus dispara la resolución de una alerta, el backend cierre los incidentes asociados sin crear uno nuevo. El test simula tener un incidente activo y luego envía la misma alerta con status resolved. El resultado esperado es que el incidente quede con status resolved, que se pueble el campo resolved_at y que la función no retorne ningún incident_id porque no se creó nada.
Automatizado y pasa.
Caso alternativo de US-03. Si llega una alerta nueva, todavía no registrada en SEVERITY_MAP, el sistema no debe romperse. Lo que tiene que hacer es asignar severidad medium por defecto y crear el incidente igual. El test envía una alerta con un alertname inventado y verifica que el incidente se cree con severity medium.
Automatizado y pasa.
Caso parametrizado que cubre 11 combinaciones de alertas, incluyendo las de Docker, Podman y Postgres. Validamos que ContainerOOMKilled mapea a critical, ContainerCrashed a high, ContainerCPUThrottling a medium, PostgresConnectionsExhausted a critical, PostgresLowCacheHitRatio a medium, y así con el resto. Si alguien agrega una nueva alerta y se le olvida actualizar el mapa, este test lo detecta.
Automatizado y pasa.
Vinculado a US-06. El test llama a query_loki_logs con un container_id y un alert_time, simulando una respuesta de Loki con dos streams y varias líneas. El resultado esperado es un string formateado con las líneas ordenadas cronológicamente y cada una con su timestamp legible en UTC.
Automatizado y pasa.
Caso alternativo crítico de US-06. La idea es que si Loki está caído, el sistema no debe fallar al crear un incidente: simplemente no adjunta logs y sigue adelante. El test simula un ConnectionError al llamar a Loki y verifica que la función retorne string vacío sin lanzar excepción.
Automatizado y pasa.
Vinculado a US-04. Cuando llega un incidente con label container_runtime=docker, el supervisor debe enrutarlo al DockerAgent. El test crea un IncidentContext con ese label y llama a find_agent_for(ctx), esperando que el agente retornado sea el DockerAgent.
Automatizado y pasa.
Caso alternativo de US-04, esencial para mantener la separación de dominios. Si un incidente tiene target postgres/customers y source_type database, el DockerAgent no debe matchear, porque no es su dominio. El test verifica que DockerAgent.matches(ctx) retorne False en ese contexto.
Automatizado y pasa.
Vinculado a US-01. Hacer un GET a /api/incidents/ con query params como severity=critical&status=detected debe devolver solo los incidentes que cumplan ambos criterios, ordenados por fecha descendente. El test verifica que la respuesta sea 200 y que la lista respete los filtros.
Automatizado y pasa.
Caso alternativo de US-02. Si el usuario manda un POST a /api/incidents/ con un severity que no está en el enum permitido (por ejemplo ultra-critical), el endpoint debe responder con 422 y un detalle de Pydantic explicando el error. El test confirma que la validación funciona.
Automatizado y pasa.
Caso del frontend, función pura del componente ApprovalModal. Tiene varios escenarios: incident_type oom debe retornar nivel Alto, dependency_failure debe retornar Medio, cualquier comando que contenga la palabra logs debe retornar Bajo (porque es solo lectura), y un incident_type desconocido debe caer al default Medio.
Automatizado en getRisk.test.js y pasa.
Vinculado al flujo HITL (Human In The Loop) de aprobación de acciones. El test renderiza el componente con un incidente de prueba, escribe un comentario en el textarea, hace click en el botón Aprobar y verifica que la función onApprove se haya llamado con el texto del comentario.
Automatizado en ApprovalModal.test.jsx y pasa.
Caso alternativo del flujo de aprobación. El usuario debe poder cerrar el modal sin necesidad de hacer click. El test renderiza el modal y simula un evento de teclado con key Escape, esperando que onClose se llame una vez.
Automatizado y pasa.
Este es el caso manual más importante porque valida que todo el flujo funciona junto. Los pasos son levantar el stack con docker compose up -d, arrancar el backend con uvicorn, crear un contenedor que crashea con docker run -d --name app-demo alpine sh -c "echo BOOM; sleep 2; exit 1", esperar unos 30 segundos y abrir el frontend.
El resultado esperado es que el incidente aparezca en el dashboard en tiempo real (vía Supabase Realtime), con status analyzed, un incident_type clasificado por el agente y un agent_reasoning poblado en markdown. Todo el flujo debe tomar menos de 30 segundos, dejando margen sobre el NFR-02 (15 segundos).
Pendiente de ejecutarse durante la sustentación.
Vinculado a HU-00. Es una prueba de regresión del Sprint 1. Se ingresan credenciales incorrectas en el formulario de login y se verifica que aparezca el mensaje de error y que el usuario no sea redirigido al dashboard.
Ejecutado y pasa, sin regresiones detectadas.
Para que cualquier persona del equipo pueda confirmar que el sprint quedó bien cubierto, esta es la trazabilidad:
US-01 está cubierto por CP-09. US-02 por CP-10 más las pruebas de modelos. US-03 por CP-01, CP-02, CP-03 y CP-04. US-04 por CP-07 y CP-08. US-06 por CP-05 y CP-06. La historia de aprobación humana por CP-11, CP-12 y CP-13. El flujo completo del producto por CP-14. Login (regresión) por CP-15.
Desde la carpeta Backend, pytest -v corre los 13 casos automatizados del backend más los modelos. Desde la carpeta Frontend, npm run test corre los del componente y de la función pura. La salida en verde es la evidencia de que pasaron.
El detalle completo (con los pasos exactos y los resultados esperados de cada caso) está en docs/sprint2-pruebas/02-casos-de-prueba.md dentro del repositorio.