Nivel inicial14 min de lectura · Publicado el

Algoritmo TDD: el ciclo rojo, verde, refactor y sus reglas

Algoritmo TDD: el ciclo rojo, verde y refactor dibujado como una rueda, con una flecha que vuelve del refactor al rojo para el siguiente test. Rojo, verde, refactor: el ciclorubentejera.com ROJOel test fallaVERDEcódigo mínimoREFACTORordena el códigosiguiente test
Rojo, verde, refactor y vuelta al rojo con el siguiente test. Normalmente quien escribe el test lo hace pasar (en pareja se pueden alternar); con un agente, los pasos se pueden repartir entre persona y agente.

TDD (Test Driven Development, desarrollo dirigido por tests) se explica en una frase, pero se aplica mal con facilidad: se escriben varios tests de golpe, se programa más de la cuenta o se salta el refactor. Este artículo va a lo concreto: el diagrama del algoritmo y las reglas de cada paso. Si aún no sabes qué es TDD, empieza por Qué es TDD.

Es como un sastre. Toma una medida, corta solo lo que esa medida pide y ajusta las costuras sin cambiar la talla. Después, la siguiente medida. La medida es el test; el corte, el código mínimo; y el ajuste, el refactor. Normalmente quien escribe el test lo hace pasar (en pareja se pueden alternar); con un agente, los pasos se pueden repartir entre persona y agente (interpretación nuestra). El símil acierta también aquí: una medida mal tomada da una prenda que no sienta bien, y un test mal escrito tampoco te protege.

El diagrama del algoritmo TDD

El algoritmo solo consta de tres pasos:

  1. Escribir la especificación del requisito: el ejemplo, el test. Es el paso rojo, porque el test falla.
  2. Implementar el código según dicho ejemplo. Es el paso verde, porque el test pasa.
  3. Refactorizar para eliminar duplicidad y hacer mejoras.

Los colores vienen de las herramientas de tests, que pintan en rojo lo que falla y en verde lo que pasa. Con el paso previo de la lista de casos, el ciclo completo queda así:

Diagrama de flujo del algoritmo TDD: la lista de casos que quieres cubrir; rojo, un test nuevo que falla; verde, lo mínimo para que pasen todos; refactor, mejorar el diseño con todo en verde; y la pregunta «¿quedan casos en la lista?»: si quedan, vuelta a rojo; si no, terminado.
Se lee de arriba abajo. La lista de casos se escribe antes de empezar y el rombo decide: mientras queden casos, vuelta a rojo; cuando no quedan, se termina.

Kent Beck, que popularizó TDD, describe este mismo flujo en cinco pasos en su artículo Canon TDD (2023): escribir la lista de escenarios, convertir exactamente uno en un test ejecutable, hacer que pasen ese test y todos los anteriores, refactorizar si hace falta y volver al segundo paso hasta vaciar la lista. Tienes los cinco pasos detallados en Qué es TDD.

Las reglas de cada paso

Rojo: escribir la especificación

Una vez tenemos claro el requisito, lo expresamos en forma de código.

¿Cómo se escribe un test para un código que no existe? Un test, al principio, no es un test, sino un ejemplo o una especificación: describe cómo queremos que se comporte el código. Y se puede modificar; no es algo inamovible.

Para escribirlo, primero pensamos cómo será la API del elemento que vamos a implementar, es decir, cómo se va a usar desde fuera. Solo una parte pequeña y bien definida. Imaginamos cómo sería el código si ya existiera y cómo comprobaríamos que hace lo que le pedimos.

Las reglas de este paso:

  • Un solo test cada vez. Beck señala como error convertir toda la lista en tests antes de hacer pasar ninguno: si el primero te obliga a cambiar de idea, tendrás que rehacer todos los demás.
  • Ejecútalo y míralo fallar. Un test que nunca has visto en rojo puede estar pasando por casualidad.
  • Que falle por el motivo correcto. No basta con un error cualquiera: debe fallar porque el código todavía no hace lo que el test pide.
  • Con una comprobación de verdad. Un test sin comprobaciones (assertions) siempre pasa y no demuestra nada.

