Vous êtes sur la page 1sur 31

ndice

TEST DRIVEN DEVELOPMENT.


BREVE RESEA HISTRICA .................................................................................................................. 1 INTRODUCCIN ................................................................................................................................... 2 REQUISITOS ......................................................................................................................................... 3 CICLO DE DESARROLLO CONDUCIDO POR PRUEBAS .......................................................................... 3 1.ELEGIR UN REQUISITO:..................................................................................................................... 3 2.ESCRIBIR UNA PRUEBA: .................................................................................................................... 3 3.VERIFICAR QUE LA PRUEBA FALLA: .................................................................................................. 3 4.ESCRIBIR LA IMPLEMENTACIN: ...................................................................................................... 3 5.EJECUTAR LAS PRUEBAS AUTOMATIZADAS: .................................................................................... 3 6.ELIMINACIN DE DUPLICACIN: ...................................................................................................... 4 7.ACTUALIZACIN DE LA LISTA DE REQUISITOS:................................................................................. 4 PROCESOS ........................................................................................................................................... 4 MANTENER UN JUEGO EXHAUSTIVO DE PRUEBAS DEL PROGRAMADOR. .......................................... 4 TODO CDIGO QUE PASA A PRODUCCIN TIENE SUS PRUEBAS ASOCIADAS. .................................... 5 ESCRIBIR LAS PRUEBAS PRIMERO. ....................................................................................................... 5 LAS PRUEBAS DETERMINAN EL CDIGO QUE TIENES QUE ESCRIBIR................................................... 5 ROLES Y RESPONSABILIDADES ............................................................................................................. 6 CLIENTE. .............................................................................................................................................. 6 DESARROLLADOR. ............................................................................................................................... 6 PRCTICAS. .......................................................................................................................................... 6 REFACTORING. .................................................................................................................................... 6 INTEGRACIN CONTINUA. .................................................................................................................. 7 HERRAMIENTAS FUNDAMENTALES EN EL USO DE TDD ...................................................................... 7 PRUEBAS UNITARIAS. .......................................................................................................................... 8 REPOSITORIOS DE CDIGO.................................................................................................................. 8 SOFTWARE DE INTEGRACIN CONTINUA. .......................................................................................... 8 HERRAMIENTAS DE CONSTRUCCIN AUTOMTICAS. ........................................................................ 8 ADOPCIN Y EXPERIENCIAS................................................................................................................. 8 ENTORNO DE USO. .............................................................................................................................. 9 ESTUDIOS ACTUALES ........................................................................................................................... 9 CARACTERSTICAS.............................................................................................................................. 10 TDD Y SUS NIVELES DE APLICACIN .................................................................................................. 10 ESCRIBIR Y EJECUTAR PRUEBAS: ....................................................................................................... 12 LAS 3 REGLAS DE TDD........................................................................................................................ 12 LOS TRES PASOS DE TDD ................................................................................................................... 12 1. HACER EL TEST AUTOMTICO. ...................................................................................................... 13 2. HACER EL CDIGO MNIMO IMPRESCINDIBLE PARA QUE EL TEST PASE. ..................................... 14 3. REHACER EL CDIGO ..................................................................................................................... 15 COMO AFRONTAR TDD ..................................................................................................................... 16 CMO DE GRANDES DEBEN SER CADA ITERACIN? ....................................................................... 16 NO DEJARSE LLEVAR MIENTRAS RESOLVEMOS UN TEST .................................................................. 17 DEJAR QUE TDD NOS LLEVE AL DISEO ............................................................................................ 18 COMO AFRONTAR TDD ..................................................................................................................... 20 FORTALEZAS Y DEBILIDADES ............................................................................................................. 20 FORTALEZAS ...................................................................................................................................... 21 DEBILIDADES ..................................................................................................................................... 23 i

ndice VENTAJAS .......................................................................................................................................... 23 OTRAS VENTAJAS .............................................................................................................................. 24 LIMITACIONES ................................................................................................................................... 25 CONCLUSIONES ................................................................................................................................. 26 MAPA CONCEPTUAL .......................................................................................................................... 27 CUESTIONARIO ......................................................................................Error! Bookmark not defined. BIBLIOGRAFA .................................................................................................................................... 28

ii

Contenido

TEST DRIVEN DEVELOPMENT

Breve resea histrica Existen antecedentes de utilizacin espordica de tcnicas de tipo Test Driven Development (TDD) que datan de varias dcadas atrs, citndose en particular las tcnicas aplicadas en el proyecto Mercury1 de la NASA en el comienzo de la dcada de 1960, que incluan la planificacin y escritura de las pruebas previo a cada micro incremento [LB03], pero ser a partir de la metodologa Extreme Programming [BA04] [Bec199] [Bec299] que emerge otra vez, difundindose a nivel mundial. Durante la dcada de 1980 y a comienzos de los 90, Kent Beck y Ward Cunningham colaboraron y refinaron sus prcticas con el propsito de lograr que el desarrollo de programas fuera ms adaptativo y orientado hacia las personas [Fow05], apoyndose en ideas y prcticas existentes, con notorias influencias de las ideas de Chistopher Alexander2, Takeuchi & Nonaka3, Jacobsen4 y otros, las cuales se constituyen en sus races [BA04 sec.2] [Bec299] En Marzo de 1996 Kent Beck fue contratado para revisar el proyecto C3 [BA04 cp.17] [Fow07] en Daimler Chrysler, el cual fue restaurado bajo su liderazgo. Esto dio lugar a la formalizacin de la metodologa Extreme Programming, colaborando estrechamente en dicha formalizacin Ward Cunningham y Ron Jeffries. En el ao 1999 Kent Beck publica el libro que puede considerarse como el manifiesto de la metodologa: Extreme Programming Explained: Embrace Change [Bec199]. Una de las prcticas fundamentales de dicha metodologa, Test First Programming, se sustenta en TDD. En tanto, en el mismo ao, Martin Fowler et all publican Refactoring, Improving the Design of Existing Code, [Fow99] considerado una fundamental introduccin a la tcnica de reconstruccin de cdigo, prctica que se aplica en TDD. En Febrero de 2001 se marca otro hito, en Salt Lake City, Utah, al emitirse el

