Portafolio Final Módulos 2 y 3: Testing Ágil + TDD en Automatización de Pruebas
👨💻 Desarrollado por: Roberto Rivas López
📅 Fecha: Julio 2025
🏫 Institución: [Tu Institución Educativa]
📦 Versión: 1.0.0
- Descripción del Proyecto
- Objetivos de Aprendizaje
- Tecnologías Utilizadas
- Arquitectura del Sistema
- Principios Aplicados
- Instalación y Configuración
- Uso del Sistema
- Ejecución de Pruebas
- Cobertura de Código
- Ciclos TDD Implementados
- Plan de Testing Ágil
- Estructura del Proyecto
- Configuración de Base de Datos
- Reflexión Personal
- Contribución
Este proyecto es un Sistema CRUD (Create, Read, Update, Delete) de Estudiantes desarrollado completamente con Test-Driven Development (TDD) aplicando metodologías ágiles y principios de diseño sólidos.
- ✅ CRUD completo para gestión de estudiantes
- ✅ 12+ ciclos TDD (RED-GREEN-REFACTOR)
- ✅ Principios SOLID implementados
- ✅ Cobertura >= 80% con JaCoCo
- ✅ Mockito para testing de dependencias
- ✅ Arquitectura por capas bien definida
- ✅ Doble implementación: Memoria y Base de Datos
- ✅ Testing Ágil integrado en el ciclo de desarrollo
- Comprender la importancia del testing en entornos ágiles
- Aplicar criterios de aceptación en historias de usuario
- Integrar testing en sprints de desarrollo
- Definir "Terminado" para incrementos de producto
- Dominar el ciclo RED-GREEN-REFACTOR
- Escribir pruebas unitarias efectivas con JUnit 5
- Utilizar Mockito para aislar dependencias
- Medir y mantener cobertura de código >= 80%
- Refactorizar aplicando principios SOLID
- Java 17 - Lenguaje de programación principal
- Maven 3.9.10 - Gestión de dependencias y construcción
- JUnit 5.10.1 - Framework de testing unitario
- Mockito 5.8.0 - Framework para mocking
- JaCoCo 0.8.11 - Análisis de cobertura de código
- H2 2.2.224 - Base de datos en memoria para testing
- MySQL Connector 8.0.33 - Driver para SQLonline
- SQLonline - Servicio de base de datos gratuito
- Visual Studio Code - IDE principal
- Git - Control de versiones
- GitHub - Repositorio remoto
El sistema implementa una arquitectura por capas siguiendo principios de diseño sólidos:
┌─────────────────────────────────────┐
│ Controlador │ ← Patrón Facade
├─────────────────────────────────────┤
│ Servicio │ ← Lógica de negocio
├─────────────────────────────────────┤
│ Repositorio │ ← Acceso a datos
├─────────────────────────────────────┤
│ Modelo │ ← Entidades de dominio
└─────────────────────────────────────┘
- 🎮 Controlador: Interfaz de usuario y orquestación
- 🎯 Servicio: Lógica de negocio y validaciones
- 💾 Repositorio: Abstracción de acceso a datos
- 📄 Modelo: Entidades y objetos de dominio
- 🔄 DTO: Objetos de transferencia de datos
Principio | Implementación | Ejemplo en el Código |
---|---|---|
SRP - Responsabilidad Única | Cada clase tiene una sola razón para cambiar | Estudiante solo maneja datos del estudiante |
OCP - Abierto/Cerrado | Extensible sin modificar código existente | Interface IEstudianteRepositorio |
LSP - Sustitución de Liskov | Subtipos reemplazables | EstudianteRepositorioMemoria vs EstudianteRepositorioBD |
ISP - Segregación de Interfaces | Interfaces específicas y cohesivas | IEstudianteServicio vs IEstudianteRepositorio |
DIP - Inversión de Dependencias | Depender de abstracciones | Servicio depende de IEstudianteRepositorio |
- 🧩 Modularidad: Código organizado en módulos cohesivos
- 🔒 Encapsulación: Datos y comportamiento encapsulados
- 🎭 Abstracción: Interfaces bien definidas
- 🚪 Separación de Intereses: Cada capa tiene su responsabilidad específica
- Java 17+ instalado
- Maven 3.9+ configurado
- Git para clonar el repositorio
- Visual Studio Code (recomendado)
-
Clonar el repositorio
git clone https://github.com/roberto-rivas/crud-tdd-estudiantes.git cd crud-tdd-estudiantes
-
Verificar instalación de Java y Maven
java --version mvn --version
-
Compilar el proyecto
mvn clean compile
-
Ejecutar las pruebas
mvn test
-
Generar el JAR ejecutable
mvn clean package
# Ejecutar con repositorio en memoria (recomendado para pruebas)
mvn exec:java -Dexec.mainClass="com.roberto.rivas.AplicacionPrincipal" -Dexec.args="--memory"
# Ejecutar con base de datos
mvn exec:java -Dexec.mainClass="com.roberto.rivas.AplicacionPrincipal" -Dexec.args="--db"
# Generar JAR
mvn clean package
# Ejecutar JAR
java -jar target/crud-tdd-proyecto-1.0.0.jar --memory
java -jar target/crud-tdd-proyecto-1.0.0.jar --db
Opción | Descripción |
---|---|
--memory , --mem |
Usar repositorio en memoria |
--database , --db |
Usar base de datos MySQL |
--help , -h |
Mostrar ayuda |
- ➕ Registrar nuevo estudiante
- 🔍 Buscar estudiante por ID
- 📧 Buscar estudiante por email
- 📋 Listar todos los estudiantes
- 🎓 Listar estudiantes por carrera
- ✏️ Actualizar estudiante
- 🗑️ Eliminar estudiante (lógico)
- 🔄 Reactivar estudiante
- 📊 Mostrar estadísticas
- 🎯 Demostración completa
# Ejecutar todas las pruebas
mvn test
# Ejecutar pruebas específicas
mvn test -Dtest=EstudianteTest
mvn test -Dtest=EstudianteRepositorioTest
mvn test -Dtest=EstudianteServicioTest
# Ejecutar pruebas con reporte detallado
mvn test -Dmaven.test.failure.ignore=true
# Ejecutar pruebas en modo debug
mvn test -Dmaven.surefire.debug
src/test/java/
├── com/roberto/rivas/
│ ├── modelo/
│ │ └── EstudianteTest.java # Ciclos TDD 1-4
│ ├── repositorio/
│ │ └── EstudianteRepositorioTest.java # Ciclos TDD 5-8
│ └── servicio/
│ └── EstudianteServicioTest.java # Ciclos TDD 9-12
- ✅ Pruebas Unitarias: 16+ casos de prueba
- ✅ Pruebas de Integración: Componentes trabajando juntos
- ✅ Pruebas de Validación: Reglas de negocio
- ✅ Pruebas con Mocks: Aislamiento de dependencias
# Ejecutar pruebas y generar reporte
mvn clean test jacoco:report
# Ver reporte en navegador
open target/site/jacoco/index.html
# Verificar que cobertura >= 80%
mvn jacoco:check
- 🎯 Cobertura de Instrucciones: >= 80%
- 🎯 Cobertura de Ramas: >= 75%
- 🎯 Cobertura de Métodos: >= 85%
- 🎯 Cobertura de Clases: >= 90%
Ciclo | Componente | Funcionalidad | Estado |
---|---|---|---|
1-4 | Modelo | Validaciones de Estudiante | ✅ |
5-8 | Repositorio | Operaciones CRUD básicas | ✅ |
9-12 | Servicio | Lógica de negocio | ✅ |
13+ | Integración | Casos especiales | ✅ |
- RED: Escribir pruebas para validaciones
- GREEN: Implementar validaciones mínimas
- REFACTOR: Mejorar encapsulación y abstracción
- RED: Pruebas para operaciones CRUD
- GREEN: Implementación básica con Map
- REFACTOR: Optimizar y añadir validaciones
- RED: Pruebas de lógica de negocio
- GREEN: Implementar reglas de negocio
- REFACTOR: Aplicar principios SOLID
Como administrador del sistema
Quiero gestionar información de estudiantes
Para mantener un registro actualizado y confiable
-
Historia US-001: Registrar Estudiante
- Crear estudiante con datos válidos
- Validar email único
- Rechazar datos incompletos
- Asignar ID automático
-
Historia US-002: Consultar Estudiante
- Buscar por ID existente
- Buscar por email válido
- Manejar búsquedas sin resultados
- Listar todos los activos
-
Historia US-003: Actualizar Estudiante
- Modificar datos existentes
- Validar email único en actualización
- Rechazar estudiante inexistente
- Mantener auditoría de cambios
-
Historia US-004: Eliminar Estudiante
- Eliminación lógica (activo = false)
- Confirmar antes de eliminar
- No mostrar en listados activos
- Permitir reactivación posterior
- ✅ Código implementado y compilando
- ✅ Pruebas unitarias pasando (>= 80% cobertura)
- ✅ Principios SOLID aplicados
- ✅ Documentación actualizada
- ✅ Sin deuda técnica significativa
- ✅ Validaciones de negocio implementadas
- ✅ Manejo de errores robusto
Rol | Responsabilidad | Persona |
---|---|---|
Developer | Implementar funcionalidades con TDD | Roberto Rivas |
Tester | Diseñar y ejecutar casos de prueba | Roberto Rivas |
DevOps | Configurar pipeline y reportes | Roberto Rivas |
crud-tdd-proyecto/
├── 📄 pom.xml # Configuración Maven
├── 📖 README.md # Documentación principal
├── 📋 PLAN_TESTING_AGIL.md # Plan de testing detallado
├── 💭 REFLEXION_PERSONAL.md # Reflexión del aprendizaje
├── 📊 PRINCIPIOS_SOLID.md # Documentación de principios
├── src/
│ ├── main/java/com/roberto/rivas/
│ │ ├── 🚀 AplicacionPrincipal.java # Punto de entrada
│ │ ├── controlador/
│ │ │ └── 🎮 EstudianteControlador.java
│ │ ├── servicio/
│ │ │ ├── 🎯 IEstudianteServicio.java
│ │ │ ├── 🎯 EstudianteServicioImpl.java
│ │ │ ├── dto/
│ │ │ │ └── 🔄 EstudianteDTO.java
│ │ │ └── excepcion/
│ │ │ └── ⚠️ ServicioException.java
│ │ ├── repositorio/
│ │ │ ├── 💾 IEstudianteRepositorio.java
│ │ │ ├── 💾 EstudianteRepositorioMemoria.java
│ │ │ ├── 💾 EstudianteRepositorioBD.java
│ │ │ └── ⚠️ RepositorioException.java
│ │ └── modelo/
│ │ └── 📄 Estudiante.java
│ └── test/java/com/roberto/rivas/
│ ├── modelo/
│ │ └── 🧪 EstudianteTest.java
│ ├── repositorio/
│ │ └── 🧪 EstudianteRepositorioTest.java
│ └── servicio/
│ └── 🧪 EstudianteServicioTest.java
├── sql-scripts/
│ ├── 🗄️ estudiantes_schema.sql # Script de creación
│ ├── 📊 datos_ejemplo.sql # Datos de prueba
│ └── 📋 consultas_testing.sql # Consultas para testing
├── target/
│ ├── classes/ # Clases compiladas
│ ├── test-classes/ # Pruebas compiladas
│ ├── site/jacoco/ # Reportes de cobertura
│ └── crud-tdd-proyecto-1.0.0.jar # JAR ejecutable
└── docs/
├── 📸 screenshots/ # Capturas de pantalla
├── 📊 diagramas/ # Diagramas de arquitectura
└── 📝 notas/ # Notas de desarrollo
-
Registrarse en SQLonline
🌐 URL: https://sqlonline.com/ 📧 Crear cuenta gratuita 🗄️ Seleccionar MySQL
-
Ejecutar Script de Inicialización
# Copiar contenido de sql-scripts/estudiantes_schema.sql # Pegar y ejecutar en SQLonline
-
Configurar Credenciales
// En EstudianteRepositorioBD.java private final String url = "jdbc:mysql://sql.freedb.tech:3306/tu_base_datos"; private final String usuario = "tu_usuario"; private final String contrasena = "tu_contraseña";
// Configuración automática para pruebas
// No requiere configuración adicional
# application.properties (si se usa Spring Boot en futuro)
spring.datasource.url=jdbc:mysql://localhost:3306/crud_estudiantes
spring.datasource.username=root
spring.datasource.password=tu_password
Durante el desarrollo de este proyecto, experimenté de primera mano cómo TDD transforma completamente la forma de programar. El ciclo RED-GREEN-REFACTOR me obligó a pensar primero en el comportamiento esperado antes de escribir código, lo que resultó en un diseño más limpio y modular.
Aprendizajes clave:
- TDD no es solo sobre testing, sino sobre diseño dirigido por pruebas
- Las pruebas actúan como documentación viva del sistema
- La refactorización constante mantiene el código limpio y mantenible
- Los principios SOLID emergen naturalmente cuando se sigue TDD
Dificultad 1: Configuración inicial de Mockito
- Problema: Integración compleja con JUnit 5
- Solución: Uso de
@ExtendWith(MockitoExtension.class)
y configuración Maven correcta
Dificultad 2: Diseño de interfaces coherentes
- Problema: Interfaces muy generales que violaban ISP
- Solución: Segregación en interfaces específicas por responsabilidad
Dificultad 3: Cobertura de código en casos edge
- Problema: Alcanzar 80% incluyendo manejo de excepciones
- Solución: Pruebas específicas para cada rama de decisión
Inicialmente fue desafiante porque requiere cambiar la mentalidad de "código primero" a "prueba primero". Sin embargo, después de los primeros ciclos, experimenté:
- Mayor confianza en el código desarrollado
- Diseño más limpio que emerge naturalmente
- Feedback inmediato sobre la calidad del diseño
- Refactorización segura respaldada por pruebas
- Implementar CI/CD desde el inicio con GitHub Actions
- Añadir más tipos de pruebas (integración, aceptación)
- Usar Spring Boot para aprovechar inyección de dependencias automática
- Implementar logging estructurado para mejor observabilidad
- Añadir validaciones más robustas usando Bean Validation
- Crear interfaz web con Spring MVC o React
- Fork el repositorio
- Crear una rama para tu feature (
git checkout -b feature/nueva-funcionalidad
) - Escribir pruebas siguiendo TDD
- Implementar la funcionalidad
- Verificar cobertura >= 80%
- Commit con mensaje descriptivo
- Push a tu rama (
git push origin feature/nueva-funcionalidad
) - Crear Pull Request
- ✅ Seguir convenciones de naming en español
- ✅ Aplicar principios SOLID
- ✅ Mantener cobertura >= 80%
- ✅ Documentar métodos públicos
- ✅ Usar TDD para nueva funcionalidad
- 🚀 API REST con Spring Boot
- 🎨 Interfaz Web con React o Thymeleaf
- 🔐 Autenticación y autorización
- 📊 Dashboard con métricas
- 🐳 Containerización con Docker
- ☁️ Despliegue en cloud (AWS, Azure)
- 📱 Aplicación móvil con React Native
👨💻 Desarrollador: Roberto Rivas López
📧 Email: roberto.rivas@ejemplo.com
🔗 LinkedIn: linkedin.com/in/roberto-rivas-lopez
🐙 GitHub: github.com/roberto-rivas
🐛 Bugs: GitHub Issues
💡 Features: GitHub Discussions
📖 Documentación: Wiki del Proyecto
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para detalles.
MIT License
Copyright (c) 2025 Roberto Rivas López
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- 🏫 [Tu Institución] por la formación en metodologías ágiles
- 👥 Comunidad Java por las mejores prácticas
- 📚 Autores de Clean Code por los principios de diseño
- 🧪 Creadores de JUnit y Mockito por las herramientas de testing
- 🌟 Comunidad Open Source por el conocimiento compartido
⭐ Si este proyecto te fue útil, ¡considera darle una estrella en GitHub!
🚀 ¡Feliz desarrollo con TDD!