Verde: implementar el código

Con el ejemplo escrito, codificamos lo mínimo necesario para que se cumpla y pase el test. No importa que el código parezca feo o chapucero.

La máxima en este paso es no implementar nada más que lo estrictamente obligatorio para cumplir la especificación. Hay que estar concentrado para cumplirla, porque casi siempre escribimos más código del que hace falta.

Las reglas de este paso:

  • Tienen que pasar todos los tests, no solo el nuevo. Si rompes uno anterior, todavía no estás en verde.
  • Que pase de verdad. No borres comprobaciones ni copies el resultado que da el código como valor esperado: así el test confirma lo que hace el código, no lo que debería hacer.
  • Las dudas, a la lista. Si te vienen a la cabeza casos nuevos o caminos que pueden entrar en juego, apúntalos para retomarlos en las siguientes vueltas. No los programes ahora.
  • No ordenes todavía. Primero que funcione; después, que quede bien.

Refactor: mejorar el diseño

Refactorizar no es reescribir el código. Es cambiar su diseño sin alterar su comportamiento y, a ser posible, sin alterar su API pública.

Es el momento de:

  • Detectar malos olores (code smells, señales de que algo está mal diseñado) y eliminarlos.
  • Buscar líneas duplicadas en el código y en los tests, y eliminarlas.
  • Revisar que el código cumple principios de diseño como SOLID.
  • Dejar el código más claro y fácil de mantener: nombres que se entiendan, funciones pequeñas.

La clave de un buen refactor es avanzar en pasos muy pequeños (baby steps). Tras cada cambio se ejecutan todos los tests y, si siguen en verde, se hace el siguiente cambio pequeño.

Las reglas de este paso:

  • Solo con todo en verde. Si un test falla, no refactorices: primero vuelve a verde.
  • Nada de funcionalidad nueva. Si se te ocurre un caso, va a la lista y entrará con su propio test rojo.
  • Sin pasarte. Beck avisa contra refactorizar más de lo que necesitas ahora y contra abstraer demasiado pronto: para él, la duplicación es una pista, no una orden.

Es el paso que más se olvida. Es fácil caer en la rutina de escribir el test, luego la implementación y pasar al siguiente sin refactorizar. Martin Fowler cuenta que saltárselo es la forma más común de estropear TDD de la que oye hablar, en Test Driven Development: el resultado es un montón de código desordenado, eso sí, con tests.

En verde se hace funcionar; en refactor se hace bien.

Un sombrero cada vez

Beck habla de no llevar «dos sombreros» a la vez: o estás añadiendo comportamiento o estás mejorando el diseño, pero no las dos cosas al mismo tiempo.

Sombrero de verde

  • Hay un test en rojo
  • Añades el comportamiento que pide
  • Vale un código feo
  • Terminas cuando todo está en verde

Sombrero de refactor

  • Todo está en verde
  • No añades comportamiento
  • Mejoras nombres, estructura y duplicados
  • Terminas sin haber roto ningún test

Las tres leyes de TDD

Robert C. Martin (Uncle Bob) resume las reglas de rojo y verde en tres leyes, que recoge en The Cycles of TDD (2014). En traducción propia:

  1. No puedes escribir código de producción sin antes tener un test que falle.
  2. No puedes escribir más test del necesario para que falle, y no compilar también cuenta como fallar.
  3. No puedes escribir más código de producción del necesario para que pase el test que está fallando.

Martin distingue dos ritmos. Las tres leyes se siguen casi segundo a segundo, mientras escribes un test. El ciclo rojo, verde, refactor va minuto a minuto. Si una vuelta te dura horas, el paso que has dado es demasiado grande.

El algoritmo en marcha: años bisiestos

