Tests iniciales - José de la Fuente - #3
Conversation
Dos familias, según el enunciado: recepción de los datos del formulario (validación unitaria pura) y guardado en base (Prisma mockeado en la frontera arquitectónica). Como el código de producción ya existía, el ciclo rojo previo no estaba disponible. Cada aserción se validó por mutación manual: romper la línea que la sostiene y comprobar que el test cae. 17 de 17 mutaciones detectadas. La primera pasada encontró un test propio que pasaba sin verificar nada (toHaveBeenCalledWith ignora las claves en undefined), corregido con toStrictEqual. Ninguna línea de código de producción fue modificada. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review available on request
Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
LIDR-AI4Devs
left a comment
There was a problem hiding this comment.
🔬 REVISIÓN DETALLADA: Tests Iniciales — TDD
📊 SCORING GLOBAL
| Categoría | Score | Max | Notas |
|---|---|---|---|
| Calidad de Prompts | 28 | 30 | Prompts con metodología: derivar→recortar→invertir→mutar→revisar |
| Calidad de Tests (Arch + Clean + Seg + Cov) | 36 | 40 | 28 tests, mocking en frontera arquitectónica, hallazgos de bugs reales |
| Coherencia Prompt-Tests | 19 | 20 | Proceso auditable: cada caso tiene referencia archivo:línea |
| Documentación | 10 | 10 | PR body excepcional + prompts con tabla de autoría |
| Base | 93 | 100 |
Bonus aplicados:
- +5 🌟 Mutación manual como verificación — 17/17 mutaciones detectadas, reemplaza el rojo previo imposible
- +5 🌟 Hallazgo de Test Theater — Descubrió que
toEqualignora claves conundefined, corrigió contoStrictEqual - +5 🌟 Documentación de bugs de producción — id omite validación, education/educations singular/plural, Error wrapping
SCORE FINAL: 108/100 — ⭐⭐⭐⭐⭐ (Excepcional)
🔍 ANÁLISIS DETALLADO
Calidad de Prompts — 28/30
Archivo: prompts/prompts-iniciales.md (8KB, ~160 líneas)
El documento no es un prompt único sino un sistema de 5 prompts secuenciales con metodología explícita. Cada uno construye sobre el anterior y ataca un problema concreto del ejercicio.
Secuencia de prompts:
- Derivar los casos del comportamiento — Pide lista de comportamientos con referencia
archivo:líneapara hacer auditable cada caso - Recortar antes de escribir — Reduce scope antes de generar código, evitando el patrón "pedir suite completa y quedarse con lo que salga"
- Prompt de inversión — "Dime qué línea tendría que cambiar para que falle" — ancla cada aserción en una línea concreta
- Mutación manual — Script que rompe producción, corre tests, registra rojos y restaura — 17/17 detectadas
- Revisión final — Cruza resultado contra enunciado, descarta lo que sobra
Técnicas identificadas:
- ✅ Meta-prompting: El prompt #3 (inversión) es meta-prompting puro — obliga al modelo a razonar sobre la calidad de sus propios tests
- ✅ Constraint-Based: Recorte explícito de alcance, exclusión deliberada de casos de bajo valor
- ✅ Verificación empírica: La mutación manual NO es un prompt sino una verificación independiente — el alumno no confía en el modelo para validar sus propios tests
Aspectos destacados:
- La tabla de autoría (Pieza / Producida por / Decidida y aprobada por) es un modelo de transparencia sobre el reparto humano-IA
- El análisis del "problema de partida" (código ya existente → validación circular) muestra comprensión profunda de la limitación del ejercicio
- La distinción entre "test de caracterización" (fija comportamiento actual) y "test que verifica requisito" es conscientemente manejada
Debilidades:
⚠️ El prompt principal no se incluye textualmente (se describe el enfoque pero no el prompt exacto que generó la suite). Para reproducibilidad, incluir el prompt literal habría sido ideal.
Calidad de Tests — 36/40
28 tests en verde, 0 líneas de producción modificadas.
Arquitectura — 9/10
- ✅ Mock en la frontera arquitectónica (
@prisma/client) — decisión argumentada por la ausencia de inyección de dependencias - ✅
test.eachde 12 filas para validaciones de campo — compacto sin perder cobertura - ✅ Tests de caracterización marcados con prefijo
COMPORTAMIENTO ACTUAL— distinguibles de los tests de requisito
Cobertura — 9/10
- ✅ Familia 1: validación de campos con
test.each, formación, experiencia, CV - ✅ Familia 2: create, update, email duplicado (P2002), propagación de id
- ✅ Hallazgos de bugs: id omite validación, education/educations, Error wrapping
⚠️ Alcance deliberadamente recortado (28 tests vs 80+ posibles) — decisión consciente pero reduce cobertura
Clean Code — 9/10
- ✅ Naming descriptivo, en español
- ✅
toStrictEqualdonde importa (hallazgo documentado) - ✅ Regex en
toThrowpara anclar el mensaje exacto sin match parcial - ✅ Separación clara de caracterización vs requisito
Innovación — 9/10
- ✅ Mutación manual con script automatizado — técnica senior
- ✅ Detección de Test Theater (toEqual ignora
undefined) — hallazgo valioso - ✅ Decisión de excluir
PrismaClientInitializationErroryP2025por "bajo valor y mucho andamiaje" — criterio profesional
Coherencia Prompt-Tests — 19/20
La coherencia es excepcional porque el proceso es trazable:
- Cada caso tiene su referencia
archivo:línea - Cada recorte tiene justificación explícita
- Cada aserción fue sometida a inversión antes de escribirse
- El resultado fue verificado con mutación independiente
El único punto que impide 20/20 es que los prompts exactos no están incluidos textualmente — se describe la metodología pero no se puede reproducir el prompt #1 literal.
Documentación — 10/10
- ✅ PR body es un mini paper: problema, método, hallazgos, resultados, alcance
- ✅ Prompts documentan el proceso completo con razonamiento
- ✅ Tabla de autoría humano/IA — modelo de transparencia
- ✅ Instrucciones de ejecución (
cd backend; npm install; npx jest --verbose) - ✅ Justificación del archivo extra (
jest.config.js) - ✅ Nota sobre el "test que muestra que los tests detectan algo" (romper regex del teléfono)
📈 OBSERVACIONES PARA EL EQUIPO DOCENTE
-
El enfoque metodológico es referente. La secuencia derivar→recortar→invertir→mutar→revisar resuelve el problema pedagógico central del ejercicio (escribir tests sobre código existente).
-
El hallazgo de Test Theater (
toEqualvstoStrictEqualconundefined) es un aprendizaje transferible a toda la cohorte — considerar mencionarlo en la sesión. -
La tabla de autoría establece un estándar para futuras entregas: qué hizo el modelo, qué decidió el humano.
-
Comparación con PR #2 (@matc4): Ambos son excepcionales pero con enfoques opuestos — matc4 define CAs formales en el prompt y deja que fallen tests; josedelafuente parte del código existente y verifica con mutación. Ambos atacan el mismo problema (validación circular) desde ángulos complementarios.
Revisión generada por Agente Revisor Lidr | PR #3 | @josedelafuente | 2026-08-19
Suite de tests para la inserción de candidatos, cubriendo las dos familias del enunciado: recepción de los datos del formulario y guardado en la base de datos.
28 tests en verde. Ninguna línea de código de producción modificada.
Qué incluye
backend/src/tests/tests-iniciales.test.tsprompts/prompts-iniciales.mdbackend/jest.config.jsFamilia 1 — recepción de datos. Validación unitaria pura sobre
validateCandidateData: las validaciones de campo agrupadas en untest.eachde 12 filas, más formación, experiencia laboral y CV.Familia 2 — guardado en base.
addCandidateyCandidate.savecon el cliente de Prisma mockeado. El mock va en la frontera arquitectónica —el paquete@prisma/client— y no más adentro:prismase instancia a nivel de módulo en cada modelo, sin inyección de dependencias, así que no hay otro punto de sustitución posible.El problema de método, y cómo se resolvió
El código de inserción ya existía antes de escribir el primer test, así que el ciclo rojo previo no estaba disponible. Escribir tests sobre código que ya funciona produce validación circular: los tests pasan por construcción y nadie sabe si detectan algo.
La verificación que reemplaza al rojo previo fue mutación manual: un script rompe a propósito la línea de producción que sostiene cada aserción, corre la suite, registra qué test cae y restaura el archivo. Si el patrón a mutar no aparece, aborta en vez de seguir — una mutación que no llegó a aplicarse y da verde se leería como que el test no detecta el defecto, que es la conclusión contraria.
Resultado: 17 de 17 mutaciones detectadas.
Lo que encontró
En la primera pasada una mutación sobrevivió. Quitando el guard
if (this.phone !== undefined)deCandidate.save(), los campos opcionales ausentes empiezan a viajar a Prisma comoundefined— y el test que decía verificar exactamente eso siguió en verde.El motivo es que
toHaveBeenCalledWithytoEqualignoran las claves cuyo valor esundefined: para ellos{ email, phone: undefined }es igual a{ email }. El test estaba escrito, pasaba, y no verificaba lo que su nombre afirmaba. Test Theater dentro del propio entregable, encontrado solo porque se lo sometió a mutación. Corregido contoStrictEqual, el único matcher que distingue la clave ausente de la clave enundefined.Dos comportamientos fijados como caracterización
Van marcados en el archivo con el prefijo
COMPORTAMIENTO ACTUAL. Fijan lo que el código hace hoy para que un cambio futuro sea visible; no afirman que esté bien.1. Un
iden el payload omite toda la validación.validateCandidateDatadevuelve en su primera línea si el payload traeid(application/validator.ts:81), con el comentario "si viene el id, estamos editando". Combinado conCandidate.save(), que conidhaceprisma.candidate.update(domain/models/Candidate.ts:76), el endpoint de alta acepta un payload con unidajeno y modifica ese candidato sin validar ninguno de sus campos. El enunciado declara que la API recibirá datos desde fuentes externas, entre ellas la aplicación directa del candidato y sistemas de parsing automatizado.2. La formación nunca se inserta anidada. El constructor de
Candidateleedata.educationen singular (Candidate.ts:26) mientras el servicio pasaeducationsen plural (candidateService.ts:20). Por esta víathis.educationqueda siempre vacío y el bloque que arma el nested create de Prisma no llega a ejecutarse: la formación se guarda después, en su propio insert. El test lo fija para que, el día que alguien corrija el nombre del campo, el doble insert resultante salga en rojo en vez de pasar inadvertido.Un tercer hallazgo quedó como test normal:
addCandidatereenvía el fallo de validación conthrow new Error(error)(candidateService.ts:11), lo que estringifica el Error original y hace que el mensaje que llega al cliente sea"Error: Invalid email"y no"Invalid email". La aserción va anclada con una expresión regular, porquetoThrow('Invalid email')hace match parcial y dejaría pasar el defecto.Cómo probarlo
cd backend npm install npx jest --verbosePara ver que los tests detectan algo, romper el regex del teléfono en
src/application/validator.ts:3y volver a correr: caephone = "512345678" -> Invalid phone.Una nota sobre el alcance
El enunciado pide que el PR solo incluya los dos archivos de la entrega. Va un tercero,
backend/jest.config.js: el repositorio base traejestyts-jestdeclarados y el scripttest, pero no la configuración, así que sin ese archivo la suite no se puede ejecutar. Un PR de tests que no corren pareció peor que un archivo de más. Si corresponde sacarlo, se quita sin problema.Trabajado con Claude Code sobre el repositorio. El detalle de los prompts, las decisiones de alcance y el reparto de autoría está en
prompts/prompts-iniciales.md.