Contenido

Manifiesto para Desarrollo gil de Software [MA01] por parte de un grupo de metodologstas all reunidos, entre los cuales estaban los proponentes de XP. Test Driven Development tendr un gran impulso al ser adoptado por practicantes y defensores de dichas metodologas, con las cuales comparte entre otras caractersticas, el desarrollo iterativo e incremental en muy breves ciclos y el diseo simple inicial. En los aos 2002 y 2003, se publican libros que tratan directamente sobre TDD, presentando y formalizando la disciplina: Test Driven Development by Example5 por Kent Beck [Bec02] y Test-driven development: A Practical Guide6 por David Astels

Introduccin Test Driven Development, TDD o desarrollo orientado a las pruebas, es la tcnica por antonomasia de Extreme Programming, tal y como veremos en las siguiente seccin. Pero tal es su importancia, que mucha gente ya la considera una metodologa independiente, un punto y aparte despus de XP. Podemos tambin sealar que el desarrollo guiado por pruebas, o Test-driven development (TDD) es una prctica de programacin que involucra otras dos prcticas: Escribir las pruebas primero (Test First Development) y Refactorizacin (Refactoring). Para escribir las pruebas generalmente se utilizan las pruebas unitarias (unit test en ingls). En Primer Lugar se escribe una prueba y se verifica que las pruebas fallen, luego se implementa el cdigo que haga que la prueba pase satisfactoriamente y seguidamente se refactoriza el cdigo escrito. El propsito del desarrollo guiado por pruebas es lograr un cdigo limpio que funcione. La idea es que los requisitos sean traducidos a pruebas, de este modo, cuando las pruebas pasen se garantizar que los requisitos se hayan implementado correctamente Realmente podemos considerarla una metodologa ya que presenta un conjunto de prcticas y mtodos de desarrollo, adems de que condiciona la mentalidad de los desarrolladores guindolos a travs del desarrollo y aumentando la calidad del producto final.
2

Contenido

Requisitos Para que funcione el desarrollo guiado por pruebas, el sistema que se programa tiene que ser lo suficientemente flexible como para permitir que sea probado automticamente. Cada prueba ser suficientemente pequea como para que permita determinar unvocamente si el cdigo probado pasa o no la prueba que esta le impone. El diseo se ve favorecido ya que se evita el indeseado "sobre diseo" de las aplicaciones y se logran interfaces ms claras y un cdigo ms cohesivo. Frameworks como JUnit proveen de un mecanismo para manejar y ejecutar conjuntos de pruebas automatizadas. (Wly)

Ciclo de desarrollo conducido por pruebas Antes de comenzar el ciclo se debe definir una lista de requisitos. Luego se comienza el siguiente ciclo: 1. Elegir un requisito: Se elige de una lista el requerimiento que se cree que nos dar mayor conocimiento del problema y que a la vez sea fcilmente implementable. 2. Escribir una prueba: Se comienza escribiendo una prueba para el requisito. Para ello el programador debe entender claramente las especificaciones y los requisitos de la funcionalidad que est por implementar. Este paso fuerza al programador a tomar la perspectiva de un cliente considerando el cdigo a travs de sus interfaces. 3. Verificar que la prueba falla: Si la prueba no falla es porque el requerimiento ya estaba implementado o porque la prueba es errnea. 4. Escribir la implementacin: Escribir el cdigo ms sencillo que haga que la prueba funcione. Se usa la metfora "Djelo simple" ("Keep It Simple, Stupid" (KISS)). 5. Ejecutar las pruebas automatizadas: Verificar si todo el conjunto de pruebas funciona correctamente.

Contenido

6. Eliminacin de duplicacin: El paso final es la refactorizacin, que se utilizar principalmente para eliminar cdigo duplicado. Se hacen de a una vez un pequeo cambio y luego se corren las pruebas hasta que funcionen. 7. Actualizacin de la lista de requisitos: Se actualiza la lista de requisitos tachando el requisito implementado. Asimismo se agregan requisitos que se hayan visto como necesarios durante este ciclo y se agregan requerimientos de diseo Tener un nico repositorio universal de pruebas facilita complementar TDD con otra prctica recomendada por los procesos giles de desarrollo, la "Integracin Frecuente". Integrar frecuentemente nuestro trabajo con el del resto del equipo de desarrollo permite ejecutar toda batera de pruebas y as descubrir si nuestra ltima versin es compatible con el resto del sistema. Es recomendable y menos costoso corregir pequeos problemas cada pocas horas que enfrentarse a problemas enormes cerca de la fecha de entrega fijada.

Procesos. Segn David Astels [32] TDD es un estilo de desarrollo donde mantienes un juego de pruebas del programador exhaustivo, ninguna parte del cdigo pasa a produccin a no ser que pase sus juegos asociados, escribes primero las pruebas y las pruebas determinan el cdigo que necesitas escribir. Veamos en mayor detalle estos principios de TDD:

Mantener un juego exhaustivo de pruebas del programador. Las pruebas del programador prueban que las clases se comporten de la forma esperada, son escritas por los desarrolladores que escriben el cdigo que ser probado. Se llaman pruebas del programador porque aunque se parecen mucho a las pruebas unitarias, se escriben por diferentes motivos. Las pruebas unitarias se escriben para demostrar que el cdigo que t has escrito funciona, las pruebas del programador son escritas para definir que significa que el cdigo funciones. Tambin se llaman as para diferenciarlas de las pruebas escritas por los usuarios.

Contenido

