← Calidad, observabilidad y documentación

UD11 · Verificar

Lo que debes recordar

El método

En esta unidad has consolidado la estrategia de calidad y verificación para transformar un prototipo funcional en software profesional listo para producción.

Para garantizar la calidad y observabilidad de cualquier backend empresarial, aplica siempre este decálogo de ingeniería:

El decálogo de calidad, observabilidad y documentación
  1. Organiza tus pruebas según la Pirámide de Pruebas: maximiza tests unitarios rápidos y minimiza tests completos de integración.
  2. Desconfía de la cobertura de líneas: audita la cobertura de ramas (Branch Coverage) para asegurar que todas las decisiones lógicas han sido probadas.
  3. Prueba siempre los casos límite y frontera (nulos, vacíos, desbordamientos, duplicados) mediante @ParameterizedTest.
  4. Verifica la atomicidad transaccional con tests de reversión (rollback) ante fallos intencionados.
  5. Prohíbe terminantemente System.out.println: utiliza la fachada SLF4J y clasifica cada mensaje en su nivel exacto (ERROR, WARN, INFO, DEBUG, TRACE).
  6. Configura Logback con rotación y compresión de archivos para evitar la saturación del almacenamiento del servidor.
  7. Inyecta un Correlation ID único mediante MDC en cada petición HTTP para enlazar todas las trazas de un mismo usuario.
  8. Respeta la privacidad (GDPR / OWASP): nunca registres contraseñas, tokens completos ni datos personales en los logs.
  9. Genera documentación viva con OpenAPI 3 y Swagger UI, describiendo códigos de respuesta, esquemas de error y seguridad JWT.
  10. Somete todo cambio a una Revisión de Código por Pares (Peer Code Review) evaluando arquitectura, seguridad, resiliencia y rendimiento.

La idea más importante

El software no termina cuando funciona en tu máquina: termina cuando otro desarrollador puede leerlo y entenderlo, un pipeline de CI puede verificarlo automáticamente con tests que cubren casos límite, un operador puede monitorizarlo y depurarlo en producción mediante logs correlacionados, y un equipo cliente puede integrarlo sin dudas gracias a su documentación técnica.

Hacer que un programa funcione con datos perfectos en local lo consigue cualquiera. La verdadera ingeniería de software consiste en construir aplicaciones observables, mantenibles y robustas que resistan el paso del tiempo y los fallos del mundo real.

Las decisiones que tienes que saber justificar

Decisión de ingeniería Lo que tienes que poder defender ante un tribunal
Pirámide de Pruebas frente a solo tests de controlador Los tests unitarios con Mockito se ejecutan en milisegundos y aíslan la lógica; abusar de @SpringBootTest ralentiza el pipeline de integración continua de minutos a horas.
Cobertura de ramas (Branch Coverage) frente a líneas La cobertura de líneas puede engañar al auditor si no hay aserciones; la cobertura de ramas garantiza que tanto el camino verdadero como el falso de cada condicional fueron verificados.
Tests parametrizados con @ParameterizedTest Permiten comprobar decenas de combinaciones y valores frontera (nulos, vacíos, límites numéricos) con un único método de prueba limpio y mantenible.
SLF4J + Logback frente a System.out.println SLF4J permite filtrar por gravedad en tiempo de ejecución, es asíncrono no bloqueante, incluye marcas de tiempo e hilos, y permite rotación de archivos en disco.
Identificador de correlación con MDC Permite reconstruir la secuencia completa de operaciones de una petición HTTP específica en entornos concurrentes con miles de usuarios simultáneos.
Prohibición de registrar datos sensibles (PII) en logs Cumplimiento estricto del RGPD y estándares de seguridad OWASP para evitar que una fuga de logs exponga contraseñas, credenciales o datos protegidos.
OpenAPI 3 autogenerado frente a documentos estáticos Los documentos manuales quedan obsoletos de inmediato; la documentación viva se actualiza automáticamente con cada cambio en el código fuente.
Revisión de código estructurada por rúbrica Asegura que el code review evalúe aspectos críticos de ingeniería (seguridad, arquitectura, consultas N+1) y no meras preferencias estéticas de formateo.
Inclusión de correlationId en respuestas RFC 7807 Conecta el soporte al usuario con la depuración técnica: el cliente reporta el código de error y el ingeniero localiza la traza exacta en segundos.
Configuración de fallos de compilación por umbrales (jacoco:check) Garantiza la disciplina del equipo en integración continua: ningún código nuevo sin cobertura suficiente puede fusionarse en la rama principal.

