Por qué los tests van a reemplazar tus documentos de Markdown cuando trabajas con IA
1. El problema con los specs en Markdown
Todos los que usamos IA para programar hemos pasado por lo mismo. Escribes un documento largo y detallado con todo lo que quieres que haga tu sistema — el famoso PRD — se lo pasas al modelo, y funciona. Al principio.
El problema llega cuando tienes que cambiar algo. Ahora necesitas actualizar el documento, volver a cargarlo entero en el contexto del modelo, y pedirle que aplique el cambio. Tu spec tiene 500 líneas. El código generado otras 300. Y cada iteración consume contexto releyendo todo. Pero no es solo un tema de tokens — es que cuando le metes al modelo demasiada información que no es relevante para lo que le estás pidiendo, se confunde. El modelo necesita que le pases solo lo necesario. Y nada más.
Y hay un problema más de fondo: el spec y el código son dos cosas separadas que tienes que mantener sincronizadas a mano. Y eso no pasa nunca. Con el tiempo el código evoluciona, el spec se queda viejo, y la “fuente de verdad” se parte en dos: un documento que ya no refleja la realidad y un código que nadie documenta.
La comunidad ha intentado solucionar esto troceando el spec en archivos pequeños, usando diffs en vez del documento completo, o con convenciones tipo CLAUDE.md que actúan como contexto persistente. Todo eso ayuda, pero no resuelve el problema de raíz: seguimos manteniendo documentación separada del código.
2. La idea: que los tests sean el spec
¿Y si en vez de escribir un documento que describe lo que quieres, escribes tests que lo demuestran?
No es una idea nueva. Dave Farley, el autor de Continuous Delivery y Modern Software Engineering, lo ha dicho claramente: “En el futuro, el código será simplemente especificaciones, y los tests son especificaciones. Nuestros tests serán nuestro código, y el código real será generado por IA.” Farley habla de los acceptance tests como un “lenguaje de programación de quinta generación” donde tú especificas el comportamiento y la IA genera la implementación.
La ventaja sobre un Markdown es brutal: un test es un contrato que la máquina puede verificar. Cuando le dices al modelo “haz que pase este test”, no tiene que interpretar nada ambiguo. El test define exactamente qué entra, qué sale, y qué se espera. El feedback es inmediato: pasa o no pasa.
Y la comunidad ya se está moviendo en esta dirección:
- AAID (Augmented AI Development), de Dawid Dahl, formaliza el workflow de TDD con IA. Su fórmula es clara: “TDD construye la solución, Acceptance Tests confirman que es la solución correcta.”
- Superpowers, el plugin de Jesse Vincent para Claude Code (93.000+ estrellas en GitHub), es radical: si se escribe código antes de que exista un test que falla, lo borra.
- Paul Duvall ha construido apps reales usando ATDD como contrato para la IA.
- Matteo Vaccari apunta que la arquitectura hexagonal es lo que hace viable todo esto en la práctica.
- El informe DORA 2025 confirma que los equipos que practican TDD obtienen mejores resultados cuando incorporan IA.
3. Dos niveles de tests, dos niveles de documentación
Decir “los tests son el spec” está bien como punto de partida, pero falta responder a algo: ¿cómo estructuras los tests para que cubran todo lo que un documento de diseño cubre?
El gap entre arriba y abajo
Cuando diseñas un sistema, normalmente empiezas desde arriba: nombre del proyecto, objetivo, requisitos, arquitectura, componentes. Y vas bajando. Hay un momento en que dejas de mantener el documento y te vas al código. Ahí se abre un hueco entre la visión de alto nivel y la implementación real que nadie mantiene.
Lo que necesitas es algo que conecte ambos mundos sin que tengas que mantener esa conexión a mano. Y resulta que la pirámide de tests hace exactamente eso.
Los BDD te dan la arquitectura de negocio
Los tests de aceptación escritos en BDD (Given/When/Then) describen lo que el sistema hace desde la perspectiva del negocio. Y no de forma superficial — capturan toda la profundidad de las reglas de negocio: precondiciones, flujos, restricciones, dependencias funcionales.
La clave para saber qué va en un BDD es preguntarte: ¿quién toma esa decisión? Si la respuesta es el negocio, el product owner, el cliente — va en BDD. Si es el equipo de desarrollo — es implementación y va en los unitarios.
Por ejemplo: si el negocio dice “usamos Stripe para pagos” porque hay un contrato — eso es regla de negocio, va en BDD. Si el equipo técnico elige Stripe porque les mola pero podrían cambiar mañana — es implementación.
Y esto aplica también a sistemas algorítmicos o matemáticos. Cuando un experto de dominio — un matemático, un analista, un científico — te especifica una fórmula o un algoritmo, esa matemática ES la arquitectura de negocio. Es tan firme como “el usuario debe estar registrado” en una app convencional. Cada fórmula, cada umbral, cada condición es una decisión de negocio que va en un escenario BDD. Si le enseñas esos escenarios al experto, debe poder validarlos sin saber programar.
Los unitarios te dan la arquitectura técnica
Y aquí viene lo más interesante: los tests unitarios, que siempre se han visto como algo redundante o de poco valor (sobre todo cuando prueban capas sin lógica compleja), resulta que ahora tienen un valor nuevo y enorme.
Cuando escribes un unitario y mockeas las dependencias, estás haciendo algo más que verificar una función. Estás declarando el diseño del sistema de forma implícita. Estás diciendo: “existe un componente X que depende de Y y Z, y con estos inputs produce este output.” Eso es un diagrama de arquitectura, pero ejecutable.
Le dice al modelo exactamente qué componentes existen, qué interfaces tienen, qué dependencias reciben, y qué lógica encapsula cada uno. Sin necesidad de un documento de arquitectura aparte.
Si el modelo necesita saber dónde vive cierta lógica para modificarla, lee el unitario y ya está: ve qué componente la encapsula, de qué depende, y qué contrato cumple. No necesita leer 500 líneas de spec — el test de 20 líneas le da justo lo que necesita.
Los unitarios, a través de los mocks, están definiendo el grafo de dependencias del sistema. Algo que antes vivía en diagramas UML que nadie mantenía. Ahora vive en tests que se ejecutan y se verifican en cada commit.
4. Cómo organizar todo esto
Features vs. casos de uso
Un caso de uso es lo que el usuario quiere conseguir de punta a punta. “Quiero generar un informe.” “Quiero procesar un pago.” Es el flujo completo.
Una feature es una pieza que contribuye a ese caso de uso. Encapsula una regla de negocio que puede cambiar independientemente de las demás.
El caso de uso es la composición de features. Es tu test e2e que verifica que todo encaja, sin entrar en los detalles de cada regla.
El criterio para dividir es simple: si dos reglas pueden cambiar independientemente, son features separadas. Y cada escenario BDD debe probar una sola regla. Si falla, tiene que quedar claro qué se rompió — tanto para ti como para la IA.
La estructura de carpetas
tests/
bdd/
use_cases/ ← Lo que el usuario experimenta (flujos e2e)
<caso_de_uso>/
<caso_de_uso>.feature
test_<caso_de_uso>.py
features/ ← Lo que el negocio decide (reglas individuales)
<regla_a>/
<regla_a>.feature
test_<regla_a>.py
<regla_b>/
<regla_b>.feature
test_<regla_b>.py
...
unit/ ← Lo que el equipo técnico diseña (componentes)
test_<componente_a>.py
test_<componente_b>.py
...
Cada nivel cambia a una velocidad distinta:
- Los use cases casi nunca cambian. Solo si el producto cambia de forma fundamental.
- Las features cambian cuando cambia una regla de negocio. Aquí vive el grueso de la especificación.
- Los unitarios cambian cuando el equipo refactoriza o reorganiza componentes.
Y lo más importante: la lista de carpetas en features/ ES tu mapa de reglas de negocio. No necesitas un índice aparte. El sistema de archivos es tu documentación.
5. El enlace entre niveles: por qué las carpetas son suficientes
Uno de los mayores dolores de cabeza al intentar conectar documentación de alto nivel con código de bajo nivel es que los enlaces se rompen. Tags tipo @spec 1.2 en cada test, IDs sincronizados entre documentos — cualquier enlace que tengas que mantener a mano acabará rompiéndose. Y el coste de mantenerlo acaba superando el beneficio.
La solución es más simple de lo que parece: la estructura de carpetas ES el enlace. El PRD reducido apunta a carpetas, no a tests individuales. “Ver tests/bdd/features/ para reglas de negocio.” Una carpeta casi nunca cambia de nombre, así que la referencia es estable.
¿Y las referencias cruzadas? Porque las features no siempre son una jerarquía limpia — a veces son más bien un grafo con relaciones cruzadas. Esto se resuelve solo a través de los unitarios: si dos componentes mockean la misma dependencia, eso te dice que comparten una relación. Un script puede extraer ese grafo directamente de los mocks, sin que mantengas nada a mano.
Y el test de caso de uso actúa como la verificación final: si las piezas no encajan, el e2e falla, y los tests individuales te dicen dónde se rompió la cadena.
6. El PRD que queda: 20 líneas y a correr
En este modelo, el PRD no desaparece — se transforma. Pasa de ser un documento de cientos de líneas a algo de 20-30 que solo tiene:
Qué es y para quién: nombre, objetivo, contexto. Por qué existe este proyecto. Cambia casi nunca.
Stack técnico: lenguajes, frameworks, librerías. Decisiones del equipo.
Dónde está la verdad:
tests/bdd/use_cases/→ flujos completostests/bdd/features/→ reglas de negociotests/unit/→ diseño de componentes
Decisiones de arquitectura que no se derivan de los tests, si las hay.
Todo lo demás — fórmulas, umbrales, clasificaciones, condiciones, flujos, algoritmos — vive en los .feature. Si el experto de dominio necesita validar las reglas, lee los features. Si un desarrollador necesita entender el sistema, navega las carpetas. Si la IA necesita implementar algo, se le pasa solo la carpeta relevante.
El PRD se convierte en lo que siempre debió ser: un documento de contexto estable que responde al “qué” y al “por qué”, delegando el “cómo funciona” a los tests.
7. Cómo se trabaja con IA en este modelo
Arranque del proyecto
Escribes el PRD ligero. Identificas las reglas de negocio y las conviertes en escenarios BDD. Las revisas con el experto de dominio. Generas la estructura de step definitions vacía. Le pides a la IA que implemente feature por feature, pasándole solo los tests de esa feature.
Cuando cambia una regla de negocio
Vas al .feature de la regla afectada. Modificas el escenario. Corres el test: falla (RED). Le pasas a la IA el test fallido y el código del componente afectado — unas 50 líneas de contexto en vez de releer 500+. La IA corrige la implementación (GREEN). Listo.
Cuando refactorizas
Modificas los unitarios para reflejar el nuevo diseño. Los BDD no los tocas porque el comportamiento externo no cambia. Le pides a la IA que haga pasar los unitarios. Verificas los BDD al final para confirmar que todo sigue funcionando. Un refactor interno nunca rompe la especificación de negocio.
Cuando añades una feature nueva
Creas una carpeta nueva en tests/bdd/features/ con su .feature. Actualizas los tests de caso de uso si el flujo e2e cambia. Le pides a la IA que implemente contra los nuevos tests. El resto del sistema no se ve afectado.
8. En resumen
Llevamos décadas diciendo que “la mejor documentación son los tests.” Con la IA, esto deja de ser filosofía y pasa a ser una necesidad práctica.
Un spec en Markdown es un artefacto pasivo que un humano tiene que interpretar y que la IA tiene que releer cada vez. Un test es un artefacto activo que la máquina verifica, que el modelo usa como contrato, y que el desarrollador navega como documentación.
Lo que se propone aquí no es eliminar la documentación — es cambiar su forma:
- Los BDD capturan la arquitectura de negocio — las reglas, las restricciones, los flujos que el experto de dominio ha definido.
- Los unitarios capturan la arquitectura técnica — los componentes, las interfaces, las dependencias que el equipo ha diseñado.
- La estructura de carpetas captura la organización del proyecto.
- Y el PRD se reduce a un documento ligero que apunta a donde vive la verdad.
Esto no es teórico. Está respaldado por el trabajo de Dave Farley (ATDD como especificación ejecutable), Dawid Dahl (AAID), Jesse Vincent (Superpowers), Paul Duvall (ATDD con IA), Matteo Vaccari (arquitectura hexagonal como enabler), y los datos del DORA Report 2025.
El desarrollo con IA no va de escribir código más rápido. Va de especificar mejor. Y la mejor forma de especificar es con tests: precisos, verificables, modulares, y — por primera vez — suficientes para que una máquina genere la implementación completa.
Referencias
- Dave Farley — ATDD & BDD: From Stories to Executable Specifications → courses.cd.training
- Dawid Dahl — AAID: Augmented AI Development → dev.to | GitHub
- Jesse Vincent — Superpowers → GitHub | Blog
- Paul Duvall — ATDD-Driven AI Development → paulmduvall.com
- Matteo Vaccari — Acceptance Tests for AI-assisted Development → matteo.vaccari.name
- Google Cloud / DORA — TDD and AI: Quality in the DORA Report 2025 → cloud.google.com
- Codemanship — Why Does TDD Work So Well In AI-Assisted Programming? → codemanship.wordpress.com