Table Of ContentDiseño Ágil con TDD
Carlos Blé Jurado y colaboradores.
Prologo de José Manuel Beas
Primera Edición, Enero de 2010
www.iExpertos.com
El libro se ha publicado bajo la Licencia Creative Commons
2
Índice general
I Base Teórica 27
1. El Agilismo 28
1.1. Modelo en cascada . . . . . . . . . . . . . . . . . . . . . 30
1.2. Hablemos de cifras . . . . . . . . . . . . . . . . . . . . . . 32
1.3. El manifiesto ágil . . . . . . . . . . . . . . . . . . . . . . . 33
1.4. ¿En qué consiste el agilismo?: Un enfoque práctico . . . 36
1.5. La situación actual . . . . . . . . . . . . . . . . . . . . . . 40
1.6. Ágil parece, plátano es . . . . . . . . . . . . . . . . . . . . 42
1.7. Los roles dentro del equipo . . . . . . . . . . . . . . . . . 43
1.8. ¿Por qué nos cuesta comenzar a ser ágiles? . . . . . . . 46
2. ¿Qué es el Desarrollo Dirigido por Tests? (TDD) 48
2.1. El algoritmo TDD . . . . . . . . . . . . . . . . . . . . . . . 51
2.1.1. Escribir la especificación primero . . . . . . . . . . 52
2.1.2. Implementarelcódigoquehacefuncionarelejem-
plo . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
2.1.3. Refactorizar . . . . . . . . . . . . . . . . . . . . . . 53
2.2. Consideraciones y recomendaciones . . . . . . . . . . . . 55
2.2.1. Ventajas del desarrollador experto frente al junior. 55
2.2.2. TDD con una tecnología desconocida . . . . . . . 56
2.2.3. TDD en medio de un proyecto . . . . . . . . . . . 56
3. Desarrollo Dirigido por Tests de Aceptación (ATDD) 58
3.1. Las historias de usuario . . . . . . . . . . . . . . . . . . . 59
3.2. Qué y no Cómo . . . . . . . . . . . . . . . . . . . . . . . . 63
3.3. ¿Está hecho o no? . . . . . . . . . . . . . . . . . . . . . . 66
3.4. El contexto es esencial. . . . . . . . . . . . . . . . . . . . 67
3
ÍNDICEGENERAL ÍNDICEGENERAL
4. Tipos de test y su importancia 68
4.1. Terminología en la comunidad TDD . . . . . . . . . . . . 69
4.1.1. Tests de Aceptación . . . . . . . . . . . . . . . . . 70
4.1.2. Tests Funcionales . . . . . . . . . . . . . . . . . . 71
4.1.3. Tests de Sistema . . . . . . . . . . . . . . . . . . . 71
4.1.4. Tests Unitarios . . . . . . . . . . . . . . . . . . . . 74
4.1.5. Tests de Integración . . . . . . . . . . . . . . . . . 75
5. Tests unitarios y frameworks xUnit 77
5.1. Las tres partes del test: AAA . . . . . . . . . . . . . . . . 78
6. Mocks y otros dobles de prueba 88
6.1. Cuándo usar un objeto real, un stub o un mock . . . . . . 90
6.2. La metáfora Record/Replay . . . . . . . . . . . . . . . . . 101
7. Diseño Orientado a Objetos 104
7.1. Diseño Orientado a Objetos (OOD) . . . . . . . . . . . . . 104
7.2. Principios S.O.L.I.D . . . . . . . . . . . . . . . . . . . . . 105
7.2.1. Single Responsibility Principle (SRP) . . . . . . . 106
7.2.2. Open-Closed Principle (OCP) . . . . . . . . . . . . 107
7.2.3. Liskov Substitution Principle (LSP) . . . . . . . . . 107
7.2.4. Interface Segregation Principle (ISP) . . . . . . . . 108
7.2.5. Dependency Inversión Principle (DIP) . . . . . . . 108
7.3. Inversión del Control (IoC) . . . . . . . . . . . . . . . . . . 109
II Ejercicios Prácticos 111
8. Inicio del proyecto - Test Unitarios 112
9. Continuación del proyecto - Test Unitarios 148
10.Fin del proyecto - Test de Integración 222
10.1.La frontera entre tests unitarios y tests de integración . . 224
10.2.Diseño emergente con un ORM . . . . . . . . . . . . . . . 235
10.2.1.Diseñando relaciones entre modelos . . . . . . . . 237
10.3.La unificación de las piezas del sistema . . . . . . . . . . 238
11.La solución en versión Python 240
12.Antipatronesy Errores comunes 281
4
ÍNDICEGENERAL ÍNDICEGENERAL
A. Integración Continua (CI) 288
A.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . 288
A.2. Prácticas de integración continua . . . . . . . . . . . . . . 291
A.2.1. Automatizar la construcción . . . . . . . . . . . . . 291
A.2.2. Los test forman parte de la construcción . . . . . . 292
A.2.3. Subir los cambios de manera frecuente . . . . . . 293
A.2.4. Construir en una máquina de integración . . . . . 294
A.2.5. Todo el mundo puede ver lo que está pasando . . 294
A.2.6. Automatizar el despliegue . . . . . . . . . . . . . . 295
A.3. IC para reducir riesgos . . . . . . . . . . . . . . . . . . . . 296
A.4. Conclusión . . . . . . . . . . . . . . . . . . . . . . . . . . 297
5
A la memoria de nuestro querido gatito Lito, que vivió con total
atención y entrega cada instante de su vida
6
Prólogo
Éraseunavezqueseera,unlejanopaísdondevivíandoscerditos,
Pablo y Adrián que, además, eran hermanos. Ambos eran los cerditos
más listos de la granja y, por eso, el gallo Iván (el gerente de la mis-
ma) organizó una reunión en el establo, donde les encargó desarrollar
un programa de ordenador para controlar el almacén de piensos. Les
explicó qué quería saber en todo momento: cuántos sacos de grano
había y quién metía y sacaba sacos de grano del almacén. Para ello
sóloteníanunmesperolesadvirtióque,enunasemana,queríayaver
algo funcionando. Al final de esa primera semana, eliminaría a uno de
los dos.
Adrián, que era el más joven e impulsivo, inmediatamente se puso
manosalaobra.“¡Nohaytiempoqueperder!”,decía.Yempezórápida-
mente a escribir líneas y líneas de código. Algunas eran de un reciente
programa que había ayudado a escribir para la guardería de la vaca
Paca. Adrián pensó que no eran muy diferentes un almacén de grano
y una guardería. En el primero se guardan sacos y en el segundo, pe-
queñosanimalitos.De acuerdo,teníaqueretocar algunascosillaspara
que aquello le sirviera pero bueno, esto del software va de reutilizar lo
que ya funciona, ¿no?
Pablo, sin embargo, antes de escribir una sola línea de código co-
menzó acordando con Iván dos cosas: qué era exactamente lo que
podría ver dentro de una semana y cómo sabría que, efectivamente,
estabaterminadacadacosa.Ivánqueríaconocer,tanrápidocomofue-
ra posible, cuántos sacos de grano había en cada parte del almacén
porquesospechabaque,enalgunaspartesdelmismo,seestabanacu-
mulando sacos sin control y se estaban estropeando. Como los sacos
entrabanysalíanconstantemente,nopodíasabercuántoshabíaydón-
deestabanencadainstante,asíqueacordaronircontabilizándolospor
7
Prólogo
zonas y apuntando a qué parte iba o de qué parte venía, cada vez que
entrara o saliera un saco. Así, en poco tiempo podrían tener una idea
clara del uso que se estaba dando a las distintas zonas del almacén.
Mientras Adrián adelantaba a Pablo escribiendo muchas líneas de
código,Pabloescribíaprimerolaspruebasautomatizadas.AAdriáneso
le parecía una pérdida de tiempo. ¡Sólo tenían una semana para con-
vencer a Iván!
Al final de la primera semana, la demo de Adrián fue espectacu-
lar, tenía un control de usuarios muy completo, hizo la demostración
desde un móvil y enseñó, además, las posibilidades de un generador
de informes muy potente que había desarrollado para otra granja ante-
riormente. Durante la demostración hubo dos o tres problemillas y tuvo
que arrancar de nuevo el programa pero, salvo eso, todo fue genial. La
demostración de Pablo fue mucho más modesta, pero cumplió con las
expectativas de Iván y el programa no falló en ningún momento. Claro,
todoloqueenseñólohabíaprobadomuchísimasvecesantesgraciasa
quehabíaautomatizadolaspruebas.PablohacíaTDD,esdecir,nunca
escribíaunalíneadecódigosinantestenerunapruebaqueleindicara
un error. Adrián no podía creer que Pablo hubiera gastado más de la
mitad de su tiempo en aquellas pruebas que no hacían más que retra-
sarle a la hora de escribir las funcionalidades que había pedido Iván.
El programa de Adrián tenía muchos botones y muchísimas opciones,
probablemente muchas más de las que jamás serían necesarias para
lo que había pedido Iván, pero tenía un aspecto “muy profesional”.
Iván no supo qué hacer. La propuesta de Pablo era muy robusta y
hacía justo lo que habían acordado. La propuesta de Adrián tenía cosi-
llasquepulir,peroeramuyprometedora.¡Habíahecholademostración
desde un móvil! Así que les propuso el siguiente trato: “Os pagaré un
50% más de lo que inicialmente habíamos presupuestado, pero sólo
a aquel de los dos que me haga el mejor proyecto. Al otro no le daré
nada.”. Era una oferta complicada porque, por un lado, el que ganaba
se llevaba mucho más de lo previsto. Muy tentador. Pero, por el otro la-
do, corrían el riesgo de trabajar durante un mes completamente gratis.
Mmmmm.
Adrián, tan impulsivo y arrogante como siempre, no dudó ni un ins-
tante. “¡Trato hecho!”, dijo. Pablo explicó que aceptaría sólo si Iván se
comprometía a colaborar como lo había hecho durante la primera se-
mana. A Iván le pareció razonable y les convocó a ambos para que le
enseñaran el resultado final en tres semanas.
AdriánsemarchópitandoyllamóasuprimoSixto,quesabíamucho
yleaseguraríalavictoria,aunquetuvieraquedarlepartedelasganan-
8
Prólogo
cias.Ambossepusieronrápidamentemanosalaobra.MientrasAdrián
arreglaba los defectillos encontrados durante la demo, Sixto se encar-
gó de diseñar una arquitectura que permitiera enviar mensajes desde
el móvil hasta un webservice que permitía encolar cualquier operación
para ser procesada en paralelo por varios servidores y así garantizar
queelsistemaestaríaendisposicióndedarservicio24horasaldíalos
7 días de la semana.
Mientras tanto, Pablo se reunió con Iván y Bernardo (el encargado
del almacén) para ver cuáles deberían ser las siguientes funcionalida-
des a desarrollar. Les pidió que le explicaran, para cada petición, qué
beneficio obtenía la granja con cada nueva funcionalidad. Y así, poco
a poco, fueron elaborando una lista de funcionalidades priorizadas y
resumidas en una serie de tarjetas. A continuación, Pablo fue, tarjeta
a tarjeta, discutiendo con Iván y Bernardo cuánto tiempo podría tardar
en terminarlas. De paso, aprovechó para anotar algunos criterios que
luego servirían para considerar que esa funcionalidad estaría comple-
tamente terminada y eliminar alguna ambigüedad que fuera surgiendo.
Cuando Pablo pensó que, por su experiencia, no podría hacer más tra-
bajo que el que ya habían discutido, dio por concluida la reunión y se
dispusoatrabajar.Antesquenada,resolvióunpardedefectosqueha-
bían surgido durante la demostración y le pidió a Iván que lo validara.
A continuación, se marchó a casa a descansar. Al día siguiente, cogió
la primera de las tarjetas y, como ya había hecho durante la semana
anterior, comenzó a automatizar los criterios de aceptación acordados
con Iván y Bernardo. Y luego, fue escribiendo la parte del programa
que hacía que se cumplieran esos criterios de aceptación. Pablo le ha-
bíapedidoayudaasuamigoHudson,uncoyotevegetarianoquehabía
venidodesdeAméricaapasarelinvierno.Hudsonnosabíaprogramar,
pero era muy rápido haciendo cosas sencillas. Pablo le encargó que
comprobara constantemente los criterios de aceptación que él había
automatizado. Así, cada vez que Pablo hacía algún cambio en su pro-
grama,avisabaaHudsonyestehacía,unatrasotra,todaslaspruebas
de aceptación que Pablo iba escribiendo. Y cada vez había más. ¡Este
Hudson era realmente veloz e incansable!
Amedidaqueibapasandoeltiempo,AdriánySixtoteníancadavez
más problemas. Terminaron culpando a todo el mundo. A Iván, porque
no les había explicado detalles importantísimos para el éxito del pro-
yecto. A la vaca Paca, porque había incluido una serie de cambios en
el programa de la guardería que hacía que no pudieran reutilizar casi
nada. A los inventores de los SMS y los webservices, porque no te-
nían ni idea de cómo funciona una granja. Eran tantos los frentes que
9
Prólogo
tenían abiertos que tuvieron que prescindir del envío de SMS y busca-
ron un generador de páginas web que les permitiera dibujar el flujo de
navegación en un gráfico y, a partir de ahí, generar el esqueleto de la
aplicación. ¡Eso seguro que les ahorraría mucho tiempo! Al poco, Six-
to, harto de ver que Adrián no valoraba sus aportaciones y que ya no
se iban a usar sus ideas para enviar y recibir los SMS, decidió que se
marchaba,aúnrenunciandoasupartedelosbeneficios.Total,élyano
creía que fueran a ser capaces de ganar la competición.
Mientras tanto, Pablo le pidió un par de veces a Iván y a Bernardo
que le validaran si lo que llevaba hecho hasta aquel momento era de
su agrado y les hizo un par de demostraciones durante aquellas 3 se-
manas, lo que sirvió para corregir algunos defectos y cambiar algunas
prioridades.IványBernardoestabanfrancamentecontentosconeltra-
bajo de Pablo. Sin embargo, entre ellos comentaron más de una vez:
“¿Qué estará haciendo Adrián? ¿Cómo lo llevará?”.
Cuandoseacercabalafechafinalparaentregarelprograma,Adrián
se quedó sin dormir un par de noches para así poder entregar su pro-
grama. Pero eran tantos los defectos que había ido acumulando que,
cadavezquearreglabaunacosa,lefallabaotra.Dehecho,cuandolle-
gó la hora de la demostración, Adrián sólo pudo enseñar el programa
instaladoensuportátil(elúnicositiodonde,aduraspenas,funcionaba)
y fue todo un desastre: mensajes de error por todos sitios, comporta-
mientos inesperados... y lo peor de todo: el programa no hacía lo que
habían acordado con Iván.
Pablo, sin embargo, no tuvo ningún problema en enseñar lo que
llevaba funcionando desde hacía mucho tiempo y que tantas veces ha-
bía probado. Por si acaso, dos días antes de la entrega, Pablo había
dejado de introducir nuevas características al programa porque quería
centrarse en dar un buen manual de usuario, que Iván había olvidado
mencionar en las primeras reuniones porque daba por sentado que se
lo entregarían. Claro, Adrián no había tenido tiempo para nada de eso.
Moraleja:
Además de toda una serie de buenas prácticas y un proceso de
desarrollo ágil, Pablo hizo algo que Adrián despreció: acordó con Iván
(el cliente) y con Bernardo (el usuario) los criterios mediante los cuá-
les se comprobaría que cada una de las funcionalidades estaría bien
acabada. A eso que solemos llamar “criterios de aceptación”, Pablo le
añadiólaposibilidaddeautomatizarsuejecucióneincorporarlosenun
proceso de integración continua (que es lo que representa su amigo
Hudson en este cuento). De esta manera, Pablo estaba siempre tran-
quilo de que no estaba estropeando nada viejo con cada nueva modifi-
10
Description:¿Qué es el Desarrollo Dirigido por Tests? (TDD). 48. 2.1. El algoritmo TDD . 4http://www.navegapolis.net/files/Flexibilidad_con_Scrum.pdf.