0% encontró este documento útil (0 votos)
149 vistas10 páginas

TDD 2

Este documento describe la técnica de desarrollo de software conocida como Desarrollo Dirigido por Tests (TDD). TDD se centra en tres pilares: implementar solo las funciones necesarias, minimizar defectos, y producir software modular y adaptable. Siguiendo TDD, los desarrolladores escriben pruebas automatizadas antes de implementar el código, lo que ayuda a diseñar software de alta calidad de forma incremental. TDD también produce una arquitectura que emerge naturalmente de las pruebas automatizadas.

Cargado por

Mezala MQ
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
149 vistas10 páginas

TDD 2

Este documento describe la técnica de desarrollo de software conocida como Desarrollo Dirigido por Tests (TDD). TDD se centra en tres pilares: implementar solo las funciones necesarias, minimizar defectos, y producir software modular y adaptable. Siguiendo TDD, los desarrolladores escriben pruebas automatizadas antes de implementar el código, lo que ayuda a diseñar software de alta calidad de forma incremental. TDD también produce una arquitectura que emerge naturalmente de las pruebas automatizadas.

Cargado por

Mezala MQ
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 10

Captulo 2

Que es el Desarrollo Dirigido por


Tests? (TDD)
El Desarrollo Dirigido por Tests (Test Driven Development), al cual me
referire como TDD, es una tecnica de dise no e implementacion de software
incluida dentro de la metodologa XP. Coincido con Peter Provost
1
en que el
nombre es un tanto desafortunado; algo como Dise no Dirigido por Ejemplos
hubiese sido quizas mas apropiado. TDD es una tecnica para dise nar software
que se centra en tres pilares fundamentales:
La implementacion de las funciones justas que el cliente necesita y no
mas
2
.
La minimizacion del n umero de defectos que llegan al software en fase
de produccion.
La produccion de software modular, altamente reutilizable y preparado
para el cambio.
Cuando empezamos a leer sobre TDD creemos que se trata de una buena
tecnica para que nuestro codigo tenga una cobertura de tests muy alta, algo
que siempre es deseable, pero es realmente una herramienta de dise no que
convierte al programador en un ocial de primera. O, si no les gustan las
metaforas, convierte al programador en desarrollador
3
. TDD es la respuesta
a las grandes preguntas de:
1
http://www.youtube.com/watch?v=JMEO6T6gkAA
2
Evitamos desarrollar funcionalidad que nunca sera usada
3
http://www.ericsink.com/No Programmers.html
53
Captulo 2
Como lo hago?, Por donde empiezo?, Como se que es lo que
hay que implementar y lo que no?, Como escribir un codigo que
se pueda modicar sin romper funcionalidad existente?
No se trata de escribir pruebas a granel como locos, sino de dise nar adecua-
damente seg un los requisitos.
Pasamos, de pensar en implementar tareas, a pensar en ejemplos certeros
que eliminen la ambig uedad creada por la prosa en lenguaje natural (nuestro
idioma). Hasta ahora estabamos acostumbrados a que las tareas, o los casos
de uso, eran las unidades de trabajo mas peque nas sobre las que ponerse a
desarrollar codigo. Con TDD intentamos traducir el caso de uso o tarea en X
ejemplos, hasta que el n umero de ejemplos sea suciente como para describir
la tarea sin lugar a malinterpretaciones de ning un tipo.
En otras metodologas de software, primero nos preocupamos de denir
como va a ser nuestra arquitectura. Pensamos en las clases de infraestruc-
tura que van a homogeneizar la forma de trabajar en todos y cada uno de
los casos, pensamos si vamos a usar un patron Facade
4
y otro Singleton
5
y una comunicacion mediante eventos, o DTOs, y una clase central que va
a hacer esto y aquello... Y si luego resulta que no necesitamos todo eso?
Cuanto vamos a tardar en darnos cuenta de ello? Cuanto dinero vamos
a malgastar? En TDD dejamos que la propia implementacion de peque nos
ejemplos, en constantes iteraciones, hagan emerger la arquitectura que nece-
sitamos usar. Ni mas ni menos. No es que nos despreocupemos por completo
de las caractersticas tecnicas de la aplicacion a priori, es decir, logicamente
tendremos que saber si el desarrollo sera para un telefono m ovil, para una
web o para un pc de escritorio; mas que nada porque tenemos que elegir
unas herramientas de desarrollo conformes a las exigencias del guion. Sin
embargo, nos limitamos a escoger el framework correspondiente y a usar su
arquitectura como base. Por ejemplo, si escogesemos Django
6
o ASP.NET
MVC
7
, ya tendramos denida buena parte de la base antes de empezar a
escribir una sola lnea de codigo. No es que trabajemos sin arquitectura, logi-
camente, si en los requisitos esta la interoperabilidad en las comunicaciones,
tendremos que usar servicios web o servicios REST, lo cual ya propicia un
determinado soporte. Lo que eliminamos son las arquitecturas encima de esas
arquitecturas, las que intentan que todo se haga siempre igual y tal como se
le ocurrio al genio de la empresa. A ser posible, esas que nos obligan a mo-
dicar siete cheros para cambiar una cadena de texto. TDD produce una
arquitectura que emerge de la no-ambig uedad de los tests automatizados,
4
Facade: http://es.wikipedia.org/wiki/Facade (patron de dise no)
5
Singleton: http://es.wikipedia.org/wiki/Singleton
6
http://www.djangoproject.com
7
http://www.asp.net/mvc/
54
Captulo 2
lo cual no exime de las revisiones de codigo entre compa neros ni de hacer
preguntas a los desarrolladores mas veteranos del equipo.
Las primeras paginas del libro de Kent Beck [3] (uno de los padres de
la metodologa XP) dan unos argumentos muy claros y directos sobre por
que merece la pena darle unos cuantos tragos a TDD, o mejor, por que es
benecioso convertirla en nuestra herramienta de dise no principal. Estas son
algunas de las razones que da Kent junto con otras destacadas guras de la
industria:
La calidad del software aumenta (y veremos por que).
Conseguimos codigo altamente reutilizable.
El trabajo en equipo se hace mas facil, une a las personas.
Nos permite conar en nuestros compa neros aunque tengan menos
experiencia.
Multiplica la comunicacion entre los miembros del equipo.
Las personas encargadas de la garanta de calidad adquieren un rol mas
inteligente e interesante.
Escribir el ejemplo (test) antes que el codigo nos obliga a escribir el
mnimo de funcionalidad necesaria, evitando sobredise nar.
Cuando revisamos un proyecto desarrollado mediante TDD, nos damos
cuenta de que los tests son la mejor documentacion tecnica que pode-
mos consultar a la hora de entender que mision cumple cada pieza del
puzzle.
Personalmente, a nadira lo siguiente:
Incrementa la productividad.
Nos hace descubrir y afrontar mas casos de uso en tiempo de dise no.
La jornada se hace mucho mas amena.
Uno se marcha a casa con la reconfortante sensacion de que el trabajo
esta bien hecho.
Ahora bien, como cualquier tecnica, no es una varita magica y no dara el
mismo resultado a un experto arquitecto de software que a un programador
junior que esta empezando. Sin embargo, es util para ambos y para todo el
rango de integrantes del equipo que hay entre uno y otro. Para el arquitecto es
55
2.1. El algoritmo TDD Captulo 2
su mano derecha, una gua que le hace claricar el dominio de negocio a cada
test y que le permite conar en su equipo aunque tenga menos experiencia.
Frecuentemente, nos encontramos con gente muy desconada que mira con
lupa el codigo de su equipo antes de que nadie pueda hacer commit al
sistema de control de versiones. Esto se convierte en un cuello de botella
porque hay varias personas esperando por el jefe (el arquitecto) para que
de el visto bueno y a este se le acumula el trabajo. Ni que decir tiene que el
ambiente de trabajo en estos casos no es nada bueno ni productivo. Cuando
el jefe sabe que su equipo hace TDD correctamente puede conar en ellos
y en lo que diga el sistema de integracion contnua
8
y las estadsticas del
repositorio de codigo. Para el programador junior que no sabe por donde va
a coger al toro, o si es el toro quien le va a coger a el (o a ella), se convierte en
el Pepito Grillo que le cuenta que paso tiene que dar ahora. Y as, un paso
tras otro, le gua en la implementacion de la tarea que le ha sido asignada.
Cuando el equipo practica de esta manera, la comunicacion uye, la
gente se vuelve mas activa y la maquinaria funciona como un engranaje
bien lubricado. Todos los que disfrutamos trabajando en el software llevamos
dentro al personaje del buen arquitecto, entre muchos otros de nuestros
personajes. La practica que aqu se describe nos lo trae para que nos ayude
y nos haga la vida mas facil.
2.1. El algoritmo TDD
La esencia de TDD es sencilla pero ponerla en practica correctamente es
cuestion de entrenamiento, como tantas otras cosas. El algoritmo TDD solo
tiene tres pasos:
Escribir la especicacion del requisito (el ejemplo, el test).
Implementar el codigo seg un dicho ejemplo.
Refactorizar para eliminar duplicidad y hacer mejoras.
Veamosla en detalle.
2.1.1. Escribir la especicacion primero
Una vez que tenemos claro cual es el requisito, lo expresamos en forma
de codigo. Si estamos a nivel de aceptacion o de historia, lo haremos con un
framework tipo Fit, Fitnesse, Concordion o Cucumber. Esto es, ATDD. Si
no, lo haremos con alg un framework xUnit. Como escribimos un test para
8
http://es.wikipedia.org/wiki/Continuous integration
56
Captulo 2 2.1. El algoritmo TDD
un codigo que todava no existe? Respondamos con otra pregunta Acaso
no es posible escribir una especicacion antes de implementarla? Por citar
un ejemplo conocido, las JSR (Java Specication Request) se escriben pa-
ra que luego terceras partes las implementen... ah, entonces es posible!. El
framework Mono se ha implementado basandose en las especicaciones del
ECMA-334 y ECMA-335 y funciona. Por eso, un test no es inicialmente un
test sino un ejemplo o especicacion. La palabra especicacion podra tener
la connotacion de que es inamovible, algo preestablecido y jo, pero no es
as. Un test se puede modicar. Para poder escribirlo, tenemos que pensar
primero en como queremos que sea la API del SUT
9
, es decir, tenemos que
trazar antes de implementar. Pero solo una parte peque na, un comporta-
miento del SUT bien denido y solo uno. Tenemos que hacer el esfuerzo
de imaginar como seria el codigo del SUT si ya estuviera implementado y
como comprobaramos que, efectivamente, hace lo que le pedimos que haga.
La diferencia con los que dictan una JSR es que no dise namos todas las
especicaciones antes de implementar cada una, sino que vamos una a una
siguiendo los tres pasos del algoritmo TDD. El hecho de tener que usar una
funcionalidad antes de haberla escrito le da un giro de 180 grados al codigo
resultante. No vamos a empezar por fastidiarnos a nosotros mismos sino que
nos cuidaremos de dise nar lo que nos sea mas comodo, mas claro, siempre
que cumpla con el requisito objetivo. En los proximos captulos veremos como
mediante ejemplos.
2.1.2. Implementar el codigo que hace funcionar el ejemplo
Teniendo el ejemplo escrito, codicamos lo mnimo necesario para que se
cumpla, para que el test pase. Tpicamente, el mnimo codigo es el de menor
n umero de caracteres porque mnimo quiere decir el que menos tiempo nos
llevo escribirlo. No importa que el codigo parezca feo o chapucero, eso lo
vamos a enmendar en el siguiente paso y en las siguientes iteraciones. En este
paso, la maxima es no implementar nada mas que lo estrictamente obligatorio
para cumplir la especicacion actual. Y no se trata de hacerlo sin pensar,
sino concentrados para ser ecientes. Parece facil pero, al principio, no lo es;
veremos que siempre escribimos mas codigo del que hace falta. Si estamos
bien concentrados, nos vendran a la mente dudas sobre el comportamiento
del SUT ante distintas entradas, es decir, los distintos ujos condicionales
que pueden entrar en juego; el resto de especicaciones de este bloque de
funcionalidad. Estaremos tentados de escribir el codigo que los gestiona sobre
la marcha y, en ese momento, solo la atencion nos ayudara a contener el
9
Subject Under Test. Es el objeto que nos ocupa, el que estamos dise nando a traves
de ejemplos.
57
2.1. El algoritmo TDD Captulo 2
impulso y a anotar las preguntas que nos han surgido en un lugar al margen
para convertirlas en especicaciones que retomaremos despues, en iteraciones
consecutivas.
2.1.3. Refactorizar
Refactorizar no signica reescribir el codigo; reescribir es mas general
que refactorizar. Segun Martn Fowler, refactorizar
10
es modicar el dise no
sin alterar su comportamiento. A ser posible, sin alterar su API p ublica. En
este tercer paso del algoritmo TDD, rastreamos el codigo (tambien el del
test) en busca de lneas duplicadas y las eliminamos refactorizando. Ademas,
revisamos que el codigo cumpla con ciertos principios de dise no (me inclino
por S.O.L.I.D) y refactorizamos para que as sea. Siempre que llego al paso
de refactorizar, y elimino la duplicidad, me planteo si el metodo en cuestion
y su clase cumplen el Principio de una