Si utilizas Test Driven Development, dispones de un gran juego de pruebas, esto es as porque no puede haber cdigo sino existen las pruebas que los prueben. Primero escribes las pruebas y luego el cdigo que ser probado, no hay por tanto cdigo sin pruebas, concluyendo que las pruebas son por tanto exhaustivas.

Todo cdigo que pasa a produccin tiene sus pruebas asociadas. Esta caracterstica nos recuerda una propiedad fundamental cuando utilizamos TDD y es que una funcionalidad no existe hasta que tenemos un juego de pruebas que vaya con l. Esta propiedad no brinda la oportunidad de utilizar un par de tcnicas muy comunes como son el refactoring y la integracin continua. Ambas tcnicas solo pueden ser ejecutadas si realmente estamos seguros de que nuestro cdigo sigue cumpliendo unas caractersticas definidas en las pruebas.

Escribir las pruebas primero. Tal y como estamos comentado en cada punto anterior, cuando tenemos una nueva funcionalidad, antes de implementarla debemos escribir sus pruebas. Esta es una de las caractersticas ms extremes de TDD. La manera de proceder es escribir un poco de las pruebas y entonces, escribir un poco de cdigo que las ejecute y las pase, entonces otra vez ampliamos las pruebas, volvemos a escribir cdigo, y as sucesivamente.

Las pruebas determinan el cdigo que tienes que escribir. Estamos limitando la escritura de cdigo a tan solo la prueba que ya tenemos implementada. Solo escribes lo necesario para pasar la prueba, esto quiere decir que haces la cosa ms sencilla para que funcione. Test Driven development como tal, se engloba dentro del ciclo de vida de la metodologa Extreme Programming, en las fases de iteracin, produccin y mantenimiento (ver siguiente apartado sobre Extreme Programming), pero en si ya
5

Contenido

es una metodologa, ya que puede ser aplicada independientemente a XP, en proyecto con Scrum, FDD o metodologas tradicionales. Debido a su radical planteamiento a la hora de escribir cdigo, cambia drsticamente la mentalidad de cualquier equipo de desarrollo, generalmente agilizando los resultados y aumentando la calidad del sistema.

Roles y responsabilidades. Normalmente nos encontraremos con los roles tpicos de un equipo gil y con muchas suerte de XP. Estos son los dos roles que como mnimo debe disponer todo proyecto con TDD:

Cliente. Desarrolla las historias con los desarrolladores, las ordena segn la prioridad y escriba las pruebas funcionales.

Desarrollador. Desarrolla las historias con el usuario, las estima, y entonces toma responsabilidad de su desarrollo utilizando TDD, lo que quiere decir que ejecuta las pruebas, implementa y refactoriza.

Prcticas. Algunas de las prcticas y mtodos que voy a mencionar a continuacin forman parte de la metodologa XP, pero que estn fuertemente vinculados con TDD, ya que sin este o no podran realizarse o bien sera una autntica locura. En concreto estoy hablando de refactoring e integracin continua.

Refactoring.

Contenido

Refactoring es el proceso de aplicar cambios a un cdigo existente y funcional sin modificar su comportamiento externo, con el propsito de mejorar la estructura interna y aumentar su legibilidad y entendimiento. Est muy relacionado con TDD ya que muchas veces duplicamos cdigo e introducimos mucha basura cuando estamos intentando programar algo para que pase unas pruebas especficas. Otro factor es que si no estamos haciendo TDD, es poco recomendable refactorizar el cdigo, ya que es probable que modifiquemos algo que finalmente provoque un error no intencionado. Se suele hacer refactoring cuando existe cdigo duplicado, cuando percibimos que el cdigo no est lo suficientemente claro o cuando parece que el cdigo tiene algn problema.

Integracin contina. Segn Martin Fowler[35], la integracin continua es una prctica de desarrollo del software donde los miembros de un equipo integran su trabajo frecuentemente, normalmente cada persona integra como mnimo una vez al da, teniendo mltiples integraciones al da. Llamamos integracin a la accin de incluir una porcin de cdigo a la totalidad del cdigo fuente de la aplicacin y normalmente situado en un repositorio de cdigo. Cada integracin es verificada mediante una construccin automtica del mismo (incluyendo pruebas), para detectar errores de integracin lo antes posible. Esta prctica reduce los problemas de integracin y permite al equipo desarrollar el software cohesivamente ms rpido. De mismo modo que con la tcnica de refactoring, est ntimamente ligada a TDD, ya que cada vez que se realiza una integracin un juego de pruebas exhaustivo se ejecuta y valida el cdigo introducido. Sin estas pruebas, la integracin continua no tendra sentido, ya que no garantizara ni la cohesin, ni la validez del cdigo integrado.

Herramientas fundamentales en el uso de TDD


7

Contenido

A continuacin mostraremos algunas herramientas fundamentales en el uso de TDD, sin ellas sera imposible realizar las tareas que nos proponen.

Pruebas unitarias. En los ltimos aos TDD ha popularizado el uso de la familia de herramientas xUnit, que son herramientas que te permiten la ejecucin de pruebas unitarias de forma automtica.

Repositorios de cdigo. Es una herramienta obligatoria para el uso de la metodologa TDD. Las ms conocidas son CVS o Subversion y facilitan el control de versiones, acceso e integracin de cdigo.

Software de integracin contina. Existen diferentes aplicaciones web como Hudson, Apache Gump, Cruise Control, etc., el cometido de las cuales es construir la aplicacin a partir del cdigo fuente, normalmente situado en un repositorio de cdigo (subversion, cvs,...) y ejecutar las pruebas especificadas. Si las pruebas son satisfactorias, se despliega en el entorno de produccin, en caso contrario no se incluyen las modificaciones. Este es un proceso que se puede ejecutar varias veces a lo largo del da y garantiza que se realiza la tcnica de integracin continua.

Herramientas de construccin automticas. Ayudan y mucho la utilizacin de herramientas como maven o Ant para la compilacin y ejecucin de las pruebas automticamente.

Adopcin y experiencias.

Contenido

Cuando queremos adoptar una nueva de metodologa de trabajo, al principio suele ser duro y TDD no es una excepcin. En una entrevista al Dr. Hakan Erdogmus, editor jefe de IEEE Software, sobre TDD y partiendo del estudio hecho por Ron Jeffries y Grigori Melnik, publicado como TDD--The Art of Fearless Programming, habla sobre muchos malentendidos sobre TDD y los problemas su adopcin. Hakan comenta que TDD a veces es entendido como un procedimiento de aseguracin de lo calidad, provocando que algunos managers no lo utilicen porque creen que sus equipos ya tienen otros procedimientos que garantizan la calidad. Hakan incide en que originalmente TDD fue pensado como una tcnica para mejorar la productividad y que el aumento de la calidad es un efecto secundario. En cuanto a otros problemas o resistencias a la hora de adoptar TDD, especifica que muchos buenos desarrolladores se resisten a utilizar TDD, simplemente porque no estn dispuestos a cambiar sus hbitos de programacin. Otros impedimentos en la adopcin de TDD que comenta Hakan es la dificultad de practicar TDD a modo personal, en un equipo que no lo usa. Tambin indica que la percepcin de los managers o gestores de proyectos, de la utilizacin de TDD, como un tiempo adicional que podra ser utilizado en otras actividades necesarias, no ayuda en exceso en su adopcin. Podemos encontrar muchas experiencias en las cuales se ha utilizado TDD como parte de Extreme Programming, es ms difcil encontrar experiencia en las cuales se documente la utilizacin de TDD como metodologa aislada, normalmente aparece siempre complementando a otra metodologa.

Entorno de uso. Una condicin sinequanum de la utilizacin de TDD, es que todo el equipo lo haga, no se puede utilizar TDD como una prctica aislada, ya que no tendra ningn tipo de valor.

Estudios actuales.

Contenido

Test Driven development es una de las metodologas con mayor acogida en el campo profesional y que continua expandindose debido a sus buenos resultados. La tendencias actual es integrar TDD independientemente en cualquier metodologa ya sea gil [33] o tradicional y aprovechar los beneficios de practicar una metodologa que siempre permite deshacer los errores, asegurar una calidad del producto y protegerse de errores tanto malintencionados como humanos.

Caractersticas Una ventaja de esta forma de programacin es el evitar escribir cdigo innecesario ("You Ain't Gonna Need It" (YAGNI)). Se intenta escribir el mnimo cdigo posible, y si el cdigo pasa una prueba aunque sepamos que es incorrecto nos da una idea de que tenemos que modificar nuestra lista de requerimientos agregando uno nuevo. La generacin de pruebas para cada funcionalidad hace que el programador confe en el cdigo escrito. Esto permite hacer modificaciones profundas del cdigo (posiblemente en una etapa de mantenimiento del programa) pues sabemos que si luego logramos hacer pasar todas las pruebas tendremos un cdigo que funcione correctamente. Otra caracterstica del Test Driven Development es que requiere que el programador primero haga fallar los casos de prueba. La idea es asegurarse de que los casos de prueba realmente funcionen y puedan recoger un error.

TDD y sus niveles de aplicacin TDD puede ser aplicado a dos niveles, a saber: Nivel de micro-iteraciones: En este nivel el desarrollo es guiado por pruebas unitarias escritas por el propio programador de la aplicacin, donde los pasos son, segn [Bec02]: Rpidamente agregar una prueba. Correr todas las pruebas y comprobar que solo la nueva falla. Hacer un pequeo cambio.
10

Contenido

Correr todas las pruebas y comprobar que pasan satisfactoriamente. Reconstruir para remover duplicaciones.

Lo anteriormente expuesto se puede resumir en el diagrama de actividad de la Figura

Pasos en un ciclo TDD

Las principales tareas se pueden agrupar en Escribir y ejecutar pruebas, Escribir cdigo de produccin y Reconstruccin, detallndose a continuacin:

11

Contenido

Escribir y ejecutar pruebas: La escritura de las pruebas sigue varios patrones identificados y detallados por Beck en [Bec02]. En particular se destaca que las pruebas: o Son escritas por el propio desarrollador en el mismo lenguaje de programacin que la aplicacin, y su ejecucin se automatiza. Esto ltimo es primordial para que obtenga un retorno inmediato, indicndose que el ritmo de cambio entre prueba-cdigo-prueba est pautado por intervalos de no ms de diez minutos. La automatizacin tambin permite aplicar, en todo momento, la batera de pruebas, implicando pruebas de regresin inmediatas y continuas. Las pruebas se deben escribir pensando en primer lugar en probar las operaciones que se deben implementar. Deben ser aisladas, de forma que puedan correrse independientemente de otras, no importando el orden Este aislamiento determinar que las soluciones de cdigo cohesivas y bajo acoplamiento, con componentes ortogonales8. Deben de escribirse antes que el cdigo que se desea probar.

Las 3 reglas de TDD La prctica de TDD puede resumirse en 3 simples reglas: 1. No se puede escribir cdigo productivo, a menos que sea para hacer pasar un test fallido. 2. No se puede escribir ms que lo necesario para que falle un test unitario; los errores de compilacin se consideran fallos. 3. No se puede escribir ms cdigo productivo del estrictamente necesario para hacer pasar un test.

Los tres pasos de TDD En TDD deben seguirse estos tres pasos y en este orden: 1. Hacer un test automtico de prueba, ejecutarlo y ver que falla.
12

Contenido

2. Hacer el cdigo mnimo imprescindible para que el test que acabamos de escribir pase. 3. Arreglar el cdigo, sobre todo, para evitar cosas duplicadas en el mismo. Comprobar que los test sigue pasando correctamente despus de haber arreglado el cdigo. Estos tres pasos deben repetirse una y otra vez hasta que la aplicacin est terminada. Vamos a ver con un poco de detalle qu implica cada uno de estos tres pasos. Por supuesto, con un ejemplo tonto. Supongamos que queremos una clase Matemticas con un mtodo esttico que hace una suma y nos devuelve el resultado.