Un ejemplo corto para ver las reglas en acción. Un año es bisiesto si es divisible entre 4, salvo que sea divisible entre 100; pero los divisibles entre 400 sí lo son.

Primero, la lista de casos:

  • 2024 es bisiesto (divisible entre 4).
  • 2023 no es bisiesto.
  • 1900 no es bisiesto (divisible entre 100).
  • 2000 es bisiesto (divisible entre 400).

Y estas son las vueltas del ciclo:

Vuelta Rojo: test nuevo Verde: lo mínimo para que pasen todos
1 2024 es bisiesto return true;
2 2023 no es bisiesto return anio % 4 === 0;
3 1900 no es bisiesto return anio % 4 === 0 && anio % 100 !== 0;
4 2000 es bisiesto return (anio % 4 === 0 && anio % 100 !== 0) || anio % 400 === 0;

En la primera vuelta, return true parece una trampa, pero es justo lo que pide la tercera ley: no hace falta más para que pase ese test. Es el segundo caso el que obliga a escribir la regla de verdad.

En la primera vuelta conviene crear la función vacía, export function esBisiesto(anio) {}, para que el test falle por el comportamiento y no por un error de importación.

Al terminar la cuarta vuelta, la condición funciona pero cuesta leerla. Toca refactor: el mismo comportamiento, con las reglas en el orden en que se explican.

// bisiesto.js
const esDivisibleEntre = (anio, divisor) => anio % divisor === 0;

export function esBisiesto(anio) {
  if (esDivisibleEntre(anio, 400)) return true;
  if (esDivisibleEntre(anio, 100)) return false;
  return esDivisibleEntre(anio, 4);
}
// bisiesto.test.js
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { esBisiesto } from './bisiesto.js';

test('2024 es bisiesto porque es divisible entre 4', () => {
  assert.equal(esBisiesto(2024), true);
});

test('2023 no es bisiesto porque no es divisible entre 4', () => {
  assert.equal(esBisiesto(2023), false);
});

test('1900 no es bisiesto porque es divisible entre 100', () => {
  assert.equal(esBisiesto(1900), false);
});

test('2000 es bisiesto porque es divisible entre 400', () => {
  assert.equal(esBisiesto(2000), true);
});

Con un package.json que contenga {"type":"module"}, se ejecuta sin instalar nada:

node --test
✔ 2024 es bisiesto porque es divisible entre 4
✔ 2023 no es bisiesto porque no es divisible entre 4
✔ 1900 no es bisiesto porque es divisible entre 100
✔ 2000 es bisiesto porque es divisible entre 400
ℹ tests 4
ℹ pass 4
ℹ fail 0

Los tests no han cambiado durante el refactor y siguen en verde: esa es la prueba de que el comportamiento es el mismo.

Cuándo adaptar el algoritmo

Con una tecnología nueva: primero un spike

La primera vez que usas una tecnología, o incluso una librería nueva, no conoces sus límites ni sus puntos fuertes.

En Extreme Programming (XP) se habla de spikes. Un spike es un programa muy sencillo que se escribe para explorar la herramienta y resolver una duda técnica concreta. Según la página de XP sobre los spikes, la mayoría no merecen conservarse, así que se escriben esperando tirarlos.

Sin un conocimiento básico de la API y de las restricciones del sistema, no es recomendable lanzarse a escribir especificaciones. Carlos Blé, en Diseño Ágil con TDD, considera un antipatrón intentar practicar TDD en un entorno desconocido. Respeta el tiempo de aprendizaje con la herramienta y vuelve al ciclo cuando tengas confianza con ella. Blé añade un matiz: si el spike es pequeño y su código vale tal cual, se le escribe el test justo después.

En medio de un proyecto

Para los requisitos nuevos, los tres pasos se siguen igual.