Unica Responsabilidad
11
y demas
principios.
El propio Fowler escribio uno de los libros mas grandes de la literatura
tecnica moderna[7] en el que se describen las refactorizaciones mas comunes.
Cada una de ellas es como una receta de cocina. Dadas unas precondiciones,
se aplican unos determinados cambios que mejoran el dise no del softwa-
re mientras que su comportamiento sigue siendo el mismo. Mejora es una
palabra ciertamente subjetiva, por lo que empleamos la metrica del codigo
duplicado como parametro de calidad. Si no existe codigo duplicado, enton-
ces hemos conseguido uno de mas calidad que el que presentaba duplicidad.
Mas alla de la duplicidad, durante la refactorizacion podemos permitirnos
darle una vuelta de tuerca al codigo para hacerlo mas claro y facil de man-
tener. Eso ya depende del conocimiento y la experiencia de cada uno. Los
IDE como Eclipse, Netbeans o VisualStudio, son capaces de llevar a cabo
las refactorizaciones mas comunes. Basta con se nalar un bloque de codigo
y elegir la refactorizacion Extraer-Metodo, Extraer-Clase, Pull-up, Pull-down
o cualquiera de las muchas disponibles. El IDE modica el codigo por noso-
tros, asegurandonos que no se cometen errores en la transicion. Al margen de
estas refactorizaciones, existen otras mas complejas que tienen que ver con
la maestra del desarrollador y que a veces recuerdan al mago sacando un
conejo de la chistera. Algunas de ellas tienen nombre y estan catalogadas a
modo de patron y otras son anonimas pero igualmente eliminan la duplicidad.
Cualquier cambio en los adentros del codigo, que mantenga su API p ubli-
ca, es una refactorizacion. La clave de una buena refactorizacion es hacerlo
en pasitos muy peque nos. Se hace un cambio, se ejecutan todos los tests
10
http://www.refactoring.com/
11
Ver Captulo7 en la pagina 111
58
Captulo 2 2.1. El algoritmo TDD
y, si todo sigue funcionando, se hace otro peque no cambio. Cuando refac-
torizamos, pensamos en global, contemplamos la perspectiva general, pero
actuamos en local. Es el momento de detectar malos olores y eliminarlos. El
verbo refactorizar no existe como tal en la Real Academia Espa nola pero, tras
discutirlo en la red, nos resulta la mejor traduccion del termino refactoring.
La tarea de buscar y eliminar codigo duplicado despues de haber completado
los dos pasos anteriores, es la que mas tiende a olvidarse. Es com un entrar en
la dinamica de escribir el test, luego el SUT, y as sucesivamente olvidando
la refactorizacion. Si de las tres etapas que tiene el algoritmo TDD dejamos
atras una, logicamente no estamos practicando TDD sino otra cosa.
Otra forma de enumerar las tres fases del ciclo es:
Rojo
Verde
Refactorizar
Es una descripcion metaforica ya que los frameworks de tests suelen colorear
en rojo aquellas especicaciones que no se cumplen y en verde las que lo
hacen. As, cuando escribimos el test, el primer color es rojo porque todava
no existe codigo que implemente el requisito. Una vez implementado, se pasa
a verde.
Cuando hemos dado los tres pasos de la especicacion que nos ocupa,
tomamos la siguiente y volvemos a repetirlos. Parece demasiado simple, la
reaccion de los asistentes a mis cursos es mayoritariamente incredula y es
que el efecto TDD solo se percibe cuando se practica. Me gusta decir que
tiene una similitud con un buen vino; la primera vez que se prueba el vino en
la vida, no gusta a nadie, pero a fuerza de repetir se convierte en un placer
para los sentidos. Connotaciones alcoholicas a un lado, espero que se capte
el mensaje.
Y TDD sirve para proyectos grandes? Un proyecto grande no es sino la
agrupacion de peque nos subproyectos y es ahora cuando toca aplicar aquello
de divide y venceras. El tama no del proyecto no guarda relacion con la
aplicabilidad de TDD. La clave esta en saber dividir, en saber priorizar. De
ah la ayuda de Scrum para gestionar adecuadamente el backlog del producto.
Por eso tanta gente combina XP y Scrum. Todava no he encontrado ning un
proyecto en el que se desaconseje aplicar TDD.
En la segunda parte del libro se expondra el algoritmo TDD mediante
ejemplos practicos, donde iremos de menos a mas, iterando progresivamente.
No se preocupe si no lo ve del todo claro ahora.
59
2.2. Consideraciones y recomendaciones Captulo 2
2.2. Consideraciones y recomendaciones
2.2.1. Ventajas del desarrollador experto frente al junior
Existe la leyenda de que TDD unicamente es valido para personal alta-
mente cualicado y con muchsima experiencia. Dista de la realidad; TDD es
bueno para todos los individuos y en todos los proyectos. Eso s, hay algunos
matices. La diferencia entre el desarrollador experimentado que se sienta a
hacer TDD y el junior, es como enfocan los tests, es decir, que tests escriben;
mas alla del codigo que escriben. El experto en dise no orientado a objetos
buscara un test que fuerce al SUT a tener una estructura o una API que
sabe que le dara buenos resultados en terminos de legibilidad y reusabilidad.
Un experto es capaz de anticipar futuros casos de uso y futuros problemas
y sera mas cuidadoso dise nando la API test tras test, aplicando las buenas
practicas que conoce. El junior probablemente se siente a escribir lo que mejor
le parece, sin saber que la solucion que elige quizas le traiga quebraderos de
cabeza mas adelante. La ventaja es que, cuando se de cuenta de que su dise no
tiene puntos a mejorar y empiece a refactorizar, contara con un importantsi-
mo respaldo detras en forma de batera de tests. Por poco experimentado
que sea, se cuidara de no dise nar una API que le resulte casi imposible de
usar. Debe tenerse en cuenta que se supone que el principiante no esta so-
lo, sino que en un contexto XP, hay desarrolladores de mas experiencia que
supervisaran y habra momentos en los que se programe en parejas. La gura
de los lderes es importante en XP al igual que en otras metodologas, con la
gran diferencia de que el lder agil esta para responder preguntas y ayudar a
los demas y no para darles latigo. El lder debe intentar que las personas que
trabajan con el esten contentas de trabajar ah y quieran seguir haciendolo.
2.2.2. TDD con una tecnologa desconocida
La primera vez que usamos una determinada tecnologa o incluso una
nueva librera, es complicado que podamos escribir la especicacion antes
que el SUT, porque no sabemos las limitaciones y fortalezas que ofrece la
nueva herramienta. En estos casos, XP habla de spikes (disculpen que no lo
traduzca, no sabra como) .Un spike es un peque no programa que se escri-
be para indagar en la herramienta, explorando su funcionalidad. Es hacerse
alguna funcion o alguna aplicacion peque na que nos aporte el conocimiento
que no tenemos. Si el spike es peque no, y resulta que nos damos cuenta
que su propio codigo es valido tal cual, entonces escribiremos el test justo a
continuacion, en lugar de dejarlo sin test. Sin un conocimiento basico de la
API y las restricciones del sistema, no recomendara lanzarse a escribir espe-
cicaciones. Hay que respetar el tiempo de aprendizaje con la herramienta y
60
Captulo 2 2.2. Consideraciones y recomendaciones
avanzar una vez que tengamos conanza con ella. Intentar practicar TDD en
un entorno desconocido es, a mi parecer, un antipatron poco documentado.
Tampoco es que descartemos forzosamente TDD, sino que primero tendre-
mos que aprender a pilotar la maquina. Una vez sepamos si es de cambio
manual o automatico, donde se encienden las luces y donde se activa el lim-
pia parabrisas, podremos echar a rodar. Es solo cuestion de aplicar el sentido
com un, primero aprendemos a usar la herramienta y luego la usamos. Tene-
mos que evitar algo que pasa muy frecuentemente, minusvalorar el riesgo de
no dominar las herramientas (y frameworks y lenguajes...)
2.2.3. TDD en medio de un proyecto
En la segunda parte del libro, la de los ejemplos practicos, iniciamos el
desarrollo de una aplicacion desde cero. Igual que hacemos en los cursos que
imparto. La pregunta de los asistentes aparece antes o despues: no se puede
aplicar TDD en un proyecto que ya esta parcialmente implementado? Claro
que se puede, aunque con mas consideraciones en juego. Para los nuevos
requisitos de la aplicacion, es decir, aquello que todava falta por implemen-
tar, podremos aplicar eso de escribir el test primero y luego el codigo (y
despues refactorizar!). Es probable que el nuevo SUT colabore con partes
legadas que no permiten la inyeccion de dependencias y que no cumplen una
unica responsabilidad
12
; codigo legado que nos diculta su reutilizacion. El
libro mas recomendado por todos en los ultimos tiempos sobre este asun-
to es, Working Eectively with Legacy Code de Michael C. Feathers[6].
Tratar con codigo legado no es moco de pavo. En general, por c odigo le-
gado entendemos que se trata de aquel que no tiene tests de ning un tipo.
Mi recomendacion, antes de ponerse a reescribir partes de codigo legado, es
crear tests de sistema (y cuando el codigo lo permita, tests unitarios) que
minimicen los posibles efectos colaterales de la reescritura. Si es una web,
por ejemplo, agarrar Selenium o similar y grabar todos los posibles usos de
la interfaz graca para poderlos reproducir despues de las modicaciones y
comprobar que todo el sistema se sigue comportando de la misma manera.
Es un esfuerzo de usar y tirar porque estos tests son tremendamente fragiles,
pero es mucho mas seguro que lanzarse a reescribir alegremente. La siguiente
recomendacion es que la nueva API y la vieja convivan durante un tiempo,
en lugar de reescribir eliminando la version legada. Ademas de tener dos API
podemos sobrecargar metodos para intentar que el codigo legado y su nueva
version convivan, si es que la API antigua nos sigue sirviendo. Viene siendo
cuestion de aplicar el sentido com un y recordar la ley de Murphy; Si puede
salir mal, saldra mal. Otra alternativa para hacer TDD con c odigo nuevo
12
Ver Captulo 7 en la pagina 111
61
2.2. Consideraciones y recomendaciones Captulo 2
que colabora con codigo legado es abusar de los objetos mock
13
. Digamos
que los tests van a ser mas fragiles de lo que deberan pero es mejor usar
paracadas que saltar sin nada. Y por supuesto, si el nuevo codigo es mas
independiente, podemos seguir haciendo TDD sin ning un problema. Se lo
recomiendo encarecidamente.
13
Los veremos en el Captulo 6 en la pagina 95
62

También podría gustarte