De dónde viene: contratos, TDD y BDD

Enterate del próximo post
Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.

Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.
El post anterior cerró con una promesa: mostrar que el método que hoy se llama Spec Driven Development no nació en 2025. Lo que sí nació en 2025 fue el nombre, y con él una ola de herramientas y de discusión pública que le da la sensación de ser una idea nueva. La idea de fondo, escribir antes qué tiene que cumplir un sistema, de una forma que se pueda comprobar sin discutir, tiene más de medio siglo, y reconocerla en sus formas anteriores sirve para distinguir qué hay de nuevo de verdad en 2025 y qué es una forma distinta de nombrar algo que ya se sabía hacer.
El primer antecedente directo es de 1969. Tony Hoare publicó una lógica para razonar sobre programas basada en una tripleta {P} S {Q}: P es una precondición, lo que tiene que ser cierto antes de ejecutar una instrucción o un programa S, y Q es una poscondición, lo que S garantiza que va a ser cierto después, siempre que P se haya cumplido. Esa tripleta es, en esencia, una especificación verificable de un fragmento de código, escrita más de medio siglo antes de que alguien necesitara pedirle nada a un agente.
Bertrand Meyer llevó esa idea a un lenguaje de programación real en 1986, con el diseño por contrato del lenguaje Eiffel: cada método de una clase declara su propia precondición y su propia poscondición, y el entorno puede comprobarlas en tiempo de ejecución. El nombre "contrato" no es casual: describe la misma relación que una especificación describe hoy entre quien pide una funcionalidad y quien la construye, qué se garantiza a cambio de qué se exige.
En 2004, dentro de la comunidad de Extreme Programming, James Ostroff, Richard Paige y Sergey Makalsky publicaron una propuesta académica que ya usaba el término "specification-driven development", con una tesis que conecta directo con el post anterior de esta serie: un test y un contrato no son dos cosas distintas, son dos formas de escribir la misma especificación en dos niveles de detalle distintos. Un test fija un caso concreto; un contrato fija una regla que cubre todos los casos que cumplen la precondición. La tesis importa más que el nombre, porque es la misma separación de capas que ya distinguió especificación de implementación, aplicada ahora a explicar por qué un test cuenta como especificación aunque no tenga la forma habitual de una.
El uso industrial más cercano al de hoy aparece en 2016, cuando Sam Hatoum empieza a usar el término para describir un flujo de trabajo concreto en su propia práctica, años antes de que ninguna herramienta lo empaquetara. Y buena parte del vocabulario que van a usar los próximos bloques de esta serie, criterio de aceptación, Dado / Cuando / Entonces, no viene de SDD: viene de Behavior Driven Development (BDD), una práctica de mediados de los 2000 que ya proponía escribir el comportamiento esperado en un formato a la vez legible por una persona y ejecutable por una máquina.
Ninguna de estas cuatro ideas es lo nuevo de 2025. Lo nuevo es el agente: un lector automático de especificaciones lo bastante capaz como para producir código a partir de ellas sin supervisión línea por línea, lo que vuelve rentable escribir specs con un cuidado que antes solo se justificaba en software crítico, aviónica, sistemas médicos, infraestructura financiera, los mismos dominios donde el diseño por contrato ya se usaba antes de que "Spec Driven Development" fuera un término que buscar.
El post anterior pidió que una especificación sea verificable: algo que dos personas puedan comprobar sin discutir, mirando el sistema desde afuera. Esa palabra, verificable, es exactamente lo que Hoare formalizó en 1969 con precondición y poscondición, sin necesitar ningún agente de por medio. Vale la pena aplicar esa forma concreta, una sola vez, sobre la especificación que la Bitácora de lecturas ya tiene escrita: no para cambiarle una sola línea, sino para mostrar que ya cumplía ese formato sin haberlo nombrado así.
## Contrato
Precondición
La URL que llega es un texto no vacío.
Poscondición
Si la URL no estaba guardada antes de esta llamada, existe un artículo
nuevo con esa URL, su título y la fecha de guardado.
Si la URL ya estaba guardada, no se crea ningún artículo nuevo y el
sistema avisa que ya existe.La decisión menos obvia no es la precondición, que apenas repite algo que ya se daba por hecho. Es que la poscondición tiene que cubrir los dos casos posibles, no solo el que sale bien. Una poscondición que dijera únicamente "existe un artículo nuevo con esa URL, su título y la fecha" describiría el camino feliz y dejaría sin decir nada sobre qué tiene que ser cierto cuando la URL ya estaba guardada, exactamente el caso que la especificación original, sin llamarlo poscondición, ya resolvía en su segunda línea. Nombrar la disciplina no agregó ningún caso nuevo a la Bitácora: agregó una regla para no olvidar ninguno.
Sin esa regla, es fácil escribir una poscondición incompleta sin notarlo, porque describir el camino feliz alcanza para que la frase suene terminada. "Existe un artículo nuevo con la URL, el título y la fecha" parece una poscondición completa hasta que se pregunta qué pasa si la URL ya existía, y la respuesta no está en ningún lado: no porque alguien la haya descartado, sino porque nunca hizo falta escribirla para que la frase se sintiera correcta.
Ese hueco no lo detecta ningún test que se corra contra una implementación ya escrita, porque nadie especificó qué buscar: un test verifica que se cumple una poscondición, no puede notar que a una poscondición le falta un caso que nadie mencionó. La verificación llega recién cuando alguien guarda dos veces el mismo artículo, el mismo escenario del primer post de la serie, ahora visible en el lugar exacto donde faltaba: no en la especificación en prosa, que sí lo cubría, sino en la versión más formal que se construyó a partir de ella sin prestarle la misma atención.
La consecuencia práctica es una regla de revisión, no una notación nueva: toda poscondición que se escriba de acá en adelante en esta serie tiene que responder, para cada caso que la precondición permite, qué tiene que ser cierto después. Si un caso queda sin poscondición, no está resuelto: está pendiente, aunque la frase que lo rodea suene terminada.
Un contrato no le agrega a una especificación ninguna herramienta que no tuviera ya. Le pone nombre y disciplina a algo que la spec de la Bitácora, sin saberlo, ya cumplía desde el primer post de la serie.
Ahora que la especificación de guardar un artículo mostró sus tres capas y su primer contrato, queda planteada la crítica más común que recibe Spec Driven Development: que escribir documentos antes de tocar código es, ni más ni menos, volver al desarrollo en cascada que la industria pasó dos décadas desarmando. El próximo post de la serie encara esa acusación de frente, con la intención, la especificación y el contrato de la Bitácora ya escritos como evidencia concreta de qué responde y qué no.