Al terminar la unidad deberías poder responder

  1. ¿Por qué una suite de pruebas con 90 % de cobertura de líneas puede permitir fallos graves en producción?
  2. ¿Qué tres niveles componen la Pirámide de Pruebas y qué proporción debe mantenerse entre ellos?
  3. ¿Cómo se utiliza @ParameterizedTest junto a @ValueSource para probar valores frontera en JUnit 5?
  4. ¿Qué comprueba un test de integración transaccional que simula un fallo en un método @Transactional?
  5. ¿Qué cuatro problemas graves presenta el uso de System.out.println en aplicaciones web de servidor?
  6. ¿Cuál es el significado y propósito de cada uno de los 5 niveles de log (ERROR, WARN, INFO, DEBUG, TRACE)?
  7. ¿Cómo opera el patrón MDC (Mapped Diagnostic Context) en un filtro HTTP de Spring Boot?
  8. ¿Por qué es obligatorio limpiar el MDC mediante MDC.remove() al terminar de procesar una petición?
  9. ¿Qué directivas de rotación de archivos en Logback evitan que los logs saturen el disco duro del servidor?
  10. ¿Por qué nunca deben registrarse tokens JWT completos ni contraseñas en las trazas de log?
  11. ¿Cómo se vincula el X-Correlation-ID de la cabecera HTTP con el objeto de error estándar RFC 7807?
  12. ¿Qué ventajas aporta la especificación OpenAPI 3 y su visor Swagger UI para el equipo de desarrollo frontend?
  13. ¿Cómo se documenta en OpenAPI que un endpoint requiere autenticación mediante Bearer Token?
  14. ¿Qué cinco dimensiones estructuran la Rúbrica de Auditoría Técnica en una revisión de código por pares?
  15. ¿Qué es el problema de las consultas N+1 en Spring Data JPA y cómo se previene con JOIN FETCH?
  16. ¿Por qué las entidades JPA nunca deben exponerse directamente en los métodos de un controlador REST?
  17. ¿Cuál es la diferencia entre un test que usa @WebMvcTest y uno que usa @DataJpaTest?
  18. ¿Cómo ayuda la herramienta JaCoCo a detectar ramas condicionales sin probar (Yellow Lines)?
  19. ¿Por qué un Code Review debe centrarse en el diseño, la seguridad y la resiliencia y no en el formateo de llaves?
  20. ¿Qué significa el principio «Fail Fast» en la gestión de excepciones de un servicio backend?

El vocabulario de la unidad

Concepto Significa
Pirámide de Pruebas Modelo arquitectónico que promueve una base amplia de tests unitarios rápidos, una capa media de tests de corte y una cima reducida de tests de integración completa.
Branch Coverage Métrica de calidad que mide el porcentaje de ramas lógicas y caminos de decisión ejecutados por una suite de pruebas.
Slice Test Prueba focalizada que levanta exclusivamente una capa o subconjunto de beans de Spring (ej: @WebMvcTest o @DataJpaTest).
JaCoCo Herramienta estándar de Java para análisis y generación de informes de cobertura de código fuente.
SLF4J Fachada abstracta de logging en Java que permite desacoplar el código del motor de trazas subyacente.
Logback Motor de registro de trazas por defecto en Spring Boot, sucesor moderno de Log4j.
MDC Mapped Diagnostic Context: almacén basado en ThreadLocal de SLF4J para adjuntar información contextual (como identificadores de usuario o petición) a todas las líneas de log.
Correlation ID Identificador alfanumérico único asignado a una petición HTTP para rastrear su ejecución a través de todos los componentes y servicios del sistema.
Log Rotation Política de archivado automático que divide los ficheros de log por fecha o tamaño y comprime los históricos antiguos para ahorrar espacio.
PII Personally Identifiable Information: datos personales sensibles protegidos por normativas de privacidad que nunca deben exponerse en registros de log.
OpenAPI 3 Especificación estándar e independiente del lenguaje para describir de forma exhaustiva las interfaces de programación REST.
Swagger UI Herramienta web que renderiza visualmente un contrato OpenAPI permitiendo explorar e interactuar con los endpoints de la API.
Peer Code Review Práctica de ingeniería donde los desarrolladores inspeccionan y comentan el código de sus compañeros antes de integrarlo en la rama principal.
N+1 Problem Ineficiencia en ORMs donde una consulta inicial genera N consultas adicionales para cargar entidades relacionadas en bucle.
Rollback Operación transaccional que anula todos los cambios realizados en la base de datos durante una transacción ante la ocurrencia de un error.

Comprobación final del producto de la unidad

Calidad, observabilidad y documentación · criterios de producción

  • La suite de pruebas combina tests unitarios puros, tests de corte (@WebMvcTest, @DataJpaTest) y tests de integración.
  • Se audita y alcanza una cobertura de ramas (*Branch Coverage*) superior al 75 % en la capa de servicios con JaCoCo.
  • Los casos límite (nulos, vacíos, límites numéricos y caracteres especiales) están probados con @ParameterizedTest.
  • Se verifica la atomicidad transaccional comprobando que los fallos provocan el rollback íntegro en la base de datos.
  • El código fuente está libre de llamadas a System.out.println, utilizando exclusivamente el Logger de SLF4J.
  • Los mensajes de log están clasificados con criterio estricto entre ERROR, WARN, INFO y DEBUG.
  • El archivo logback-spring.xml implementa rotación y compresión de archivos diarios con límite de tamaño.
  • Cada petición HTTP dispone de un X-Correlation-ID inyectado en el MDC y devuelto en las cabeceras de respuesta.
  • Los contratos OpenAPI 3 están enriquecidos y sincronizados con descripciones, códigos de error y seguridad JWT.
  • El código ha superado una revisión por pares con rúbrica técnica corrigiendo defectos de arquitectura y consultas N+1.

Resultados de la unidad

  • Explicar qué cubre y qué no cubre la suite de pruebas existente.
  • Completar los casos límite que faltan y medir la cobertura con criterio.
  • Dejar trazas útiles y depurar un fallo con ellas.
  • Publicar documentación técnica y someterla a una revisión por pares.

Ya deberías ser capaz de

  • Explicar qué cubre y qué no cubre la suite de pruebas existente.
  • Completar los casos límite que faltan y medir la cobertura con criterio.
  • Dejar trazas útiles y depurar un fallo con ellas.
  • Publicar documentación técnica y someterla a una revisión por pares.