1. Hacer el test automtico. Lo primero, hacer un test. Puede ser como esto public void testSuma() { assertEquals(5, Matematicas.suma(2,3)); } Lo primero que deberamos ver es que el test ni siquiera compila. No existe la clase Matemticas y, por supuesto, no tiene el mtodo suma(). Y esta es la primera ventaja de TDD. Nos ha obligado a pensar exactamente qu queremos que haga nuestra aplicacin desde fuera de ella. Necesitamos una clase que tenga un mtodo suma() con dos parmetros que nos devuelva el resultado de la suma. Este caso es muy trivial, pero cualquiera que haya programado un poco en serio, sabr que muchas veces no sabemos exactamente qu clases hacer o qu mtodos ponerle exactamente. Es ms, muchas veces perdemos el tiempo haciendo mtodos que pensamos que luego sern tiles, cuando la cruda realidad es que muchas veces no se van a usar nunca. Con TDD slo hacemos lo que realmente necesitamos en ese momento.
13

Contenido

Adems, antes de hacer la implementacin, nos ha obligado a pensar el nombre de la clase y el del mtodo, pensando slo en cmo vamos a verlo desde fuera. Todos los que programamos sabemos que a veces elegir el nombre de las clases no es tan evidente y muchas veces, el nombre va muy ligado a cmo lo implementamos (por ejemplo, ArrayPersonas porque usamos un array, en vez de Personas a secas, o algo ms bonito como la clase Muchedumbre o Pandilla).

2. Hacer el cdigo mnimo imprescindible para que el test pase. Para que el test pase, lo primero que hay que hacer es la clase Matemticas y ponerle el mtodo suma(), que debe devolver algo, cualquier entero, para que al menos compile. public class Matematicas { public static int suma (int a, int b) { return 0; } } Ya compila el test y la clase, pero si ejecutamos el test, fallar, ya que el mtodo devuelve 0 y no 5. Corregimos la clase de la forma ms inmediata posible para que pase el test. Y lo ms inmediato es hacer que devuelva 5. public class Matematicas { public static int suma (int a, int b) { return 5; }

14

Contenido

} Ya est. Todo funciona como debe. Obviamente, poner return 5 no es la solucin correcta y en un caso real tan simple, pondramos directamente return a+b. Pero de momento, djame ponerlo as para poder explicar el siguiente pas.

3. Rehacer el cdigo El tercer paso es arreglar el cdigo. Debemos arreglar sobre todo duplicidades. A veces, estas duplicidades son evidentes (por ejemplo, cdigo repetido), pero otras, como en este caso, no son tan evidentes. Qu hay repetido en este cdigo?. Aparentemente nada, pero pensemos un poco. De dnde sale ese 5?. Lo hemos puesto porque mentalmente hemos hecho la suma 2+3 y sabemos que ese es el resultado. Si no lo hubieramos hecho, habramos puesto return 2+3. Y esa es precisamente la duplicidad. El nmero 2 est repetido en el cdigo: en nuestra clase de test y en nuestra clase Matematicas. Lo mismo con el 3. Podemos eliminar esa duplicidad implementando la solucin obvia: public class Matematicas { public static int suma (int a, int b) { return a+b; } } Bueno, este caso es demasiado simple y en un caso real no haramos tantos pasos para algo tan evidente, bastara hacer el test y poner directamente la implementacin buena. Veamos ahora algunas ideas sobre cmo llevar TDD a la prctica

15

Contenido

Como afrontar TDD El mtodo a seguir es sencillo. Consiste en elegir uno de los requisitos a implementar, buscar un primer ejemplo sencillo del requisito, crear una prueba unitaria, ejecutar la prueba, implementar el cdigo mnimo para superar la prueba y ejecutar de nuevo la prueba para ver que se supera. Obviamente la gracia de ejecutar la prueba despus de crearla es ver que esta falla y que ser necesario hacer algo en el cdigo para que esta pase. A continuacin solo es necesario volver a aplicar el proceso descrito anteriormente hasta haber resuelto la funcionalidad o funcionalidades que se deban implementar. A dems una vez pasada la prueba es necesario revisar el cdigo, por si requiere refactoring. Si es el caso, se revisara, corregir y se ejecutaran las pruebas unitarias, de nuevo. Es importante tener presente que solo se crea un test por iteracin y solo se implementa el cdigo mnimo necesario para resolver ese caso. No es bueno emocionarse implementando y desarrollar ms de lo necesario para resolver el caso de prueba. Si nos vamos por las ramas desarrollando ms casos perderemos una gran parte de la eficacia de este mtodo.

Cmo de grandes deben ser cada iteracin? Hemos visto en el ejemplo de la suma que hemos hecho un test para la suma, hemos hecho una implementacin inmediata y luego hemos refactorizado para llegar a una implementacin buena. Estos pasos son excesivos para una cosa tan simple. En un proyecto real, cmo de grandes son los pasos?. La solucin depende de nosotros, de nuestra experiencia y de nuestra capacidad para programar.

16

Contenido

Los test que hagamos no deben ser muy triviales, de forma que no nos eternicemos haciendo test tontos que se resuelven en cuestin de segundos. Tampoco deben ser muy complejos, de forma que un test no puede llevarnos dos das para codificarlo y otra semana ms para hacer el cdigo necesario para que pase el test y otra semana para hacer el refactor. Debemos hacer test hasta el punto de complejidad en el que todava nos sintamos cmodos programando y teniendo las cosas en la cabeza, pero sin llegar a ser triviales, es decir, que no nos aburramos, pero que tampoco tengamos que pasar ratos largos pensando qu hacer para resolver el test. Por eso, el lmite depende de nuestra capacidad y experiencia. Prcticamente todos somos capaces de implementar un mtodo suma() a la primera. Sin embargo, un mtodo factorial() recursivo puede resultar demasiado para un aprendiz, aunque sea trivial para un programador con buena cabeza y varios aos de experiencia. Un programador novato deber hacer el factorial con un test para el caso trivial de factorial de 1, resolverlo, otro test para otro caso no trivial y resolverlo. El programador avanzado puede hacer el factorial() en un solo paso. Lo ideal es que en hacer un test y el cdigo necesario para que pase dicho test ms la refactorizacin no se tarde ms de un cuarto de hora/media hora. Una indicacin clara de que estamos haciendo pasos muy grandes es que empiecen a fallarnos test inesperadamente. Una cosa es ser consciente de que hemos hecho una modificacin que hace que falle un test antiguo y que lo vamos a arreglar un poco despus, y otra cosa es que cuando creemos que ya hemos acabado, un test nos falle sin esperarlo.

No dejarse llevar mientras resolvemos un test Una vez hecho el test y viendo que falla, debemos hacer el cdigo mnimo necesario para que eso funcione. Es normal, y cualquier programador con experiencia me dar la razn, que mientras estamos codificando nos demos cuenta de posibles fallos, mejoras o necesidades en otras partes del cdigo
17

Contenido

relacionadas con lo que estamos haciendo y que vayamos corriendo a hacerlas. Pues bien, eso es justo lo que NO debemos hacer. Debemos centrarnos en hacer que el test que hemos escrito pase lo antes posible. Un ejemplo sencillo de esto. Imagina que hacemos un mtodo para convertir un String a maysculas. Java ya tiene ese mtodo, pero vamos a hacerlo. Nuestro test dice que si pasamos "pedro" como parmetro, el mtodo nos debe devolver "PEDRO". Nos ponemos a codificar e inmediatamente empezamos a pensar ... "y si me pasan un parmetro null?. Seguro que el cdigo rompe. Tengo que poner un if para comprobar el parmetro...". Pues bien, eso es lo que NO hay que hacer. Codificamos el mtodo suponiendo que el parmetro no es null y luego, ms adelante, hacemos un segundo test para cuando nos pasen un parmetro null. Obviamente, esto vuelve a ser demasiado sencillo, en un caso real quizs el arreglo que creemos necesitar no tiene una solucin tan rpida. Para sentirnos cmodos dejando esas mejoras/modificaciones adicionales sin hacer, lo mejor es en cuanto las veamos, apuntar en una lista la necesidad de hacer ms adelante un test para implementar esa mejora. Una vez apuntado y con la seguridad de que no se nos olvidar, podemos seguir codificando nuestro test actual. Una vez que ese test pasa y hemos hecho el refactor, podemos elegir otro de los test pendientes de la lista. En el ejemplo anterior, mientras codificamos el caso del mtodo en el que el parmetro es correcto, se nos ocurre "qu pasa si me pasan un null?". Pues bien, lo apuntamos en la lista "hacer un test cuando el parmetro es null" y seguimos codificando nuestro test actual (devolver "PEDRO" cuando nos pasan "pedro").

Dejar que TDD nos lleve al diseo El ejemplo de la suma es muy sencillo y la refactorizacin que hicimos para evitar duplicidades es bastante cuestionable. Veamos ahora un ejemplo algo ms complejo en el que la refactorizacin nos lleva a un diseo ms simple.

18

Contenido

Supn que en un primer test debemos poder fijar el sueldo a un Jefe. Hacemos un test simple en el que a una clase Jefe llamamos al mtodo setSueldo() y luego llamando a getSueldo() comprobamos que es correcto. Este primer test es bastante simple y no nos extendemos ms. Supn ahora, en un segundo test, que hacemos lo mismo con un Currito: Fijarle el sueldo. Hacemos un test similar, esta vez para la clase Currito, con su mtodo setSueldo() y getSueldo(). Y ahora llega el momento de refactorizar y evitar duplicidades. Qu tenemos duplicado? Pues dos clases Jefe y Currito que son exactamente iguales, salvo el nombre. Cualquier diseo Orientado a Objetos nos dir que esto es correcto, que es adecuado hacer una clase para cada tipo de empleado. Pero TDD nos indica que debemos simplificar y evitar duplicidades, as que creamos una clase Empleado con mtodos setSueldo() y getSueldo() y borramos las dos clases anteriores Jefe y Currito, adems de rehacer los test. Ya tenemos un diseo mucho ms simple (hay una sola clase y no hay cdigo duplicado) que cumple perfectamente con ambos test. Supn ahora un tercer test, en el que se quiere preguntar e Empleado si tiene derecho a coche de empresa y debe ser cierto slo si es Jefe. Hacemos el test y ... Volvemos a crear Jefe y Currito?. No, de momento no es necesario. Lo ms simple es que empleado en el constructor admita un enumerado cuyos valores sean Jefe o Currito y se lo guarde. Luego, el mtodo tieneCocheEmpresa() devolver true o false en funcin del valor de ese enumerado. Entonces, cundo debemos hacer las clases Jefe y Currito, heredando de Empleado o algo similar?. Pues bien. slo cuando un test nos lo requiera y la solucin ms simple para ese test sea dividir la clase Empleado en dos. La condicin para comprobar el enumerado es una condicin que tampoco debe repetirse en el cdigo. Si en nuestro cdigo de la clase Empleado se empieza a repetir varias veces cosas como

19

Contenido