Para las partes antiguas que no tienen tests de ningún tipo (legacy code), antes de tocar nada se escriben tests que fijen cómo se comporta hoy: tests de sistema, que prueban la aplicación entera desde fuera, y, si el código lo permite, tests unitarios, que prueban piezas pequeñas. A estos tests que retratan el comportamiento actual se les suele llamar tests de caracterización. Con ellos, los cambios tienen menos efectos secundarios inesperados. A partir de ahí, lo nuevo entra con el ciclo de siempre.

Cómo empezar a usar TDD en un proyecto real lo tienes en Pasos para aplicar TDD.

¿Para qué perfil de programador sirve?

TDD vale tanto para perfiles expertos como para quien empieza.

Una persona experta será capaz de anticipar casos de uso y problemas futuros, y diseñará la API con más cuidado test tras test, aplicando las buenas prácticas que conoce.

Quien empieza probablemente escriba lo que mejor le parece, sin saber que esa solución puede traerle quebraderos de cabeza más adelante. La ventaja es que, cuando se dé cuenta de que su diseño se puede mejorar y empiece a refactorizar, tendrá detrás el respaldo de una batería de tests. Y como cada test le obliga a usar su propia API, por poco experimentado que sea, evitará diseñar una que le resulte casi imposible de usar.

El algoritmo cuando programa la IA

En IA Limpia, el enfoque de Rubén para programar con IA, las reglas del ciclo no cambian cuando el código lo escribe un agente; lo que cambia es quién tiene que vigilarlas. Como criterio:

  • Una vuelta por petición. Un test, su código mínimo y, si toca, su refactor. A nuestro juicio, un agente tiende a escribir mucho código de golpe, justo lo que prohíbe la tercera ley.
  • Mira el rojo. Comprueba que el test nuevo falla antes de pedir el código, igual que harías tú.
  • Los tests no se tocan en verde. Si el agente borra una comprobación o cambia un valor esperado para que pase, es el mismo error de la regla de verde, solo que más rápido.
  • El refactor, con los tests quietos. Si en refactor cambian los tests, ya no tienes la prueba de que el comportamiento es el mismo.

Tienes un ejemplo de instrucciones para un agente en Qué es TDD.

Tu chuleta

Paso Qué haces Qué no haces
Lista Apuntar los casos que quieres cubrir Decidir cómo será el código por dentro
Rojo Un test, y verlo fallar por el motivo correcto Escribir varios tests de golpe
Verde Lo mínimo para que pasen todos los tests Ordenar, generalizar o añadir casos no pedidos
Refactor Mejorar el diseño en pasos pequeños, con todo en verde Añadir comportamiento o cambiar los tests

Siguiente paso: copia el ejemplo de los bisiestos, borra bisiesto.js y repite las cuatro vueltas tú mismo, ejecutando node --test en cada paso.

Fuentes

Consultadas el 7 de noviembre de 2026.

  • Carlos Blé, Diseño Ágil con TDD (primera edición, 2010). Era la fuente del artículo original: los tres pasos, las reglas de cada uno, los spikes, TDD en medio de un proyecto y los perfiles de programador, reescritos con palabras propias. Más sobre el libro y sus ediciones en Libro TDD de Carlos Blé.
  • Kent Beck, Canon TDD (11 de diciembre de 2023): los cinco pasos, los errores de cada paso, los «dos sombreros» y «la duplicación es una pista, no una orden», en resumen y traducción propios.
  • Martin Fowler, Test Driven Development (versión del 11 de diciembre de 2023; la original es de 2005): olvidar el refactor como el error más común que oye.
  • Robert C. Martin, The Cycles of TDD (17 de diciembre de 2014): las tres leyes, en traducción propia, y los ritmos de cada ciclo.
  • Don Wells, Create a Spike Solution, extremeprogramming.org: qué es un spike y por qué se tira.
  • Documentación oficial de Node.js 24: Test runner (node:test).
  • El ejemplo se ha ejecutado vuelta a vuelta, en rojo y en verde, con Node.js 24.21.0 en Ubuntu 26.04, sin dependencias. Las salidas son reales, recortadas para quitar los tiempos y algunos contadores.