Diseñ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: