clase:daw:daw-proyecto:tema06
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Próxima revisión | Revisión previa | ||
| clase:daw:daw-proyecto:tema06 [2026/10/13 19:42] – creado Lorenzo | clase:daw:daw-proyecto:tema06 [2026/10/14 14:08] (actual) – Tema nuevo «2. IA y agentes»: los temas 2 a 7 pasan a ser 3 a 8, con sus referencias cruzadas renumeradas claude | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ====== 6. Automatizando el proyecto con IA ====== | ====== 6. Automatizando el proyecto con IA ====== | ||
| + | |||
| + | Objetivo del tema: que la calidad la vigilen **tests que genera la IA** en los cuatro niveles (arquitectura, | ||
| + | |||
| + | Una skill nueva, ''/ | ||
| + | |||
| + | ^ Skill ^ Sustantivos ^ Verbos ^ | ||
| + | | ''/ | ||
| + | | ''/ | ||
| + | |||
| + | ===== Los cuatro tipos de tests ===== | ||
| + | |||
| + | ^ Tipo ^ Qué prueba ^ Con qué ^ Necesita ^ Lo ejecuta ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | Los dos primeros forman parte del build de Maven: corren en cada compilación y no necesitan nada levantado. Los dos últimos **no forman parte del build**: son lentos, necesitan la aplicación y se lanzan cuando se quiere. Los comandos son los mismos para el alumno, para el agente y para CI (tema 7); lo que añade ''/ | ||
| + | |||
| + | ===== Crear los tests: /test < | ||
| + | |||
| + | ==== arch: tests de arquitectura con ArchUnit ==== | ||
| + | |||
| + | Las reglas de arquitectura (las de Programación y DWS: capas, nombres, sin ciclos, '' | ||
| + | |||
| + | < | ||
| + | /test arch create | ||
| + | - Las clases de controller solo dependen de domain. | ||
| + | - Las de persistence solo dependen de domain. | ||
| + | - Nada en domain importa org.springframework ni jakarta.persistence. | ||
| + | - Los controladores acaban en Controller y están en ..controller.. | ||
| + | - Los repositorios de persistence acaban en RepositoryImpl e implementan una interfaz de domain. | ||
| + | - Sin ciclos entre paquetes. | ||
| + | </ | ||
| + | |||
| + | Cada test lleva en su '' | ||
| + | |||
| + | <sxh java> | ||
| + | @Test | ||
| + | @DisplayName(" | ||
| + | void domainSinSpring() { | ||
| + | noClasses().that().resideInAPackage(" | ||
| + | .should().dependOnClassesThat().resideInAPackage(" | ||
| + | .check(clases); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | **No hay un documento aparte con la arquitectura.** Mantener un Markdown sincronizado con los tests es un trabajo que nadie hace, así que la fuente de verdad son los tests con su descripción. Para cambiar una regla se le pide a la skill que cambie el test. Cuando se añade una regla que el código actual aún no cumple, '' | ||
| + | |||
| + | ==== unit: tests unitarios con JUnit ==== | ||
| + | |||
| + | Los tests unitarios prueban la lógica del dominio **sin Spring y sin base de datos**: un servicio con sus repositorios sustituidos por mocks de Mockito. Son los más rápidos y los que mejor localizan un error. | ||
| + | |||
| + | < | ||
| + | /test unit create | ||
| + | </ | ||
| + | |||
| + | Sin argumento genera los de todas las clases que no los tienen; con una clase o un paquete (''/ | ||
| + | |||
| + | Lo que hace: lee la clase, identifica cada comportamiento (lo que devuelve, lo que valida, lo que lanza) y escribe un test por comportamiento en '' | ||
| + | |||
| + | Qué no prueban: controladores ni repositorios. Eso es de los tests de API. | ||
| + | |||
| + | ==== api: tests de API con Playwright ==== | ||
| + | |||
| + | Los tests de API prueban cada endpoint **de verdad**: peticiones HTTP contra el backend del worktree, comprobando el código de estado y el JSON. Se escriben con Playwright, igual que los E2E (mismo lenguaje, misma configuración, | ||
| + | |||
| + | < | ||
| + | /test api create Pedido: alta válida, sin cliente, cliente que no existe, borrar uno con líneas | ||
| + | </ | ||
| + | |||
| + | El argumento son los **escenarios**: | ||
| + | |||
| + | <sxh typescript> | ||
| + | test(' | ||
| + | const res = await request.post('/ | ||
| + | expect(res.status()).toBe(400); | ||
| + | expect((await res.json()).errores.numero).toBeDefined(); | ||
| + | }); | ||
| + | </ | ||
| + | |||
| + | Los de API y los E2E son dos **proyectos** del mismo '' | ||
| + | |||
| + | <sxh typescript; | ||
| + | export default defineConfig({ | ||
| + | use: { baseURL: process.env.BASE_URL ?? ' | ||
| + | projects: [ | ||
| + | { name: ' | ||
| + | { name: ' | ||
| + | ], | ||
| + | }); | ||
| + | </ | ||
| + | |||
| + | ==== e2e: tests E2E con Playwright ==== | ||
| + | |||
| + | Los tests E2E prueban la aplicación completa desde el navegador, como lo haría el usuario. Los criterios de aceptación de '' | ||
| + | |||
| + | < | ||
| + | /test e2e create los criterios de aceptación de requirements.md | ||
| + | </ | ||
| + | |||
| + | Cómo trabaja: lee los criterios, abre la aplicación del worktree con el Playwright MCP para ver qué hay en pantalla, escribe el test y lo ejecuta; si falla por un selector o un texto, lo arregla y lo vuelve a pasar. La IA interviene **al generar**, no al ejecutar: lo que queda en el repositorio es un '' | ||
| + | |||
| + | Reglas que la skill tiene que respetar (están en '' | ||
| + | |||
| + | * Selectores por '' | ||
| + | * Un test por criterio de aceptación, | ||
| + | * Los tests cuentan con los datos de prueba del tema 4 y **se pasan sobre la base de datos recién reseteada**. | ||
| + | |||
| + | ===== Ejecutarlos: | ||
| + | |||
| + | Ejecuta los tests de un tipo y, si algo sale en rojo, lo explica: qué test, qué esperaba, qué ha pasado y dónde mirar. Por dentro son los comandos del tema 4, que es lo que ejecuta CI sin ninguna skill: | ||
| + | |||
| + | ^ Verbo ^ Comando ^ | ||
| + | | ''/ | ||
| + | | ''/ | ||
| + | | ''/ | ||
| + | | ''/ | ||
| + | |||
| + | No hay un «todos» a propósito: los tipos se lanzan **uno a uno**, en ese orden, para saber en cada momento qué se está probando y contra qué. Para que '' | ||
| + | |||
| + | ===== Repararlos: /test < | ||
| + | |||
| + | Pasa mucho: se cambia algo del código, se refactoriza, | ||
| + | |||
| + | < | ||
| + | /test e2e repair | ||
| + | </ | ||
| + | |||
| + | El criterio es la **intención**: | ||
| + | |||
| + | * Un test está desactualizado solo si un cambio **intencionado** del código (un commit, o un cambio sin commitear que el alumno ha hecho a propósito) modificó o eliminó lo que el test comprueba: el texto de un mensaje, un campo, un flujo. Entonces se actualiza el test. | ||
| + | * Sin un cambio intencionado que lo justifique, el fallo es una **regresión**: | ||
| + | * Si no se sabe, **no se toca nada** y se pregunta. | ||
| + | |||
| + | Y tres reglas que no se negocian, porque sin ellas «reparar» acaba siendo «hacer que pase»: | ||
| + | |||
| + | * Nunca quita, comenta ni relaja una aserción, salvo que el cambio intencionado lo obligue. Nunca crea tests nuevos: para eso está '' | ||
| + | * Borra un test solo si lo que comprobaba ya no existe en la aplicación, | ||
| + | * Un test cada vez, sin commits, y al final una tabla: test, diagnóstico (desactualizado / regresión / sin determinar) y qué se ha cambiado. El alumno la lee y decide si está de acuerdo. | ||
| + | |||
| + | '' | ||
| + | |||
| + | ===== La revisión: /code review ===== | ||
| + | |||
| + | Sin pull request nadie mira el código antes de que llegue a '' | ||
| + | |||
| + | < | ||
| + | /code review | ||
| + | </ | ||
| + | |||
| + | Una sola revisión que mira dos cosas, el código y los tests, y que **no toca nada y no bloquea**: deja cada hallazgo como una tarea '' | ||
| + | |||
| + | ==== El código: contra la spec y las reglas ==== | ||
| + | |||
| + | Compara el diff de la rama contra '' | ||
| + | |||
| + | * **La spec del issue**: ¿hace lo que se pidió, y como se pidió? ¿Falta algún criterio de aceptación? | ||
| + | * **Las convenciones** ('' | ||
| + | * **Las reglas de calidad** de '' | ||
| + | |||
| + | Cada hallazgo lleva la **regla** incumplida, el **sitio** ('' | ||
| + | |||
| + | Un hallazgo bien hecho y dos mal hechos: | ||
| + | |||
| + | < | ||
| + | GRAVE PedidoService.java: | ||
| + | | ||
| + | | ||
| + | |||
| + | MAL " | ||
| + | (no mira las clases hermanas: todos los servicios lo escriben así; y no dice qué cuesta) | ||
| + | MAL "el método es demasiado largo" | ||
| + | (sin regla ni coste: es una opinión) | ||
| + | </ | ||
| + | |||
| + | Los graves se corrigen. Los mejorables los decide el alumno: o se dejan abiertos para que se corrijan con los graves, o se cierran a mano con un «no se hace, es así a propósito». Un hallazgo cerrado así no bloquea nada. | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | ==== calidad-codigo: | ||
| + | |||
| + | '' | ||
| + | |||
| + | < | ||
| + | .claude/ | ||
| + | ├── SKILL.md | ||
| + | ├── metodos.md | ||
| + | ├── clases.md | ||
| + | ├── comentarios.md | ||
| + | └── tests.md | ||
| + | </ | ||
| + | |||
| + | **La máxima**: el código se escribe para que **una persona lo entienda al leerlo** y para que **un agente lo pueda modificar sin equivocarse**. Consecuencia que lo cambia todo: una repetición pequeña y visible es aceptable; una indirección para ahorrar dos líneas (un método que solo reenvía, un genérico) no lo es, porque el agente no olvida los dos sitios que hay que tocar y la persona sí pierde el hilo. | ||
| + | |||
| + | Cuando dos reglas chocan, gana la primera de esta lista: mantenibilidad, | ||
| + | |||
| + | ^ Fichero ^ Reglas (las que entran; se amplía con lo que salga en las revisiones) ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | Y en '' | ||
| + | |||
| + | La '' | ||
| + | |||
| + | ==== Los tests: contra los criterios ==== | ||
| + | |||
| + | La misma revisión mira después los tests del issue: que **cada criterio de aceptación** de '' | ||
| + | |||
| + | ==== Las correcciones: | ||
| + | |||
| + | < | ||
| + | /code impl .kiro/ | ||
| + | </ | ||
| + | |||
| + | El mismo ''/ | ||
| + | |||
| + | ===== Lo que comprueba /git-flow finish ===== | ||
| + | |||
| + | Con los tests y la revisión, '' | ||
| + | |||
| + | - '' | ||
| + | - '' | ||
| + | - Los cuatro tipos de tests en verde: '' | ||
| + | |||
| + | Si está todo, hace lo del tema 3: '' | ||
| + | |||
| + | ===== Ejercicios ===== | ||
| + | |||
| + | ==== Ejercicio 1 ==== | ||
| + | * Crea un issue «Skill /test: create» e inícialo. | ||
| + | * Instala Playwright en '' | ||
| + | * Escribe la skill ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * Finaliza el issue. | ||
| + | |||
| + | ==== Ejercicio 2 ==== | ||
| + | * Crea un issue «Skill /test: run y repair» e inícialo. | ||
| + | * Añade el verbo '' | ||
| + | * Introduce un error a mano en una validación del servicio, reconstruye el backend y lanza ''/ | ||
| + | * Añade el verbo '' | ||
| + | * Cambia a propósito el texto de un mensaje de error del formulario y lanza ''/ | ||
| + | * Finaliza el issue. | ||
| + | |||
| + | ==== Ejercicio 3 ==== | ||
| + | * Crea un issue «Skill /code» e inícialo. | ||
| + | * Escribe la skill de conocimiento '' | ||
| + | * Añade a la skill ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * Finaliza el issue. | ||
| + | |||
| + | ==== Ejercicio 4 ==== | ||
| + | * Crea un issue «finish comprueba» e inícialo. | ||
| + | * Amplía ''/ | ||
| + | * Deja una tarea sin marcar en '' | ||
| + | |||
| + | ==== Ejercicio 5 ==== | ||
| + | * Crea un issue para la segunda entidad de tu proyecto e inícialo. Es el primer issue que se hace con el arnés entero. | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
| + | * ''/ | ||
clase/daw/daw-proyecto/tema06.1791913338.txt.gz · Última modificación: por Lorenzo