if (TipoEmpleado.JEFE == tipoEmpleado) { ...el evitar ese if duplicado en varios sitios empieza a invitar a pensar en otra solucin, algo de herencia o quizs polimorfismo

Como afrontar TDD El mtodo a seguir es sencillo. Consiste en elegir uno de los requisitos a implementar, buscar un primer ejemplo sencillo del requisito, crear una prueba unitaria, ejecutar la prueba, implementar el cdigo mnimo para superar la prueba y ejecutar de nuevo la prueba para ver que se supera. Obviamente la gracia de ejecutar la prueba despus de crearla es ver que esta falla y que ser necesario hacer algo en el cdigo para que esta pase. A continuacin solo es necesario volver a aplicar el proceso descrito anteriormente hasta haber resuelto la funcionalidad o funcionalidades que se deban implementar. A dems una vez pasada la prueba es necesario revisar el cdigo, por si requiere refactoring. Si es el caso, se revisara, corregir y se ejecutaran las pruebas unitarias, de nuevo. Es importante tener presente que solo se crea un test por iteracin y solo se implementa el cdigo mnimo necesario para resolver ese caso. No es bueno emocionarse implementando y desarrollar ms de lo necesario para resolver el caso de prueba. Si nos vamos por las ramas desarrollando ms casos perderemos una gran parte de la eficacia de este mtodo.

Fortalezas y Debilidades Test Driven Development presenta , como toda disciplina, defensores y detractores, fortalezas y debilidades; En la literatura es posible encontrar mucha
20

Contenido

informacin acerca de estas, especialmente desde un punto de vista terico. Sera muy til contar con abundante evidencia emprica documentada, para obtener criterios objetivos de valorizacin y para medir adecuadamente los beneficios y perjuicios de su utilizacin as como las mejores prcticas para determinar cundo resulta oportuno adoptarla y para qu tipo de proyectos. Sin embargo, solo

recientemente la informacin de este tipo se est exponiendo y sumariando en publicaciones, como ser [Fit207],[JM07],[MM07] [REA05],[Sin06]] aunque

probablemente sea un importante indicio de que se contar con dicha informacin en el mediano plazo, partiendo de la base que el resurgimiento y formalizacin de la disciplina data de hace pocos aos. Dada esta situacin se opinar acerca de algunas de las fortalezas y debilidades desde un punto de vista terico.

Fortalezas Al elaborar las pruebas primero el programador no siente que la prueba destruye su cdigo. Se invierte la posicin, ahora es el cdigo el que salva la prueba, convirtindose el acto destructivo de la prueba en una carrera de salvar obstculos, paso a paso. Por otra parte, y tal como destacaba Myers en 1975 [Mey04], siendo las pruebas un proceso destructivo se establece una dificultad sicolgica desde el inicio para su correcta elaboracin por parte de los programadores; hecho que TDD ayuda a resolver. Al elaborar sus propias pruebas no som ete su cdigo a pruebas ajenas. Nuevamente se pone la carga en la responsabilidad de elaborar buenos obstculos para un cdigo saludable que deber sortearlos, sin la presin de la competencia. Al automatizar el programador rpidamente obtiene retorno acerca del estado de salud de la aplicacin. Si introduce mejoras en el cdigo o nuevas funcionalidades sabr rpidamente si pasan todas las pruebas. Esto reduce el stress y el temor. La automatizacin as lograda est escrita en el mismo lenguaje en que programa, y acompaa al cdigo. No necesita aprender lenguajes nuevos.
21

Contenido

En cuanto al mtodo, siguiendo el razonamiento empleado por Mugridge en [Mug03], este puede ser explorado desde el valor del mtodo cientfico como una metfora para Test Driven Development, especialmente al considerar la evolucin de la teora y el rol de la reproducibilidad en la experimentacin, lo que le da un enorme valor a la disciplina. En las siguientes figuras se representa dicha metfora alineando las prcticas con el mtodo cientfico:

FDD

Mtodo Cientfico Sin llegar a sostener, al contrario de Mugridge [Mug03], que el resto de los mtodos estn equivocados, es razonable coincidir en la importancia de esta correspondencia.

22

Contenido

Al prevenir defectos, mediante el diseo cont inuo de pruebas, extendiendo la aseveracin de Beizer acerca que el acto de disear pruebas es de las tcnicas ms efectivas de prevencin de defectos [Bei90].

Debilidades Los ciclos extremadamente cortos y el cambio entre pruebas y codificacin de produccin hacen que muchos programadores lo sientan como contrario a su intuicin y desgastante. Exige adems disciplina, responsabilidad y coraje. La imposibilidad de adopcin cuando se utilizan lenguajes de programacin que no cuentan con el marco de pruebas unitarias, o cuando se utilizan herramientas de alto nivel (CASE) para la generacin de cdigo y asistencia al desarrollo que no lo integran. Si bien esto puede resolverse en muchos casos con desarrollo propio, no siempre es posible por problemas de costo y tiempo. Las dificultades o imposibilidad para su adopcin cuando se utilizan herramientas de alto nivel (CASE) para la asistencia al desarrollo o lenguajes de programacin que no adhieren al paradigma de la orientacin a objetos. En las pruebas de aceptacin, donde es ms dificultosa la automatizacin, especialmente pues la prueba puede ser asimilada a un ciclo funcional, lo que acrecienta la complejidad de los casos, con altamente probable intervencin de interfaces, especialmente grficas (GUI), desde las cuales la aplicacin interacta con el usuario. Tambin es de particular importancia a este nivel el tiempo que transcurre entre la elaboracin de la prueba y su ejecucin, que ya no puede medirse en minutos, sino en das o iteraciones, lo cual quita ritmo al proceso y disminuye los aspectos positivos del rpido retorno.

Ventajas La pregunta habitual cuando alguien te habla sobre TDD es Porque es mejor hacer las pruebas antes que el cdigo? Para responder a esta pregunta tenemos que pensar en la forma que se aplica TDD. Por un lado si se implementa y despus se realizan las pruebas estas suelen
23

Contenido

estar condicionadas a lo implementado, con lo que es fcil obviar pruebas u olvidar algunos casos de test. Por otro lado al realizar primero las pruebas se realiza un ejercicio previo de anlisis, en profundidad, de los requisitos y de los diversos escenarios. Eliminando la mayor parte de variabilidad y encontrado aquellos aspectos ms importantes o no contemplados en los requisitos.

El hecho que adems solo se implemente el cdigo necesario para resolver un caso de prueba concreto, pasar la prueba, hace que el cdigo creado sea el mnimo necesario, reduciendo redundancia y los tpicos bloques de cdigo de por si acaso que habitualmente se convierten en cdigo muerto. Obviamente la obtencin de un buen resultado aplicando TDD depende de realizar un conjunto de pruebas unitarias que cubran todos los casos descritos en los requisitos. Es cierto que habr que trabajar la tcnica para realizar buenos test, siendo aqu donde reside una de las mayores dificultades de este mtodo. No obstante hay que remarcar que TDD no solo se basa en las pruebas. Una correcta aplicacin de la etapa de refactoring hace que nuestro cdigo sea ms legible, ptimo y fcil de mantener, factores que no siempre priman en nuestros proyectos. Hay que aplicar concienzudamente el paso de refactor, que es el que aportara un valor extra a nuestro cdigo. Tambin que destacar que dado que el cdigo evoluciona con el paso del tiempo el refactoring debe aplicarse, siempre que sea necesario, tanto al cdigo implementado como a las pruebas unitarias, con el fin de mantenerlas actualizadas, aadiendo nuevos casos, cuando sea necesario, o completndolas al detectar fallos en el cdigo.

Otras Ventajas Los programadores que utilizan el desarrollo guiado por pruebas en un proyecto virgen encuentran que en raras ocasiones tienen la necesidad de utilizar el depurador o debugger.

24

Contenido

A pesar de los elevados requisitos iniciales de aplicar esta metodologa, el desarrollo guiado por pruebas (TDD) puede proporcionar un gran valor aadido en la creacin de software, produciendo aplicaciones de ms calidad y en menos tiempo. Ofrece ms que una simple validacin del cumplimiento de los requisitos, tambin puede guiar el diseo de un programa. Centrndose en primer lugar en los casos de prueba uno debe imaginarse cmo los clientes utilizarn la funcionalidad (en este caso, los casos de prueba). Por lo tanto, al programador solo le importa la interfaz y no la implementacin. Esta ventaja es similar al diseo por convenio pero se parece a l por los casos de prueba ms que por las aserciones matemticas. El poder del TDD radica en la capacidad de avanzar en pequeos pasos cuando se necesita. Permite que un programador se centre en la tarea actual y la primera meta es, a menudo, hacer que la prueba pase. Inicialmente no se consideran los casos excepcionales y el manejo de errores. Estos, se implementan despus de que se haya alcanzado la funcionalidad principal. Otra ventaja es que, cuando es utilizada correctamente, se asegura de que todo el cdigo escrito est cubierto por una prueba. Esto puede dar al programador un mayor nivel de confianza en el cdigo.

Limitaciones El desarrollo guiado por pruebas requiere que las pruebas puedan automatizarse. Esto resulta complejo en los siguientes dominios: Interfaces Grfica de usuario (GUIs), aunque hay soluciones parciales propuestas. Objetos distribuidos, aunque los objetos simulados (MockObjects) pueden ayudar. Bases de datos. Hacer pruebas de cdigo que trabaja con base de datos es complejo porque requiere poner en la base de datos unos datos conocidos antes de hacer las pruebas y verificar que el contenido de la base de datos es el esperado despus de la prueba. Todo esto hace que la prueba sea costosa de codificar, aparte de tener disponible una base de datos que se pueda modificar libremente.

25

Contenido

Conclusiones Seguramente TDD no se convertir en la bala de plata14 [Bro95 cp.16], pero sus fortalezas parecen aventajar en mucho a sus debilidades, la mayora de las cuales radicaran en los problemas que presenta la automatizacin de las pruebas. De all la importancia de investigar, proponer y construir mecanismos que permitan su utilizacin en ambientes de desarrollo que usan modernas herramientas de programacin bajo las cuales no es posible an su utilizacin. La baja penetracin en Uruguay de esta disciplina es probable que se deba, entre otras razones, a la falta del marco adecuado relacionado a las herramientas de desarrollo ms utilizadas.

26

Contenido

Mapa Conceptual
TEST DRIVEN DEVELOPMENT

BREVE HISTORIA

DEFINICION

REGLAS DEL DDT

Existen antecedentes de utilizacin espordica de tcnicas de tipo Test Driven Development (TDD) que datan de varias dcadas atrs, citndose en particular las tcnicas aplicadas en el proyecto Mercury1 de la NASA en el comienzo de la dcada de 1960

Test Driven Development, TDD o desarrollo orientado a las pruebas, es la tcnica por antonomasia de Extreme Programming, tal y como veremos en las siguiente seccin. Pero tal es su importancia, que mucha gente ya la considera una metodologa independiente, un punto y aparte despus de XP.

1. No se puede escribir cdigo productivo, a menos que sea para hacer pasar un test fallido. 2. No se puede escribir ms que lo necesario para que falle un test unitario; los errores de compilacin se consideran fallos. 3. No se puede escribir ms cdigo productivo del estrictamente necesario para hacer pasar un test.

Durante la dcada de 1980 y a comienzos de los 90, Kent Beck y Ward Cunningham colaboraron y refinaron sus prcticas con el propsito de lograr que el desarrollo de programas fuera ms adaptativo y orientado hacia las personas.

27

Contenido

Bibliografa http://c2.com/cgi/wiki?TestDrivenDevelopment http://www.testdriven.com/ http://es.wikipedia.org/wiki/Desarrollo_guiado_por_pruebas http://www.agiledata.org/essays/tdd.html http://blog.lordudun.es/2011/04/introduccion-a-tdd-test-driven-development/ http://www.testdriven.com/

28

Vous aimerez peut-être aussi