0% encontró este documento útil (0 votos)
150 vistas139 páginas

Test Driven Development TDD Universidad

Este documento presenta una investigación sobre el desarrollo de software guiado por pruebas (TDD). Describe el marco teórico del desarrollo ágil de software y metodologías como XP y Scrum. Luego, analiza TDD en detalle, incluidas sus variantes como ATDD y BDD. También cubre prácticas como la refactorización, la integración continua y herramientas. Finalmente, incluye una guía práctica de TDD y un ejemplo de implementación de un sistema de seguimiento de incidentes utilizando

Cargado por

Juan Quispe
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)
150 vistas139 páginas

Test Driven Development TDD Universidad

Este documento presenta una investigación sobre el desarrollo de software guiado por pruebas (TDD). Describe el marco teórico del desarrollo ágil de software y metodologías como XP y Scrum. Luego, analiza TDD en detalle, incluidas sus variantes como ATDD y BDD. También cubre prácticas como la refactorización, la integración continua y herramientas. Finalmente, incluye una guía práctica de TDD y un ejemplo de implementación de un sistema de seguimiento de incidentes utilizando

Cargado por

Juan Quispe
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/ 139

Universidad Nacional de Salta

Facultad de Ciencias Exactas

Investigación Aplicada de
Desarrollo de Software Guiado
por Tests (TDD)

Seminario de Sistemas presentado por Maria Lorena Garcı́a para obtener el


grado de Licenciatura en Análisis de Sistemas

2017

Seminario de Sistemas

Tesis

L.U: 204.623 - Nro de Actuación: 1003/2016

Comisión Evaluadora: Aballay Patricia, Binda Adriana, Martı́n Dı́az


Agradecimientos

A mis hijos, que son la razón principal por la que, después de tantos años, me embarcara de
nuevo en la Universidad.
A mi esposo Gustavo, por tenerme paciencia.
A Nilsa por apoyarme y alentarme.
A todos aquellos de la comunidad de Internet que ofrecen sus aportaciones, sin las cuales me
habrı́a encontrado más de una vez en un callejón sin salida.
Muchas gracias a todos.

2
Índice general

Agradecimientos 2

1. Introducción 6
1.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.1. Objetivos especı́ficos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2. Alcance del Proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2. Marco Teórico 8
2.1. Modelo Ágil de Desarrollo de Software . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.1. Introducción al Modelo Ágil . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.2. El Agilisimo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.3. Manifiesto ágil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2. Metodologı́as ágiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.1. XP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.2. SCRUM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.3. Crystal Methodologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.4. Dynamic Systems Development Method (DSDM) . . . . . . . . . . . . . . . . 20
2.2.5. Adaptive Software Development (ASD) . . . . . . . . . . . . . . . . . . . . . 20
2.2.6. Feature-Driven Development8 (FDD) . . . . . . . . . . . . . . . . . . . . . . 22
2.2.7. Lean Development (LD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2.8. Kanban - revisar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3. Investigación de TDD 25
3.1. TDD (Test Driven Development) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.1. ¿Qué es TDD? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.1.2. ¿Cómo se hace TDD? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.1.3. El lado no tan bueno de TDD . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2. ATDD (Acceptance Test Driven Development) . . . . . . . . . . . . . . . . . . . . . 31
3.3. BDD (Behaviour Driven Development) . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.4. Variantes de TDD clásico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

3
Índice general

3.4.1. UTDD (Unit Test Driven Development . . . . . . . . . . . . . . . . . . . . . 35


3.4.2. DDD (Domain Driven Design) or D3 . . . . . . . . . . . . . . . . . . . . . . . 36
3.4.3. NDD (Need-Driven Development ) . . . . . . . . . . . . . . . . . . . . . . . . 42
3.4.4. TDM (Test Driven Maintenance) . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.4.5. BDD, ATDD, NDD ¿ sus diferencias? . . . . . . . . . . . . . . . . . . . . . . 46

4. Prácticas y técnicas con TDD 48


4.1. Refactorización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.1.1. Refactorización segura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.1.2. ¿Qué refactorizar? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.1.3. Herramientas de Refactorización . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.2. Integración Continua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.1. Mejora de la calidad en el desarrollo del software . . . . . . . . . . . . . . . . 58
4.2.2. Buenas Practicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.3. Beneficios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.2.4. Inconvenientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3. Herramientas para Integración continua . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3.1. Gestión de requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.3.2. Servidor de Versiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.3.3. Pruebas Automatizadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.3.4. Construcción y despliegue automatizados . . . . . . . . . . . . . . . . . . . . 90
4.3.5. Servidores de Integración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.3.6. Control de Calidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

5. Guı́a práctica 95
5.1. Evaluación previa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
5.2. Tipos de test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
5.2.1. Test unitarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.2.2. Test de aceptación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.2.3. Test funcionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.2.4. Test de integración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.2.5. Test de sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.2.6. Objetos simulados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.3. Métodos prácticos de refactorización. . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
5.3.1. Composición de Métodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
5.3.2. Desplazamiento de funcionalidad entre métodos . . . . . . . . . . . . . . . . . 105
5.3.3. Organización de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
5.3.4. Simplificación de expresiones condicionales . . . . . . . . . . . . . . . . . . . 107
5.3.5. Generalización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
5.4. Ejemplo práctico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

C.U. Marı́a Lorena Garcı́a TDD 4


Índice general

5.4.1. Historia de usuario, criterios de aceptación . . . . . . . . . . . . . . . . . . . 112


5.4.2. Test unitarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

6. Sistema de Seguimiento de Incidentes (Tickets) 124


6.1. Visión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
6.2. Elección y trazabilidad entre herramientas . . . . . . . . . . . . . . . . . . . . . . . . 125
6.2.1. Desarrollo de módulo de Departamento . . . . . . . . . . . . . . . . . . . . . 126
6.2.2. Herramientas utilizadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
6.2.3. Conclusión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

7. Conclusiones 128

Glosario 130

Bibliografı́a 135

C.U. Marı́a Lorena Garcı́a TDD 5


Capı́tulo 1

Introducción

En un mundo rodeado de sistemas donde el cambio es permanente, con innovaciones constantes


y nuevas tecnologı́as, la información es un requisito importante, nutre y da vida a las organizaciones.
Sin información nadie estarı́a enterado de lo que sucede. Hacerla llegar a quienes la necesitan como
herramienta para la toma de decisiones requiere un estudio.
El diseño y desarrollo de software toma como propósito hacer llegar esta información, existe
una necesidad constante de construir sistemas capaces de enfrentar los cambios, los movimientos.
El desafı́o de los equipos de trabajo en el desarrollo de Software plantea muchos retos, los de entender
el mercado y brindar lo que los clientes necesitan, cubrir todos los aspectos de una organización, y
los cambios que van necesitando.
Para acompañar a estos cambios de requisitos, porque cambian los sistemas de información,
las personas y surgen nuevas formas de realizar un mismo proceso, aparecieron las metodologı́as
ágiles de desarrollo de software dejando de lado las tradicionales que centraban su atención en
cumplir cada etapa y cada una de ellas debı́a estar terminada para avanzar con la siguiente y en
una documentación exhaustiva.
Las metodologı́as ágiles dan mayor valor al individuo, a la colaboración con el cliente y al
desarrollo incremental del software con iteraciones muy cortas y dentro de ellas, encontramos el
desarrollo guiado por pruebas - TDD.

1.1. Objetivos
El objetivo del Trabajo de Seminario es hacer una recopilación Bibliográfica y construir un
Marco Teórico Completo de las Metodologı́as Ágiles en particular del Desarrollo Guiado por Pruebas
(TDD) como metodologı́a ágil con el fin de entender las fortalezas y debilidades.
Se destacará como TDD cumple con los postulados del manifiesto ágil para ası́ asegurar su
validez como metodologı́a de desarrollo de software ágil.
Este trabajo presentará una introducción y utilización de la práctica de desarrollo de software

6
Capı́tulo 1. Introducción

conocida como Test-Driven Development (TDD) en un ejemplo práctico.


Se espera dar con lo investigado una base sólida, una guı́a a aquellas personas que incursionen
en TDD en un contexto de desarrollo. Aportar conocimiento por medio de una recopilación teórica
y un ejemplo práctico.

1.1.1. Objetivos especı́ficos


Realizar una recopilación Bibliográfica de TDD.

Obtener una guı́a para su utilización en el desarrollo de Software.

Mostrar las fortalezas y debilidades de TDD, de modo que sirva de ayuda para la toma de
decisión al momento de decidir su utilización.

Probar si se obtiene código de calidad.

Comprobar que la aplicación obtenida usando TDD tiene menor ı́ndice de errores.

Comprobar si es posible aplicar TDD puro en el desarrollo de toda una aplicación.

Obtener una lista de herramientas necesarias para su utilización.

1.2. Alcance del Proyecto


Se tratará de mostrar en este proyecto de investigación las particularidades de la Metodologı́a,
las ventajas y dificultades que puedan surgir, como los proyectos en los cuales conviene aplicar.
Asimismo se pretende mostrar los beneficios y desafı́os que se encuentren a lo largo de la inves-
tigación y en la utilización de TDD para el desarrollo de un Sistema de Seguimiento de Incidentes.
Se resaltarán ı́ndices de calidad en el código, de la aplicación, productividad y la comunicación.

C.U. Marı́a Lorena Garcı́a TDD 7


Capı́tulo 2

Marco Teórico

2.1. Modelo Ágil de Desarrollo de Software

En cualquier proceso de negocio, como en el desarrollo de software, los objetivos especı́ficos


deben alcanzarse en un tiempo determinado y fijo. Existen muchas estrategias para obtener los
objetivos. Se conocen dos modelos “populares”, el modelo de cascada y el modelo ágil.

El modelo en cascada fue heredado de estrategias de fabricación de hardware, prácticas que


estaban durante la década de 1970. Debido a eso tiene un enfoque muy estructurado. Las notaciones
de modelado y las herramientas pretendieron ser el éxito en el desarrollo de software, sin embargo,
las expectativas no fueron satisfechas [34]. Se habı́a postergado la metodologı́a de Desarrollo. De
nada sirve tener una documentación completa, si no se prevén directivas para su aplicación. Este
modelo ha resultado efectivo para proyectos de gran tamaño. Por eso en esta década ha comenzado
un creciente interés en metodologı́as de desarrollo.

El modelo ágil de desarrollo de software, de la década de 1990, decide romper enfoques tradi-
cionales, dejar de lado lo estructurado, también las burocracias que acompañaban al desarrollo de
software. Se hizo al desarrollo de software más flexible, más ligero. De esta forma nacen métodos
ágiles, los más importantes y populares del desarrollo de software, que posteriormente evolucionaron
son Scrum en 1995, Crystal Clear, Extreme Programming, en 1996. En 2001, un grupo de pioneros
en el desarrollo ágil de software se reunieron y declararon el “Manifiesto Ágil”, que es un conjunto
de reglas canónicas de la clase, para los métodos ágiles de desarrollo de software.

Las metodologı́as ágiles emergen como una posible respuesta para llenar el vació metodológico
en la parte del desarrollo del Software. Las metodologı́as ágiles son sin duda uno de los temas
recientes en ingenierı́a de software que están acaparando gran interés.

8
Capı́tulo 2. Marco Teórico

2.1.1. Introducción al Modelo Ágil


Modelado Ágil es una metodologı́a basada en la práctica para modelado efectivo de sistemas
de software. La metodologı́a del Modelo Ágil es una colección de prácticas, guiadas por principios.
El Modelo Ágil no es un proceso prescriptivo, en él no existen procedimientos detallados de cómo
crear un modelo, solo sugiere prácticas para ser un modelador efectivo. Es flexible, no es rı́gido y es
rápido. Es más un arte, nadie dice cómo hacer las cosas, más bien se dice que se puede hacer para
que salgan mejor.
En el Modelo ágil se tienen tres objetivos:

1. Definir y mostrar cómo poner en práctica una colección de valores, principios y prácticas que
conlleven a un modelado ligero efectivo.

2. Explorar la aplicación de técnicas de modelado en proyectos de software a través de un enfoque


ágil.

3. Explorar el cómo mejorar el modelado bajo procesos prescriptivos.

¿ Qué es el modelo Ágil?

El modelo ágil es la actitud que tiene un individuo para el desarrollo del software, tener a
priori una dirección hacia un fin determinado, no es un proceso , o algo que se establece, un
ejemplo de algo prescriptivo como el manual de un televisor, el modelo ágil no dice que hay
que hacer en determinado caso.

Utiliza enfoque adaptativo, donde no hay una planificación detallada.

Solo hay claridad sobre las caracterı́sticas deben ser desarrolladas.

El equipo se adapta a los requerimientos de los productos que cambian de forma dinámica.

El cliente es la columna vertebral.

Promueve el trabajo en equipo y la formación transversal.

Es una recolección de las mejores prácticas para ser efectivo.

No siempre es lo que se necesita.

Incluye muchas ideas para ser utilizadas en la práctica, no es una teorı́a.

Es para todos los desarrolladores.

La idea es la minimización de la documentación, solo lo necesario.

No es para todos los proyectos.

C.U. Marı́a Lorena Garcı́a TDD 9


Capı́tulo 2. Marco Teórico

Lo importante, modelar con un propósito, identificar lo válido, luego averiguar hasta qué punto
de detalle se desea la información, y saber para quién va dirigido el modelo.
El Modelo Ágil, es un modelo que logra recuperar gran parte del complejo social en el desarrollo
del Software. Hace que el modelo se regule ası́ mismo, que siempre tenderá hacia el equilibrio, lo
cual lo hace un modelo ideal pero obviamente imperfecto.
Las metodologı́as ágiles resuelven los problemas surgidos por las expectativas y necesidades por
parte de los usuarios, las cuales se hicieron más urgentes y frecuentes. Fue ası́ como a comienzo
de los 90 surgieron propuestas metodológicas para lograr resultados más rápidos en el desarrollo
de software sin disminuir su calidad. En febrero de 2001 en Utah-EEUU, se reunieron 17 empre-
sarios de la industria del software y como resultado del debate respecto a las metodologı́as, se
obtuvo principios y valores que deben regir el desarrollo de software de buena calidad, en tiempos
cortos y flexible a los cambios, se aceptó el término ágil para hacer referencia a nuevos enfoques
metodológicos en el desarrollo de software [34].
En esta reunión se creó “The Agile Alliance”, organización sin ánimo de lucro dedicada a
promover los conceptos relacionados con el desarrollo ágil de software. Como punto de partida o
base fundamental de las metodologı́as ágiles se redactó y proclamó el manifiesto ágil.
Modelado Ágil es una metodologı́a basada en la práctica para modelado efectivo de sistemas
de software. La metodologı́a del Modelo Ágil es una colección de prácticas, guiadas por principios.
El Modelo Ágil no es un proceso prescriptivo, en él no existen procedimientos detallados de cómo
crear un modelo, solo sugiere prácticas para ser un modelador efectivo. Es flexible, no es rı́gido y
es rápido. Es más un arte, nadie te dice cómo hacer las cosas, más bien te dicen que podrı́as hacer
para que te salgan mejor.

2.1.2. El Agilisimo
El agilı́simo es una respuesta a los fracasos y las frustraciones del modelo en cascada. Si bien las
metodologı́as ágiles llevan siendo usadas, no mucho, la cantidad de metodologı́as ágiles es amplia,
existiendo métodos para organizar equipos y técnicas para escribir y mantener software [12].
Muchos autores afirman que para atacar la forma de organizar equipos deberı́amos irnos hacia
Scrum y para el mantenimiento del software Programación Extrema.
Cuando se habla de agilı́simo no se busca el perfeccionismo, se reconoce que el software es
propenso a errores, pero es cierto que la naturaleza viene propiamente de quienes realizan el código,
es por ello que se toman medidas para minimizar sus efectos nocivos desde el principio.
Se reconoce que los humanos nos equivocamos con frecuencia, por lo que no se espera encontrar
desarrolladores perfectos, en el agilı́simo se proponen técnicas que ayudan a minimizar los errores
y se intenta dar confianza a pesar de ellos.
La esencia del agilı́smo es adaptarse a los cambios, entonces, se ve al modelo en cascada trans-
formado en una rueda, que a cada vuelta obtenemos una iteración, se alimenta con nuevos reque-
rimientos o aproximaciones más refinadas, se pulen detalles técnicos. Ejecutando diversas técnicas
que se engloban, con la debida disciplina, se obtienen resultados satisfactorios sin entrar en un caos.

C.U. Marı́a Lorena Garcı́a TDD 10


Capı́tulo 2. Marco Teórico

En el agilı́smo el análisis es corto, ni se hace indefinidamente antes de empezar la codificación,


se acota y se encuadra en cada iteración.
Analizando las órbitas clásicas en el desarrollo de Software, se pueden considerar:

El alcance del software: Viene siendo discutido, ya que no hay un consenso claro sobre la
unidad de medida (lı́nea de código, punto función, caso de uso...) a aplicar.

El tiempo: Algo que es trivial de medir, y sin embargo arroja terribles resultados. Aproxima-
damente sólo un tercio de los proyectos informáticos logran ser puestos en funcionamiento en
el tiempo inicialmente estimado o acordado, lo que denota un proceso descontrolado.

El coste: en la que normalmente se centran las metodologı́as y gerentes del sector, incidiendo
en ella con poca precisión, puesto que habitualmente la presión gerencial sobre esta dimensión
afecta a la calidad resultante.

La calidad, la realidad demuestra que muchos clientes y usuarios no tienen un mı́nimo co-
nocimiento de en qué dimensiones pueden y deben exigir, ni con qué parámetros medirla. A
pesar de la existencia de clasificaciones de factores de calidad del software fáciles de explicar
y comprender.

La mayorı́a de los factores nombrados son factores humanos. Se evidencia el problema, el agilı́si-
mo intenta dar respuesta.

2.1.3. Manifiesto ágil


El Manifiesto [19] comienza enumerando los principales valores del desarrollo ágil. Se valora:

1. Individuos e interacciones sobre procesos y herramientas.

2. Software funcionando sobre documentación extensiva.

3. Colaboración con el cliente sobre negociación contractual.

4. Respuesta ante el cambio sobre seguir un plan

Los valores anteriores inspiran los doce principios del manifiesto. Estos principios son las ca-
racterı́sticas que diferencian un proceso ágil de uno tradicional. Los dos primeros son generales y
resumen gran parte del espı́ritu ágil. Son:

I. La prioridad es satisfacer al cliente mediante tempranas y continuas entregas de software que


le aporte un valor. Un proceso es ágil si a las pocas semanas de empezar ya entrega software
que funcione aunque sea rudimentario. El cliente decide si pone en marcha dicho software
con la funcionalidad que ahora le proporciona o simplemente lo revisa e informa de posibles
cambios a realizar.

C.U. Marı́a Lorena Garcı́a TDD 11


Capı́tulo 2. Marco Teórico

II. Dar la bienvenida a los cambios. Se capturan los cambios para que el cliente tenga una ventaja
competitiva. Este principio es una actitud que deben adoptar los miembros del equipo de
desarrollo. Los cambios en los requisitos deben verse como algo positivo. Les va a permitir
aprender más, a la vez que logran una mayor satisfacción del cliente. Este principio implica
además que la estructura del software debe ser flexible para poder incorporar los cambios
sin demasiado coste añadido. El paradigma orientado a objetos puede ayudar a conseguir
esta flexibilidad. Luego existen una serie de principios que tienen que ver directamente con el
proceso de desarrollo de software a seguir.

III. Entregar frecuentemente software que funcione desde un par de semanas a un par de meses,
con el menor intervalo de tiempo posible entre entregas. Las entregas al cliente se insiste en
que sean software, no planificaciones, ni documentación de análisis o de diseño.

IV. La gente del negocio y los desarrolladores deben trabajar juntos a lo largo del proyecto. El
proceso de desarrollo necesita ser guiado por el cliente, por lo que la interacción con el equipo
es muy frecuente.

V. Construir el proyecto en torno a individuos motivados. Darles el entorno y el apoyo que


necesitan y confiar en ellos para conseguir finalizar el trabajo. La gente es el principal factor
de éxito, todo los demás (proceso, entorno, gestión, etc.) queda en segundo plano. Si cualquiera
de ellos tiene un efecto negativo sobre los individuos debe ser cambiado.

VI. El diálogo cara a cara es el método más eficiente y efectivo para comunicar información
dentro de un equipo de desarrollo. Los miembros de equipo deben hablar entre ellos, éste es
el principal modo de comunicación. Se pueden crear documentos pero no todo estará en ellos,
no es lo que el equipo espera.

VII. El software que funciona es la medida principal de progreso. El estado de un proyecto no


viene dado por la documentación generada o la fase en la que se encuentre, sino por el código
generado y en funcionamiento. Por ejemplo, un proyecto se encuentra al 50

VIII. Los procesos ágiles promueven un desarrollo sostenible. Los promotores, desarrolladores y
usuarios deberı́an ser capaces de mantener una paz constante. No se trata de desarrollar
lo más rápido posible, sino de mantener el ritmo de desarrollo durante toda la duración del
proyecto, asegurando en todo momento que la calidad de lo producido es máxima. Finalmente
los últimos principios están más directamente relacionados con el equipo de desarrollo, en
cuanto metas a seguir y organización del mismo.

IX. La atención continua a la calidad técnica y al buen diseño mejora la agilidad. Producir código
claro y robusto es la clave para avanzar más rápidamente en el proyecto.

X. La simplicidad es esencial. Tomar los caminos más simples que sean consistentes con los
objetivos perseguidos. Si el código producido es simple y de alta calidad será más sencillo
adaptarlo a los cambios que puedan surgir.

C.U. Marı́a Lorena Garcı́a TDD 12


Capı́tulo 2. Marco Teórico

XI. Las mejores arquitecturas, requisitos y diseños surgen de los equipos organizados por sı́ mis-
mos. Todo el equipo es informado de las responsabilidades y éstas recaen sobre todos sus
miembros. Es el propio equipo el que decide la mejor forma de organizarse, de acuerdo a los
objetivos que se persigan.

XII. En intervalos regulares, el equipo reflexiona respecto a cómo llegar a ser más efectivo, y
según esto ajusta su comportamiento. Puesto que el entorno está cambiando continuamente,
el equipo también debe ajustarse al nuevo escenario de forma continua. Puede cambiar su
organización, sus reglas, sus convenciones, sus relaciones, etc., para seguir siendo ágil.

Los firmantes de los valores y principios de este Manifiesto son: Kent Beck, Mike Beedle, Arie van
Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith,
Andrew Hunt, Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin, Steve Mellor, Ken Schwaber,
Jeff Sutherland y Dave Thomas. Aunque los creadores e impulsores de las metodologı́as ágiles más
populares han suscrito el manifiesto ágil y coinciden con los principios enunciados anteriormente,
cada metodologı́a tiene caracterı́sticas propias y hace hincapié en algunos aspectos más especı́ficos
[34].

2.2. Metodologı́as ágiles


2.2.1. XP
La programación extrema o eXtreme Programming (XP) es una metodologı́a de desarrollo de la
ingenierı́a de software formulada por Kent Beck, autor del primer libro sobre la materia, Extreme
Programming Explained: Embrace Change (1999). Es el más destacado de los procesos ágiles de
desarrollo de software.
Es una metodologı́a ágil centrada en potenciar las relaciones interpersonales como clave para el
éxito en desarrollo de software, promoviendo el trabajo en equipo, preocupándose por el aprendizaje
de los desarrolladores, y propiciando un buen clima de trabajo. XP se basa en realimentación
continua entre el cliente y el equipo de desarrollo, comunicación fluida entre todos los participantes,
simplicidad en las soluciones implementadas y coraje para enfrentar los cambios. XP se define como
especialmente adecuada para proyectos con requisitos imprecisos y muy cambiantes, y donde existe
un alto riesgo técnico.
Kent Beck, entre otros, que con su larga experiencia como programador eligió las mejores carac-
terı́sticas de las metodologı́as y profundizó en las relaciones de éstas y como se reforzaban unas a
otras. Por tanto XP no se basa en principios nuevos, sino que todas, o casi todas, sus caracterı́sticas
ya se conocen dentro de la ingenierı́a del software, las cuales se complementan para minimizar los
tópicos problemas que pueden surgir en todo desarrollo de proyectos software.
Una parte central del desarrollo Ágil y en particular de XP, es la capacidad (y, de hecho, la
necesidad) de crear el software de forma incremental en cada iteración. Esto se logra mediante la

C.U. Marı́a Lorena Garcı́a TDD 13


Capı́tulo 2. Marco Teórico

adición de nuevo código en cada iteración, pero también por refactorización del código existente
escrito durante las iteraciones anteriores. Esta refactorización puede lograrse de manera segura sólo
si se tiene un sistema de prueba fuerte, capaz de verificar que todo el producto de software no se
romperá cuando se agregue nuevo código, o al modificar lo existente.
Por lo tanto, cuando se desarrolla el software, finalmente se crean dos sistemas separados, pero
fuertemente conectados:

El producto de software que desea proporcionar a los usuarios.

Su instrumento de prueba que le ayuda a construir de forma incremental

Objetivos de la programación extrema

El objetivo principal de XP es la satisfacción del cliente. Se le trata de dar al cliente lo que quiere
y cuando quiere. Por tanto, se debe responder rápidamente a las necesidades del cliente, aunque
realice cambios en fases avanzadas del proyecto. Como metodologı́a Ágil que es, se pueden producir
modificaciones de los requisitos del proyecto a lo largo de su desarrollo, sin que esto produzca un
buen dolor de cabeza. Otro de los objetivos es el trabajo en grupo. Tanto los jefes del proyecto,
clientes y desarrolladores forman parte del equipo y deben estar involucrados en el desarrollo.

Valores de la programación extrema

Para garantizar el éxito de un proyecto, los autores de XP han considerado como fundamentales
cuatro valores:

Comunicación. Muy importante. La XP ayuda mediante sus prácticas a la comunicación entre


los integrantes del grupo de trabajo: jefes de proyecto, clientes y desarrolladores.

Sencillez. Los programas deben ser los más sencillos posibles y tener la funcionalidad necesaria
que se indican en los requisitos. No hay que añadir algo que no se necesite hoy. Si se necesita
añadir más funcionalidad mañana pues ya se hará entonces.

Retroalimentación. Las pruebas que se le realizan al software nos mantiene informados del
grado de fiabilidad del sistema.

Valentı́a. Asumir retos, ser valientes ante los problemas y afrontarlos. El intentar mejorar algo
que ya funciona. Aunque gracias a las pruebas unitarias no existe el riesgo de ‘meter la pata’.

Algunas voces, añaden además un quinto valor: la humildad. El compartir el código, la refac-
torización y el trabajo en equipo tan estrecho es una buena dosis de humildad que siempre es de
agradecer.

C.U. Marı́a Lorena Garcı́a TDD 14


Capı́tulo 2. Marco Teórico

Prácticas de XP

Las 12 son las prácticas de la programación extrema son [19]:

El juego de la planificación (the planning game). Es un permanente diálogo entre las partes
empresarial (deseable) y técnica (posible).

Pequeñas entregas (small releases). Cada versión debe de ser tan pequeña como fuera posible,
conteniendo los requisitos de negocios más importantes, las versiones tienen que tener sentido
como un todo, no se puede implementar media caracterı́stica y lanzar la versión.
Es mucho mejor planificar para 1 mes o 2 que para seis meses y un año, las compañı́as que
entregan software muy voluminoso no son capaces de hacerlo con mucha frecuencia.

Metáfora (metaphor). Una metáfora es una historia que todo el mundo puede contar acerca de
cómo funciona el sistema. Algunas veces podremos encontrar metáforas sencillas “Programa
de gestión de compras, ventas, con gestión de cartera y almacén”. Las metáforas ayudan a
cualquier persona a entender el objeto del programa.

Diseño sencillo (simple design): Se basa en la filosofı́a de que el mayor valor de negocio es
entregado por el programa más sencillo que cumpla los requerimientos. Un diseño sencillo se
enfoca en proporcionar un sistema que cubra las necesidades inmediatas del cliente, ni más
ni menos. Este proceso permite eliminar redundancias y rejuvenecer los diseños obsoletos de
forma sencilla.

Pruebas (testing). No debe existir ninguna caracterı́stica en el programa que no haya sido
probada, los programadores escriben pruebas para chequear el correcto funcionamiento del
programa, los clientes realizan pruebas funcionales. El resultado un programa más seguro que
conforme pasa el tiempo es capaz de aceptar nuevos cambios.

Refactorización (refactoring). Cuando implementamos nuevas caracterı́sticas en nuestros pro-


gramas nos planteamos la manera de hacerlo lo más simple posible, después de implementar
esta caracterı́stica, nos preguntamos cómo hacer el programa más simple sin perder funciona-
lidad, este proceso se le denomina recodificar o refactorizar (refactoring). Esto a veces lleva a
hacer más trabajo del necesario, pero a la vez se está preparando al sistema para que en un
futuro acepte nuevos cambios y pueda albergar nuevas caracterı́sticas. No se debe recodificar
ante especulaciones si no solo cuando el sistema lo pida.

Programación por parejas (pair programming). Todo el código de producción lo escriben dos
personas frente al ordenador, con un sólo ratón y un sólo teclado. Cada miembro de la pareja
juega su papel: uno codifica en el ordenador y piensa la mejor manera de hacerlo, el otro
piensa más estratégicamente, ¿Va a funcionar?, ¿Puede haber pruebas donde no funcione?,
¿Hay forma de simplificar el sistema global para que el problema desaparezca?

C.U. Marı́a Lorena Garcı́a TDD 15


Capı́tulo 2. Marco Teórico

El emparejamiento es dinámico, se puede emparejar con distintas personas, tomar criterios


como si una persona no conoce muy bien un trabajo sobre un área emparejarla con alguien
que sı́.

Propiedad colectiva (collective ownership). Cualquier persona que crea que puede aportar
valor al código en cualquier parcela puede hacerlo, ningún miembro del equipo es propietario
del código. Si alguien quiere hacer cambios en el código puede hacerlo. Si hacemos el código
propietario, y necesitamos de su autor para que lo cambie entonces estaremos alejándonos
cada vez más de la comprensión del problema, si necesitamos un cambio sobre una parte del
código lo hacemos y punto. XP propone un propiedad colectiva sobre el código nadie conoce
cada parte igual de bien pero todos conoce algo sobre cada parte, esto nos preparará para la
sustitución no traumática de cada miembro del equipo.

Integración continua (continuos integration). El código se debe integrar como mı́nimo una vez
al dı́a, y realizar las pruebas sobre la totalidad del sistema. Una pareja de programadores se
encargara de integrar todo el código en una máquina y realizar todas las pruebas hasta que
estas funcionen al 100

40 horas semanales (40-hour week). Si se quiere que los programadores estén frescos y mo-
tivados cada mañana y cansados y satisfechos cada noche. Esto requiere que trabajemos 40
horas a la semana, mucha gente no puede estar más de 35 horas concentrada a la semana,
otros pueden llegar hasta 45 pero ninguno puede llegar a 60 horas durante varias semanas y
aun seguir fresco, creativo y confiado. Las horas extras son sı́ntoma de serios problemas en el
proyecto, la regla de XP dice nunca 2 semanas seguidas realizando horas extras.

Cliente en casa (on-site costumer). Un cliente real debe sentarse con el equipo de programado-
res, estar disponible para responder a sus preguntas, resolver discusiones y fijar las prioridades.
Lo difı́cil es que el cliente nos ceda una persona que conozca el negocio para que se integre en
el equipo normalmente estos elementos son muy valiosos, pero debemos de hacerles ver que
será mejor para su negocio tener un software pronto en funcionamiento, y esto no implica que
el cliente no pueda realizar cualquier otro trabajo.

Estándares de codificación (coding standards). Si los programadores van a estar tocando


partes distintas del sistema, intercambiando compañeros, haciendo refactoring, debemos de
establecer un estándar de codificación aceptado e implantado por todo el equipo.

Algunas de estas prácticas reciben muchas crı́ticas, sobre todo la programación por parejas.
Muchos jefes de proyecto no aceptan que dos desarrolladores tengan un único ordenador, ya que
creen que esto minimizará la productividad, sin saber que de este modo puede producirse el mismo
código que dos personas trabajando en solitario pero con un código de mayor calidad.
XP lleva las mejores prácticas a niveles extremos [17]. Por ejemplo la práctica de hacer test
antes de desarrollar fue usada por la NASA en el programa Mercury Space por primera vez para

C.U. Marı́a Lorena Garcı́a TDD 16


Capı́tulo 2. Marco Teórico

tarjetas perforadas en 1960. XP la llevo al extremo con TDD. Aunque Kent Beck con XP no se
considera a sı́ mismo el creador de Test Driven Development, fue el que implemento SUnit, un
framework de tests unitarios para Smalltalk que fueron las bases de la familia xUnit (conjunto de
frameworks basados en sus premisas como nUnit, phpUnit, junit, MsUnit, etc). Este framework se
pensó para realizar TDD basándose en ideas de Gerard Weinberg y Leeds, Herbert D. en su libro
(Computer Programming Fundamentals – 1960).
CI(Continuos integration) fue propuesta y nombrada por primera vez en 1991 por Grady Booch
en su método (Método Booch). En este caso Booch no hablaba en ningún caso de integrar varias
veces al dı́a. Grady Booch es conocido por desarrollar UML junto con James Rumbaugh. En 1991/94
desarrolló el método Booch. Se trataba de una técnica usada en ingenierı́a software para el diseño
de objetos (predecesor de UML y RUP).Este método hablaba de uso de objetos, métricas, QA,
patrones de diseño, formalismo, madurez de procesos y una notación robusta. Habla de sacar
releases de arquitectura hasta llegar al sistema final (evolutivos). . . si, es el precursor de RUP
también, evidentemente.

2.2.2. SCRUM
Desarrollada por Ken Schwaber, Jeff Sutherland y Mike Beedle. Define un marco para la gestión
de proyectos, que se ha utilizado con éxito durante los últimos 10 años. Está especialmente indicada
para proyectos con un rápido cambio de requisitos. Sus principales caracterı́sticas se pueden resumir
en dos. El desarrollo de software se realiza mediante iteraciones, denominadas sprints, con una
duración de 30 dı́as. El resultado de cada sprint es un incremento ejecutable que se muestra al
cliente. La segunda caracterı́stica importante son las reuniones a lo largo proyecto. Éstas son las
verdaderas protagonistas, especialmente la reunión diaria de 15 minutos del equipo de desarrollo
para coordinación e integración.
Popular metodologı́a ágil, fácil de entender y de implementar en muchos tipos de procesos
de desarrollo, no siendo fácil de dominar porque requiere mucho esfuerzo de equipo y apoyo de
autoridades. Esta documentada en el “Scrum Framework”, es un conjunto de prácticas, guı́a de
grupos, roles, eventos, herramientas y reglas, con las cuales ejecutar proyectos. La teorı́a del método
Scrum está basada en tres pilares: Transparencia, Inspección y Adaptación [30]:

Transparencia: este pilar consiste en dar visibilidad a los responsables del producto final. Un
ejemplo de transparencia serı́a crear una definición común de que se entiende por “acabado”,
de manera que todas las partes estén de acuerdo.

Inspección: este pilar consiste en crear puntos de chequeo en los cuales verificar como está avan-
zando el proyecto hacia su meta final, vigilando posibles desviaciones problemáticas de lo que
serı́a el resultado final esperado.

Adaptación: este pilar consiste en ajustar un proceso para minimizar los posibles problemas
si una inspección muestra un problema o una tendencia indeseada.

C.U. Marı́a Lorena Garcı́a TDD 17


Capı́tulo 2. Marco Teórico

Es una metodologı́a en donde gran parte de las actividades que componen su proceso son
actividades de gestión. Las actividades se organizan en tres fases llamadas de pre-juego, juego y
post-juego. Las actividades técnicas se encuentran principalmente en las fases de Juego y post-
juego. La seleccion de estas practicas tiene su origen en un estudio realizado en Hirotaka Takeuchi
e Ikujio Nonaka sobre ”nuevas practicas de produccion.a mediados de los 80 en su articulo titulado
”The new product develoment game”[27]
Se descubrio que las empresas que estaban obteniendo mejores resultados en el desarollo de
software a pesar de lo acelerado que cambiaba el mercado eran aquellas que se estaban alejando de
la forma tradicional de desarrollar sus productos.
Los objetivos de la gestión con Scrum son[42]:

Generar Valor.

Reducción de tiempo de desarrollo.

Agilidad y flexibilidad.

Fiabilidad.

Scrum es un cambio en la mentalidad del equipo, además de cambiar la forma y organización


de los proyectos. No solo se busca un producto entregable y finalizado, sino un producto que
evoluciona y se adapta con el tiempo. No hay finalizaciones de fases, o de equipos especializados,
sino es terminar la interacción de un gran equipo multidisciplinario que otorga valor al producto.
No se busca terminar una fase de un equipo especializado, sino terminar una iteración de un equipo
multidisciplinario que agrega valor al producto.
En Scrum se debe tener disciplina, responsabilidad y la suficiente información para saber que
conlleva realizar esta implementación. Fomenta el trabajo en equipo,la responsabilidad del resultado
del proyecto es del equipo y no de una persona individual. Es una solución integral para la gestión
de proyectos que no tengan los requisitos definidos en su totalidad al inicio. Ayuda a que sea natural
agregar modificaciones o nuevas funcionalidades,cuando un proyecto ya se ha iniciado.
Scrum es una metodologı́a que se adapta a los proyectos que necesitan innovación constante.
Los equipos son retados a un cambio de mentalidad.
Las metodologı́as tradicionales ven los cambios como algo negativo y que se debe evitar a toda
costa, mientras que las metodologı́as ágiles lo ven como algo adecuado, que permite que el producto
se acerque más a lo que el cliente quiere.

2.2.3. Crystal Methodologies


Se trata de un conjunto de metodologı́as para el desarrollo de software caracterizadas por estar
centradas en las personas que componen el equipo (de ellas depende el éxito del proyecto) y la
reducción al máximo del número de artefactos producidos. Han sido desarrolladas por Alistair
Cockburn. El desarrollo de software se considera un juego cooperativo de invención y comunicación,

C.U. Marı́a Lorena Garcı́a TDD 18


Capı́tulo 2. Marco Teórico

limitado por los recursos a utilizar. El equipo de desarrollo es un factor clave, por lo que se deben
invertir esfuerzos en mejorar sus habilidades y destrezas, ası́ como tener polı́ticas de trabajo en
equipo definidas. Estas polı́ticas dependerán del tamaño del equipo, estableciéndose una clasificación
por colores, por ejemplo Crystal Clear (3 a 8 miembros) y Crystal Orange (25 a 50 miembros).
Crystal es una familia de metodologı́as diseñada para proyectos que van desde los dirigidos por
pequeños equipos desarrollando sistemas de baja criticidad (Crystal Clear), a aquéllos dirigidos por
grandes equipos construyendo sistemas de alta criticidad (Crystal Magenta). El sistema Crystal
provee un gran ejemplo de como adaptar un método para que coincida con las caracterı́sticas de
un proyecto y una organización. En la figura 3, vemos los métodos Crystal básicos:

Figura 2.1: Crystal Methods - Elaboración propia

El tamaño del equipo viene representado en el eje de las X y el nivel de criticidad del proyecto
en el eje de las Y. Crystal Clear está dirigido a proyectos pequeños con equipos de una a seis
personas. Los proyectos Crystal Clear desarrollan sistemas en los cuales un fallo puede resultar en
una pérdida de confort (p.e. un fallo en un videojuego) o una pérdida financiera de bajo nivel (p.e.
un fallo del procesador de textos resultante en una pérdida de tiempo en el negocio). Ası́, el proyecto
involucra a más gente y desarrolla aplicaciones más crı́ticas, escala los procedimientos detrás de la
comunicación cara a cara e introduce validaciones adicionales y medidas de trazabilidad.

C.U. Marı́a Lorena Garcı́a TDD 19


Capı́tulo 2. Marco Teórico

2.2.4. Dynamic Systems Development Method (DSDM)


Define el marco para desarrollar un proceso de producción de software. Nace en 1994 con el
objetivo el objetivo de crear una metodologı́a RAD unificada. Sus principales caracterı́sticas son: es
un proceso iterativo e incremental y el equipo de desarrollo y el usuario trabajan juntos. Propone
cinco fases: estudio viabilidad, estudio del negocio, modelado funcional, diseño y construcción, y
finalmente implementación. Las tres últimas son iterativas, además de existir realimentación a todas
las fases.
El método DSDM fue uno de los primeros métodos ágiles, y empezó muy prescriptivo y detallado.
Su cobertura del ciclo de vida del proyecto es amplia, abarcando aspectos de un proyecto ágil que
van desde la viabilidad y la justificación económica hasta la implementación.
DSDM se centra en 8 principios. Aunque estos principios fueron creados antes del Manifiesto.
Ágil, están alineados con éste. Los 8 principios son:

1. Centrarse en la necesidad del negocio.

2. Entregar a tiempo.

3. Colaborar.

4. Nunca comprometer la calidad.

5. Construir incrementalmente desde bases firmes.

6. Desarrollar de manera iterativa.

7. Comunicar continuamente y de manera clara.

8. Demostrar control.

DSDM ayudó a popularizar anticipadamente las consideraciones de arquitectura, filtros ágiles


idóneos, y contratos ágiles.

2.2.5. Adaptive Software Development (ASD)


Su impulsor fue Jim Highsmith. Sus principales caracterı́sticas son: iterativo, orientado a los
componentes software más que a las tareas y tolerante a los cambios. El ciclo de vida que propone
tiene tres fases esenciales: especulación, colaboración y aprendizaje. En la primera de ellas se inicia el
proyecto y se planifican las caracterı́sticas del software; en la segunda desarrollan las caracterı́sticas
y finalmente en la tercera se revisa su calidad, y se entrega al cliente. La revisión de los componentes
sirve para aprender de los errores y volver a iniciar el ciclo de desarrollo.
Es un modelo de implementación de patrones ágiles para desarrollo de software. Al igual que
otras metodologı́as ágiles, su funcionamiento es cı́clico y reconoce que en cada iteración se produ-
cirán cambios e incluso errores[28].
Sus principales caracterı́sticas del ASD son:

C.U. Marı́a Lorena Garcı́a TDD 20


Capı́tulo 2. Marco Teórico

Se basa en los riesgos.

Iterativo.

Orientado a componentes.

Soporta cambios.

ASD es un cambio orientado a un ciclo de vida donde hay tres componentes: especular, colaborar
y aprender.

Especular : Es la primera fase donde se establecen los principales objetivos, se analizan las
limitaciones, riesgos con las que se trabajar en el proyecto.
Las estimaciones sufren como en todo proyecto desviaciones, ayudan a la correcta atención de
los miembros del equipo, de forma de mover los plazos y dar correcta prioridad a las tareas.
Como en la mayorı́a de las metodologı́as ágiles se presta atención a las caracterı́sticas que
se requiere que pueden ser utilizadas por el cliente al final de cada iteración. Por lo tanto
hay una serie de tareas dentro de cada iteración que tienen prioridad, además que las tareas
o pasos se pueden volver a examinar hasta que los miembros del equipo y el cliente estén
satisfechos con el resultado.

Colaborar: Es la fase donde el desarrollo es el componente cı́clico, la coordinación, compartir


lo aprendido de manera de transmitir a los otros equipos, y que no se tenga que volver a ser
aprendido.

Aprender:La última etapa termina con una serie de ciclos de colaboración, su trabajo consiste
en capturar lo que se ha aprendido, tanto positivo como negativo. Es un elemento crı́tico para
la eficacia de los equipos. Jim Highsmith identifica cuatro tipos de aprendizaje en esta etapa:

• Calidad del producto desde un punto de vista del cliente: Es la única medida legı́tima
de éxito.
• Calidad del producto desde un punto de vista de los desarrolladores. La calidad desde
el punto de vista técnico.
• Gestión y rendimiento: Se evalúa los procesos utilizados por el equipo, y lo que se ha
aprendido.
• Situación del proyecto: Es cuando hacemos la planificación de la siguiente iteración, que
es el punto de partida de la construcción de la siguiente.

Usada de manera adecuada esta metodologı́a ASD se puede alcanzar excelentes resultados pero
debido a las caracterı́sticas que maneja es mas factible usarla para proyectos pequeños y medianos,
para adquirir practica y experiencia para ası́ poder llegar al Rapid Application Development (RAD)
en donde tendremos productos de alta calidad.

C.U. Marı́a Lorena Garcı́a TDD 21


Capı́tulo 2. Marco Teórico

2.2.6. Feature-Driven Development8 (FDD)


Define un proceso iterativo que consta de 5 pasos. Las iteraciones son cortas (hasta 2 semanas).
Se centra en las fases de diseño e implementación del sistema partiendo de una lista de caracterı́sticas
que debe reunir el software. Sus impulsores son Jeff De Luca y Peter Coad en 1997.

Figura 2.2: Desarrollo basado en caracterı́sticas - Elaboración propia

FDD recomienda un conjunto de buenas prácticas, derivadas de la ingenierı́a de software.


Estas prácticas incluyen:

Ámbito del modelado de objetos: En esta práctica, los equipos exploran y explican el ámbito
(o el ambiente de negocio) del problema a ser resuelto.

Desarrollo por caracterı́stica: Esta práctica implica romper funciones trozos de dos semanas
o menos y llamarlas caracterı́sticas.

Clase (código) individual de propiedad: Con esta práctica, las áreas de código tienen un único
propietario para garantizar la consistencia, rendimiento e integridad conceptual (a diferencia
del planteamiento colectivo del método XP).

Equipos por caracterı́stica: consiste en equipos pequeños, formados dinámicamente que per-
miten evaluar múltiples opciones de diseño antes de escoger un diseño. Los equipos de carac-

C.U. Marı́a Lorena Garcı́a TDD 22


Capı́tulo 2. Marco Teórico

terı́stica ayudan a mitigar los riesgos asociados a la propiedad individual.

Inspecciones: Son revisiones que ayudan a asegurar un diseño y código de buena calidad.

Manejo de la configuración: Esta práctica implica etiquetar códigos, rastrear los cambios, y
manejar el código fuente.

Construcciones regulares: A través de construcciones regulares, el equipo se asegura de que el


nuevo código se integra con el código existente. Esta práctica también permite crear fácilmente
una demo.

Visibilidad del progreso y de los resultados: Esta práctica rastrea el progreso basado en el
trabajo completado.

El desarrollo basado en las caracterı́sticas es una metodologı́a ágil que populariza los diagramas
de flujo acumulativos y los diagramas de parking. Ambas son herramientas útiles de rastreo y
diagnóstico que se utilizan ahora para otros enfoques ágiles.

2.2.7. Lean Development (LD)


Definida por Bob Charette’s a partir de su experiencia en proyectos con la industria japonesa
del automóvil en los años 80 y utilizada en numerosos proyectos de telecomunicaciones en Europa.
En LD, los cambios se consideran riesgos, pero si se manejan adecuadamente se pueden convertir
en oportunidades que mejoren la productividad del cliente. Su principal caracterı́stica es introducir
un mecanismo para implementar dichos cambios.
Estrictamente hablando, el desarrollo de software Lean no es un método ágil, pero los valores de
Lean y ágil están cercanamente alineados. Lean es un conjunto de principios que han sido obtenidos
de los enfoques Lean manufacturing y aplicados a desarrollo de software [30].

Eliminar las pérdidas: Para maximizar el valor, debemos minimizar las pérdidas. Para los
sistemas de software, las pérdidas pueden tomar la forma de trabajo parcialmente hecho,
retrasos, transferencias, caracterı́sticas innecesarias. Por lo tanto, para incrementar, debemos
desarrollar vı́as para identificar y eliminar estas pérdidas.

Dar poder al equipo: En lugar de tomar un enfoque de microgestión, debemos respetar el


conocimiento superior que tienen los miembros del equipo de los pasos técnicos necesarios en
el proyecto y permitirles tomar decisiones locales para ser productivos y obtener éxito.

Realizar entregas rápidas: Maximiza la rentabilidad en inversión del proyecto entregando


un software valioso de manera rápida e iterando a través del diseño. Encontramos la mejor
solución a través de la rápida evolución de las opciones.

Optimizar el total: El objetivo es ver el sistema como la suma de sus partes. Vamos más
allá de las partes del proyecto y buscamos como se alinean con la organización. Como parte de
optimización del total, también centrarce en la formación de mejores relaciones intergrupales.

C.U. Marı́a Lorena Garcı́a TDD 23


Capı́tulo 2. Marco Teórico

Construir la calidad desde dentro: El desarrollo Lean no intenta testear la calidad al final;
construye la calidad en el producto y continuamente asegura la calidad a través del proceso
de desarrollo, usando técnicas como la refactorización, integración continua, y testeo de las
unidades.

Aplaza decisiones: Equilibrar la planificación temprana tomando decisiones y comprome-


tiéndonos con las cosas lo más tarde posible. Por ejemplo, esto puede significar repriorizar la
cartera de pedidos hasta que sea hora de planear una iteración, o evitar estar atado a una
solución tecnológica determinada.

Amplificar el aprendizaje: Este concepto implica facilitar la comunicación desde el primer


momento y a menudo, obtener feedback lo antes posible, y construir sobre lo que aprendemos.

Los proyectos de software son experiencias de aprendizaje de negocios y tecnologı́a, es importante


empezar pronto y mantener un aprendizaje continuo. Lean da técnicas y conceptos como el mapeo
del flujo de valor, las siete formas de pérdidas, y trabajo en progreso (WIP).

2.2.8. Kanban - revisar


Es un desarrollo de sistemas de producción, que deriva de Lean utilizados en Toyota. “Kanban”
es una palabra japonesa que significa tablón de anuncios. El tablón de anuncios o tablón de tareas
Kanban, como también se llama, juega un importante papel en esta metodologı́a. Se limita el
trabajo en progreso (WIP) para ayudar a identificar los problemas y minimizar las pérdidas y
costes asociados con los cambios durante el desarrollo [30].
El desarrollo Kanban opera según cinco principios fundamentales:

Visualiza el flujo de trabajo: Los proyectos con trabajadores con conocimientos manipulan el
conocimiento, el cual es intangible e invisible. Es importante por lo tanto tener una manera
de visualizar el flujo de trabajo para organizar, optimizar y seguirlo.

Limitar el WIP: Si la cantidad de trabajo en proceso es baja, se aumenta la visibilidad de los


problemas y cuellos de botella, y a la vez facilita la mejora continua. Esto crea un sistema
de salida del trabajo a través del esfuerzo de desarrollo, de esta manera se reduce los costes
asociados con los cambios, y minimiza los costes perdidos.

Dirige el flujo de trabajo: Mediante el seguimiento del flujo de trabajo a través de un sistema,
los problemas pueden ser identificados y se puede medir la efectividad de los cambios.

Hacer polı́ticas de proceso explicitas: Es importante explicar claramente como funcionan las
cosas de manera que el equipo pueda tener discusiones abiertas sobre las mejoras objetiva-
mente en lugar de emocional o subjetivamente.

Mejorar la colaboración: A través de la medida y experimentación cientı́fica, el equipo debe


mejorar de manera colectiva los procesos que utiliza.

C.U. Marı́a Lorena Garcı́a TDD 24


Capı́tulo 3

Investigación de TDD

3.1. TDD (Test Driven Development)


El Desarrollo Guiado o Dirigido por Tests TDD, es una técnica de diseño e implementación de
software que se encuentra incluida dentro de la metodologı́a ágil XP [7].
Pero antes de hablar de TDD y su implementación vamos a hacer una introducción conceptual
corta iniciándonos en lo que es el desarrollo de software. Trataremos de encontrar su esencia, que
es lo que hace y principalmente porque no es solo hacer testing1 . Para empezar definiremos que es
software de una manera distinta a la clásica.
Una definición técnica de software serı́a “Es el conjunto de los programas de cómputo, proce-
dimientos, reglas, documentación y datos asociados, que forman parte de las operaciones de un
sistema de computación.”2 si analizamos otra definición por ejemplo la del paradigma orientado a
objetos que se separa de la representación técnica, y él cual se centra más en lo que está modelando
nuestro sistema nos permite hablar a un nivel un poco más alto de abstracción.
Según el paradigma Orientado a Objetos el software es un modelo computable de un dominio de
problema de la realidad, y como sabemos, construir un modelo es muy distinto a construir un auto
o una casa, es como implementamos una parte de la realidad que nos importa. Hay mucho debate
en si el desarrollo de software es una ciencia o es un proceso de ingenierı́a, pero en la opinión de
muchos el desarrollo de software es algo creativo y depende mucho el entendimiento que hacemos
del dominio del problema.
Por más que tenga muchas caracterı́sticas ingenieriles construir un software difiere bastante de
las ingenierı́as clásicas. Básicamente, difiere en el producto que uno tiene que construir, el software
tiene caracterı́sticas esenciales diferentes.
Cualquier ingenierı́a otorga mı́nimos conocimientos y capacidades para resolver problemas,
además de ofrecer las herramientas básicas para que se ejecute la implementación, pero la creati-
1 Pruebas de Software,conjunto de actividades dentro del desarrollo de software
2 Extraı́do del estándar 729 de IEEE

25
Capı́tulo 3. Investigación de TDD

vidad es la capacidad de generar nuevas ideas o conceptos, de nuevas asociaciones entre ideas y
conceptos conocidos, que habitualmente producen soluciones originales.
Según la Real Academia Española la creatividad es la facultad de crear o capacidad de creación.
Ahora el verbo crear nos dice:

1. tr. Producir algo de la nada.

2. tr. Establecer, fundar, introducir por vez primera algo; hacerlo nacer o darle vida, en sentido
figurado. Crear una industria, un género literario, un sistema filosófico, un orden polı́tico,
necesidades, derechos, abusos.

Esta definición nos ayuda mucho a convencernos que el desarrollo de software es algo creativo.
Cuando creamos también estamos aprendiendo. Ahora si pensamos en el desarrollo de software
como un proceso en el cual uno va adquiriendo conocimiento, donde nos vamos haciendo una idea
mental de cómo resolver el problema y al cual luego vamos representando, modelando, en lo que
nosotros llamamos programa, estarı́amos ante un proceso de aprendizaje.
Esto tiene mucho que ver con la esencia de lo que es TDD. Entender el desarrollo de software
como un proceso de adquisición de conocimiento ayuda a que no confundamos a TDD como solo
una herramienta de testing, donde el testing no es más ni menos que un medio para llegar al fin,
que es obtener un buen diseño.
Como todo proceso de aprendizaje si lo vemos desde la visión constructivista del aprendizaje,
donde la idea esencial es aprender haciendo. La evaluación de lo que vamos haciendo genera infor-
mación, por lo que es importante detenernos a pensar que hacemos con esta información. Como es
sistematizada, interpretada y comunicada, podemos decir que esta evaluación genera conocimiento
con un alto valor retroalimentador.
Las caracterı́sticas básicas de este proceso de aprendizaje son que es iterativo, incremental y
que hay que tener una retroalimentación inmediata. La metodologı́a de desarrollo Lean apoyada
por la comunidad ágil, en unos de sus principios hace hincapié en el desarrollo de software como
un proceso de aprendizaje [59], existe un marco teórico sólido y basado en la experiencia de las
practicas ágiles de gestión.
Para aprender algo y bien hay que obtener lo más rápido posible una retroalimentación. Cuando
desarrollamos necesitamos ir viendo como se comporta nuestro código, por eso el proceso iterativo
e incremental también hay que aplicarlo cuando uno está desarrollando software.
Cuando se empieza a entender que el desarrollo de software es un proceso iterativo, incremental
con feedback inmediato en definitiva constructivista, podemos empezar a pensar en herramientas,
técnicas, qué es lo que conviene utilizar. Por ejemplo un lenguaje de programación que tarde mucho
en realizar lo que está haciendo, claramente no está ayudando a obtener un feedback inmediato.
Además desde el momento en que se coloca el código fuente en un repositorio o al alcance de otros
desarrolladores supone un feedback inmediato a los desarrolladores sobre posibles defectos en el
código, problemas de seguridad, rendimiento, etc.

C.U. Marı́a Lorena Garcı́a TDD 26


Capı́tulo 3. Investigación de TDD

Una caracterı́stica esencial del software es que cambia3 , es mutable, ya sea porque cambia el
dominio del problema, o el soporte o nuestra manera de entender el dominio del problema.
Pero lo que impacta más es que nosotros cambiamos la manera de entender cuándo vamos
modelando y estamos continuamente en el desafı́o de poder reflejar ese cambio en nuestro modelo.
Cuando no podemos o no se quiere actualizar estamos en presencia de un sistema legacy4 .
Resumiendo, hay que tener claro que el software debe ser un buen modelo, representar correc-
tamente el dominio, ser fiable, fácil de cambiar (acompañar el proceso de aprendizaje del domino
del problema), y saber auto-defenderse de usos incorrectos[13].
Como explicamos anteriormente esta introducción es importante para entender la esencia de
TDD.

3.1.1. ¿Qué es TDD?


Según algunos autores (Hernan Wilkinson5 o Carlos Ble6 ), TDD es una técnica de aprendizaje
o de programación, porque ayuda al programador a entender el dominio del problema que esta
representado, que es iterativa e incremental y constructivista[13].
Constructivista porque estamos probando lo que estamos haciendo y obteniendo feedback inme-
diato porque justamente las pruebas nos indican si anduvo todo bien. Mediante las pruebas podemos
recordar todo lo aprendido y nos ayuda a no olvidar lo aprendido al quedar todo documentado en
las pruebas.
Algo fundamental de TDD es entender que incluye análisis, diseño, programación y testing.
Ya que implica entender el dominio del problema, un análisis correcto del dominio del problema,
hacer un buen diseño, una buena implementación y por supuesto testearlo. TDD no es solo hacer
testing, es una técnica que nos hace fluir por las etapa de análisis, diseño, programación y testing
del desarrollo del software [13].

3.1.2. ¿Cómo se hace TDD?


Para hacer TDD hay que seguir dos axiomas: El primero que introdujo Kent Benk “Nunca
escribas una nueva funcionalidad sin escribir primero una prueba que falle”[31]; él segundo axioma
expresado por Dave Chaplin “Si no se puede escribir una prueba para el nuevo código, entonces no
se deberı́a estar pensando en incorporar el nuevo código” [18].
Usando los axiomas mencionados diremos que TDD se divide en 3 sub-prácticas [58]:
3 Frederick Brooks, ingeniero conocido por escribir el ensayo ”No hay balas de Plata”1986 en donde manifiesta

que el cambio (mutabilidad) es una caracterı́stica esencial del software.


4 Sistema Legacy - Un sistema heredado (o sistema legacy) es un sistema informático (equipos informáticos o

aplicaciones) que ha quedado anticuado pero que sigue siendo utilizado por el usuario (generalmente, una organización
o empresa) y no se quiere o no se puede reemplazar o actualizar de forma sencilla.
5 Ingeniero en Software, profesor de la Universidad de Buenos Aires
6 Ingenieria Tecnica en Informatica de Sistemas, de la Universidad de la Laguna, autor del libro ”Diseño Agil con

TDD”

C.U. Marı́a Lorena Garcı́a TDD 27


Capı́tulo 3. Investigación de TDD

Primero los Tests: Las pruebas se escriben primero, incluso antes del propio código. Estás
deben estar escritas por los desarrolladores, por lo que nos referı́amos más arriba cuando
hablábamos de entender el dominio del problema. El proceso de aprendizaje que estamos
teniendo al desarrollar las pruebas, y el código implementado que se va a probar.

Automatización: Las pruebas deben ser ejecutadas automáticamente las veces que sea nece-
sario, debemos tener la retroalimentación inmediata que nos brindará el conocimiento de lo
que estamos probando, y si estamos en lo correcto o no.

Refactorizar: TDD habla de que la arquitectura se forja a base de iterar y refactorizar en lugar
de diseñarla completamente de antemano. La refactorización permite mantener la calidad de
la arquitectura, se cambia el diseño sin cambiar la funcionalidad, manteniendo las pruebas
como reaseguro.[55]

La esencia de TDD es sencilla pero ponerla en practica no es fácil, el entrenamiento, el acos-


tumbrarse a pensar primero en las pruebas es lo que lleva tiempo. El algoritmo TDD sólo tiene tres
pasos:

1. Escribir el test primero (el ejemplo, el test).

2. Implementar el código según dicho ejemplo.

3. Refactorizar para eliminar duplicidad y hacer mejoras

Escribir el test primero

¿Cómo escribimos un test para un código que todavı́a no existe?. Para contestar esta pregunta
vamos a repasar primero que hacemos cuando estamos haciendo las especificaciones de nuestro
dominio del problema.
En las especificaciones escribimos lo que deberı́a hacer nuestro software, los requisitos. En TDD
estarı́amos expresando un requisito en forma de código (el test), lo que debe hacer nuestro sistema
y que deberı́a devolver. Un ejemplo de esto son las JSR (Java Specification Request) que se escriben
para que luego en otras partes la implementen. En TDD escribimos nuestros tests para que luego
se implemente el código que los hará pasar.
Inicialmente a lo que llamamos ejemplo o test no es mas que una especificación [12]. La diferencia
fundamental es que el test puede ser modificado, una especificación se espera que no. Lo que en
realidad estamos haciendo es un ejemplo en código de como cumplir un requisito, una manera de
resolverlo, pero sin alterar la esencia del requisito.
Cuando elaboramos el test tenemos que hacer el esfuerzo de imaginar como serı́a el código como
si ya estuviera implementado, y como comprobarı́amos que hace efectivamente lo que queremos que
haga. Al tener que usar una funcionalidad antes de haberla escrito, buscamos simpleza, tratamos
de no complicarnos a nosotros mismos, que sea cómodo, más claro, pero que siempre cumpla con
el objetivo del requisito.

C.U. Marı́a Lorena Garcı́a TDD 28


Capı́tulo 3. Investigación de TDD

Los primeros tests son difı́ciles, al escribir el test empezamos a analizar el problema y empezamos
a pensar como lo escribiremos. Generalmente no se sabe por donde empezar o encarar el problema,
por donde resolverlo. Siempre conviene comenzar por la aserción o las aserciones, escribirlas, son
las que formaran parte del test, porque a partir de ellas voy a lograr deducir que es lo que quiero
probar [13].
El algoritmo de TDD es un ciclo que debe ser realizado de forma rápida, es posible incluso que
al agregar una caracterı́stica sea necesario crear muchos más tests, hasta que ya no quede más por
agregar o eliminar por medio de la refactorización.
Posteriormente veremos mediante ejemplos como desarrollar tests, su implementación y refac-
torización.

Implementar el código que hace funcionar el ejemplo

Teniendo las mı́nimas aserciones escritas en el test y el test falla, codificamos lo mı́nimo para que
éste pase. Las aserciones nos guı́an en lo que tenemos que hacer. Cuando decimos el mı́nimo código
nos referimos al que menos tiempo nos lleve escribir, si el código parece feo o groseramente simple
en este momento no nos debe importar, luego lo arreglaremos. Es importante no implementar nada
mas que lo mı́nimo y necesario para que el test pase.
Es un proceso de pensar la mejor forma de hacer eficiente el código, no de hacerlo sin pensar.
Es algo difı́cil de hacer, ya que solemos escribir mas código del que nos hace falta. El hecho de ser
minimalista en el código nos ayuda a desarrollar código eficiente.
Si nos concentramos en este paso nos aparecerán las dudas propias del requisito, el comporta-
miento que debe tener el software, si deberı́an existir nuevas especificaciones, si existen más entradas
de las que pensábamos. Haremos un análisis de los distintos flujos condicionales que pueden entrar
en juego.
De seguro estaremos tentados de escribir más código sobre la marcha, pero solo tenemos que
tener la atención de anotar las preguntas que nos surgen que podrán convertirse en especificaciones
que tendremos que retomar después.

Refactorizar para eliminar duplicidad y hacer mejoras

En la refactorización hay que enfocarse en escribir código que implemente una ejecución exitosa,
cuando decimos exitosa nos referimos a que el código haga lo que esperamos que haga y además las
pruebas pasen. Se debe enfocar en eliminar código duplicado, innecesario, mejorarlo para cumplir
con patrones de codificación establecidos que faciliten la lectura y claridad.
No significa reescribir código. Según Martı́n Fowler, refactorizar [37] es modificar el diseño sin
alterar el funcionamiento. En este paso del algoritmo de TDD intentaremos, porque no estamos
libres de pasar por alto algo, de buscar código duplicado, innecesario, tanto en los tests como
en el código. Se busca también cumplir con principios de diseño. Si estamos desarrollando con

C.U. Marı́a Lorena Garcı́a TDD 29


Capı́tulo 3. Investigación de TDD

programación orientada objeto podrı́amos usar S.O.L.I.D7 que son cinco principios. S.O.L.I.D fue
introducido por ”Tı́o Bob”Martı́n en el 2000. La idea es ser fiel a principios de desarrollo de software
para obtener mas robustes.
En la refactorización existen muchas recetas, dadas precondiciones se aplican determinados
cambios. Los cambios mejoran el diseño del software pero no alteran su comportamiento. Cuando
decimos que mejoran deberı́amos aplicar alguna métrica para afirmarlo, generalmente en la refac-
torización usarı́amos la métrica del código duplicado como parámetro de calidad. Entonces si no
existe código duplicado, obtuvimos código de mejor calidad comparándolo con el que presentaba
duplicidad.
Claro que la refactorización depende mucho del programador, de su conocimiento y experien-
cia. Hoy en dı́a existen muchas aplicaciones que ayudan al desarrollador en la refactorización sin
mencionar los IDE que también contribuyen bastante.
Aún ası́ existen refactorizaciones mas complejas, y otras que a modo de patrón parecen trucos
tı́picos de los que uno llama “trucos de cocina” que suelen eliminar la duplicidad, que mantenga su
coordinación con el resto del código lo que se suele llamar API Pública.
Como se decı́a arriba la refactorización depende mucho del desarrollador, se recomienda ir paso
a paso, para cada cambio ejecutar los tests. En este proceso suele pasarse de una visión global del
código a una local, es como repasar nuestro diseño modular, las llamadas, etc. La tarea de revisar el
código suele olvidarse o dejarse para el último, en la refactorización es donde la haremos. La ventaja
es que no estamos revisando todo el código sino a medida que lo implementamos y probamos.
Estarı́amos haciendo pruebas de unidad a medida que desarrollamos cada test y luego el código
que lo pasa. Y podrı́amos decir que hacemos pruebas de integración cuando corremos todos los
tests y refactorizamos.
Los pasos del algoritmo de TDD son todos importantes, si pasamos de largo uno no estamos
haciendo TDD.
Si nos preguntamos cual es el objetivo principal de TDD encontraremos que hay dos puntos de
vista, uno es que el objetivo de TDD es la especificación y no la validación. (Martin, Newkirk, y
Kess 2003 ). Es una manera de pensar a través de requisitos o diseño antes de escribir el código
funcional. Otro punto de vista es que es una técnica de programación como a Ron Jeffries le gusta
decir el objetivo de TDD es escribir código limpio que funciona.
Creo ambos argumentos son validos, me inclino más por la opinión de la especificación porque
a medida que vamos desarrollando los tests estamos cumpliendo especificaciones que nos dicen que
tiene que hacer el software y como realiza lo que hace y los resultados que debemos obtener, porque
nos obliga a pensar en que debe hacer el software antes de incluso hacer el código.
Es importante entender que no tener la cantidad de pruebas (unitarias o no) conducirı́a a
muchos ciclos de ida y vuelta entro lo que necesitamos desarrollar, la calidad requerida e incluso
para que el mismo desarrollador entienda la lógica de negocio. Por eso el uso de TDD (o sus
7 SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion)

es un acrónimo mnemotécnico introducido por Robert C. Martin1 2 a comienzos de la década del 20003 que representa
cinco principios básicos de la programación orientada a objetos y el diseño.

C.U. Marı́a Lorena Garcı́a TDD 30


Capı́tulo 3. Investigación de TDD

variantes) ayuda a asegurarse que un código correcto cortará los ciclos de ida y vuelta causados
por requerimientos incomprendidos. El proceso de desarrollo será más corto usando TDD que no
usarlo, independientemente de la pregunta de calidad.[9]

3.1.3. El lado no tan bueno de TDD


TDD como algunos autores afirman es una práctica de programación que se puede usar en casi
cualquier tipo de proyecto de desarrollo con el objetivo de mejorar la calidad del código, es una
mejora en el trabajo diario, en la rutina del programador. El programador obtiene mayor confianza
en su código.
Ahora como logramos obtener esa seguridad, la confianza y la rutina para usar TDD. Solo la
obtendremos con mucha disciplina, perseverancia, y práctica, mucha práctica.
A pesar de todo que lo que provee TDD, no es posible forzar el uso en sistemas que no fueron
concebidos para él, por ejemplo el mantenimiento de un código Legacy, ya que TDD fue concebido
para su aplicación desde él comienzo del desarrollo, sus premisas lo dicen: ”primero el test antes
del código”.
TDD no puede dar garantı́a de calidad, de duplicidad reducida si no se concibió desde un
principio el código fuente de una aplicación.
La realización a la inversa, es casi escribir el código de nuevo, escribir los test teniendo el código,
significarı́a los tests no estarı́an guiando el desarrollo.
No serı́a TDD sino solo testing.
Otro ejemplo en donde es casi imposible de aplicar TDD es cuando se intenta hacer TDD en el
desarrollo de la interfaz de usuario. Requiere demasiado esfuerzo, en realidad TDD esta mas hecho
para ser aplicado en capas donde esta la lógica del negocio.
Los casos descriptos son bien detallados en el trabajo de Fontela[24]. Luego en nuestros ejemplos
prácticos indagaremos aún más en estos casos en donde TDD no se pude aplicar con éxito.

3.2. ATDD (Acceptance Test Driven Development)


Se ha hablado de los dos puntos de vista validos sobre el objetivo de TDD, cuando se dice que
TDD tiene por objetivo la especificación y no la validación. De esta forma surge ATDD (Acceptance
Test Driven Development) o como muchos lo llaman TDD ampliado[24]. ATDD toma cada reque-
rimiento en la forma de una historia de usuario de la cual se crean varias pruebas que el usuario
deberá aceptar, se las llama pruebas de aceptación, y a partir de ellas se construye las pruebas
automatizadas, luego se hace los pasos que describe TDD.
ATDD es igual que TDD pero a un nivel diferente, se empieza con una lista de criterios escritos
por el cliente, requisitos de negocio y estos constituyen la lista de tests de aceptación. También
es conocida como STDD (Story Test Driven Development), Desarrollo Guiado por Historias de
Prueba.

C.U. Marı́a Lorena Garcı́a TDD 31


Capı́tulo 3. Investigación de TDD

Si no hay entendimiento con el cliente ni la mejor metodologı́a o técnica producirá un buen


resultado, es por eso que ATDD es quizás más importante que solo hacer TDD. El punto de partida
de ATDD es donde se relacionan varı́as metodologı́as ágiles como por ejemplo SCRUM y XP porque
en todas se parte de una lista de requisitos de aceptación.
En ATDD se afronta de una manera distinta la implementación, distinta a las metodologı́as
tradicionales, pero común a las de las metodologı́as ágiles. En ATDD la lista de requisitos se
escriben en una reunión entre el cliente y el desarrollador o todos los que formen en el equipo de
desarrollo. Al igual que las reuniones de SCRUM todos deben entender que es lo que hay que hacer
y por qué. Asimismo dejar claro de que modo se certificará que el software hace lo que se pide.
Las historias de usuarios en ATDD son requerimientos simples, suelen ser una lista de ejemplos
que cuentan lo que el cliente quiere. No representan la especificación, el cómo. Tienen que ser lo
mas claras posibles, sin ningún tipo de ambigüedad, de allı́ es que suele tener similitudes a un caso
de uso, salvando las diferencias.
Cada historia de usuario es el resultado de escuchar al cliente y de ayudarle a resumir el requisito
en una sola frase. Es importante escribirlas en el vocabulario que entiende el cliente, el vocabulario
del negocio.
La verdad es que al cliente no le importa el código sino que el sistema satisfaga sus requerimien-
tos, ATDD permite saber si se ha satisfecho esa necesidad, es un check list tanto para el cliente
como el desarrollador. Es verificar si las pruebas incluidas o las que están contenidas en una historia
de usuario están funcionando.
También se puede incluir atributos de calidad en los criterios de aceptación que no necesaria-
mente están en las historias de usuario. Cada historia de usuario genera preguntas, y cada pregunta
puede ser un criterio de aceptación que se puede transformar en un test o la suma de varios. Por
ejemplo para la generación de tickets se podrá hacer las siguientes preguntas que fácilmente se
convertirı́an en criterios de aceptación.

¿Quién puede generar un ticket?

¿Qué hace el sistema cuando se genera un ticket?

¿Qué contiene el ticket como datos?

La idea es que los criterios de aceptación sean concisos, cuanto menos palabras halla mejor,
intentamos que no haya ambigüedad, ejemplo ”Si el ticket fue creado se enviará un mail de confir-
mación ”.
Los tests de aceptación están escritos como dijimos por el cliente y el equipo de desarrollo por
lo tanto deben estar escritos en lenguaje humano, con términos que entienda el cliente.
Mas adelante veremos como conectar estos criterios escritos en lenguaje humano con herramien-
tas de automatización de tests que permiten ahorrar mucho el trabajo en la creación de datos que
serán usados por los tests.

C.U. Marı́a Lorena Garcı́a TDD 32


Capı́tulo 3. Investigación de TDD

ATDD o STDD es el comienzo de un ciclo iterativo en el desarrollo, a partir de un test de


aceptación vamos realizando un conjunto de tests unitarios hasta obtener el código que cumple con
el criterio. Como es de suponer en este ciclo no vemos el diseño gráfico ni la interfaz ni el conjunto
de tablas de una base de datos, simplemente estamos yendo de la lógica del negocio a lo técnico,
pero siempre usando lo que indica el cliente como criterio.
Si nos ponemos a resumir algunas de las ventajas que obtenemos usando ATDD, tendrı́amos:

Comunicación y visión compartida. Todo el equipo aprende la lógica del negocio y la entiende.
Se parte discutiendo y analizando ejemplos concretos de funcionamiento, y estos se discuten
con el cliente. Incluso el Cliente aprende de su negocio y puede ofrecer mejores ideas de
implementación o el equipo sugerir cambios significativos que agilicen, optimicen los procesos
de negocio. Se refinan los ejemplos, y se logra entender que es lo que hay que construir.

Guı́a para el desarrollo, antes de programar los programadores conocen los test de aceptación,
estos ejemplos que se analizaron y crearon serán los que ayudaran a minimizar dudas y
ambigüedades que se van presentando.

¿El qué? ¿Y no el cómo?. El equipo se prepara para preguntarle al cliente que quiere y no
como hacerlo. Existen herramientas que nos ayudan en esta etapa como el Concordion6. La
mayorı́a de las veces el cliente no sabe que es lo que quiere, el equipo intenta aclarar que es
lo que quiere haciendo preguntas con afirmaciones que no tengan ambigüedades, pero nunca
el cliente deberá indicar como implementarlo, salvo casos justificados.

El entendimiento de los criterios de aceptación, ayuda a prevenir bugs, en vez de controlar que no
haya bugs al final.

3.3. BDD (Behaviour Driven Development)


BDD en la Ingenierı́a de Software, Behavior-Driven Development o desarrollo guiado por el
comportamiento (DGC), es un proceso de desarrollo de software que surgió a partir de TDD. El
desarrollo guiado por el comportamiento combina las técnicas generales y los principios de TDD,
junto con ideas del diseño guiado por el dominio y el análisis y diseño orientado a objetos para
proveer al desarrollo de software con herramientas compartidas y un proceso compartido de co-
laboración en el desarrollo de software[57]. Esto significa crear una especificación o requerimiento
ejecutable que falla porque la caracterı́stica o comporamiento no existe, entonces prosigo con es-
cribir el código más simple que puede hacer pasar la especificación, a continuación, se realiza la
refactorización para eliminar la duplicación y el ciclo se repite hasta que la especificación esta lista.
Surgió originalmente con la intención de cambiar la palabra test (proveniente del uso de TDD)
por should, queriendo ası́ mejorar la comunicación entre desarrolladores y testers. Se basa en la
premisa: “Utilizar ejemplos que nos permitan describir comportamiento” [53].

C.U. Marı́a Lorena Garcı́a TDD 33


Capı́tulo 3. Investigación de TDD

Si se mira alrededor de BDD, es muy probable encontrar que la conversación, la colaboración,


escenarios y ejemplos son su núcleo, junto a las sugerencias para automatizar.
Decimos que es una metodologia que nos permite a traves de ejemplos en los escenarios ilustrar
un comportamiento[35].
Esto último es particularmente interesante, ya que, en lugar de pensar en pruebas o test, (tal
como TDD promueve) hablamos de describir comportamiento como plantea DDD8 , lo que a su vez
significa considerar la especificación de criterios/pruebas de aceptación tal como plantea ATDD[53].
BDD promueve el hablar el lenguaje del cliente, mantener la alta abstraccion sin caer en detalles
de implementación. Las clases y los metodos en lo que son las ideas principales de BDD se deben
escribir con el lenguaje del negocio, de modo que la lectura del codigo pueda ser leida como si fuera
una oracion, esto resulta muy util cuando los test falla, ya que los nombres cobran gran significado
para su posterior analisis [24].
BDD también se conoce como Especificación por Ejemplo. Los beneficios esperados son para
los equipos que ya utilizan TDD o ATDD pueden considerar BDD por varias razones[4]:

Ofrece una guı́a precisa sobre cómo organizar la conversación entre desarrolladores, probadores
y expertos en dominios

Las anotaciones originadas en el enfoque BDD están más cerca del lenguaje cotidiano y
tienen una curva de aprendizaje más superficial comparada con las de herramientas como Fit
/ FitNesse.

Las herramientas dirigidas a un enfoque BDD generalmente permiten la generación automáti-


ca de documentación técnica y de usuario final de las .especificaciones”de BDD.

3.4. Variantes de TDD clásico


En los primeros años, TDD se vio como sinónimo de pruebas unitarias automatizadas realizadas
antes de escribir el código.Simultáneamente, se escribieron los primeros frameworks de pruebas
automatizadas: SUnit para Smalltalk y JUnit para Java. Los mismos fueron las bases para la
construcción de las demás herramientas, a las que no sorprendentemente se las llamó genéricamente
xUnit.
Hay dos problemas con esta definición simplificada de TDD: el hecho de que se hable solamente
de pruebas, y el hecho de que se hable de que las mismas sean unitarias. El primera contrariedad
es el propio nombre de TDD, que incluye la palabra “test”. En efecto, mientras por un lado se
afirma que es una técnica de diseño y no de pruebas, el nombre invita a pensar otra cosa. Incluso
las herramientas que fueron surgiendo a partir de TDD, desarrolladas incluso por los mentores de
la práctica, requerı́an que el código de pruebas tuviese métodos cuyos nombres empezasen con test
y las clases fueran descendientes de algo como TestCase (si bien NUnit y la versión 4 de JUnit
8 Domain Driven Design

C.U. Marı́a Lorena Garcı́a TDD 34


Capı́tulo 3. Investigación de TDD

mejoraron esto, sigue estando presente la palabra Test en las anotaciones que utilizan). Nadie niega
que TDD genera un buen conjunto de pruebas de regresión, pero ese no pretende ser su objetivo
principal, sino más bien un efecto lateral positivo.
El segundo se produce porque en todos los ejemplos que plantean sus creadores, se trabaja sobre
pequeñas porciones de código, e incluso ellos mismos hablan de pruebas unitarias. Asimismo, las
herramientas reflejan esto en sus nombres: JUnit, SUnit, NUnit, etc. Y cuando Beck escribe su libro
de TDD se basa primordialmente en ejemplos de pruebas unitarias. Pero notemos que el propio
esquema de TDD y sus ventajas exceden en mucho las pruebas unitarias.
A continuación se plantean variantes al clásico TDD que se irán describiendo brevemente.

3.4.1. UTDD (Unit Test Driven Development


Con estos equı́vocos de origen de TDD, sin embargo, UTDD es una sigla menos habitual, se ha
aplicado con creciente éxito. Tal vez sus mayores ventajas hayan sido, además de las previstas:

Las pruebas en código sirven como documentación del uso esperado de las clases y métodos
en cuestión.

Muchos años a TDD se lo vio como sinónimo de pruebas unitarias automatizadas realizadas
antes de escribir el código.
UTDD habla solamente de pruebas y solo de pruebas unitarias, un motivo de este mal entendido
es su propio nombre, ya que usa la palabra Tests. Por ello la confusión de que se dice ser una técnica
de diseño y no de pruebas.
Otro motivo son las herramientas que salieron para el uso de TDD que implicaban que los test
o clases deberı́an empezar con el nombre tests. Tambien el hecho de que todos los ejemplos de TDD
que se plantean empiezan con pruebas unitarias, solo pequeñas porciones de codigo, o solo se habla
de pruebas unitarias.[24].
Con estos equı́vocos de origen, UTDD se ha aplicado con creciente éxito. Las mayores ventajas
de UTDD es que las pruebas de codigo sirven como documentacion del uso esperado de las clases
y metodos en cuestion[24].

Las pruebas en código indican con menor ambigüedad lo que las clases y métodos deben hacer.

Las pruebas escritas con anterioridad ayudan a entender mejor la clase que se está creando,
antes de escribirla.

Las pruebas escritas con anterioridad suelen incluir más casos de pruebas negativas que las
que escribimos a posteriori.

Sin embargo, con el tiempo también se evidenciaron algunas contras de la práctica:

Basa todo el desarrollo en la programación de pequeñas unidades, sin una visión de conjunto.
Hay un antipatrón clásico de UTDD que es el de una clase de prueba por clase productiva y
un método de prueba por método productivo.

C.U. Marı́a Lorena Garcı́a TDD 35


Capı́tulo 3. Investigación de TDD

Figura 3.1: Ciclo de UTDD - Elaboración propia

Relacionado con lo anterior, muchos han criticado la pretensión de que la arquitectura evolu-
cione sola, sin hacer nada de diseño previo.

No permite probar interfaces de usuario ni comportamiento esperado por el cliente.

Es una práctica centrada en la programación, con lo cual no sirve para especialistas del negocio
ni testers. Los testers tradicionales tienden a desconfiar de ella por este mismo motivo.

Si bien las refactorizaciones son más sencillas con pruebas automatizadas, los cambios de
diseño medianos y grandes suelen exigir cambios en las pruebas unitarias.

3.4.2. DDD (Domain Driven Design) or D3


DDD en castellano Diseño guiado por el dominio. Es el diseño complejo del sistema mediante
la creación de modelos y sub modelos de dominio que se intentan poner en práctica. Es el proceso
de pensar en el panorama general, descomponerlo y comprender las relaciones entre las partes.
Su mayor ventaja es crear sistemas cohesionados. Suele utilizarse para la confección de los Çasos
de Uso”. La filosofı́a de DDD es abstracta y quizás mucho más que un conjunto de patrones de
diseño que se ocupa de cómo diseñar un sistema grande, escalable y fácil de mantener. En última

C.U. Marı́a Lorena Garcı́a TDD 36


Capı́tulo 3. Investigación de TDD

instancia DDD se trata de crear un ecosistema de código que captura implı́cita o explı́citamente
partes importantes de conocimiento del dominio.
TDD y DDD no son mutuamente excluyentes, tener conocimiento en DDD, es ciertamente tener
también conicimiento en TDD, sienod siempre TDD el núcleo.
DDD no es necesariamente un análisis desde arriba hacia abajo, los contextos pueden ser aco-
tados, y posiblemente el concepto mas importante de DDD es poder usar un lenguaje del cliente
en todas partes y las conversaciones con el cliente es para determinar lineas generales para el uso
de TDD.
Por ejemplo, al escribir la lógica de negocio de dominio, uno no debe estar preocupado por
el ahorro de entidades en la base de datos. En resumen, no se debe pensar en nada fuera de los
dominios al escribir la lógica de negocio.[23]
”DDD es acerca del descubrimiento de lo QUÉ es necesario escribir, PORQUÉ es necesario
escribirlo y CUÁNTO esfuerzo hay que utilizar para ello ”[51]
Arriba se habı́a dicho que DDD no era un gran conjunto de patrones, tampoco es un lenguaje
de patrones, y menos un framework, ni nada mágico ”Silver bullet”9 . Como dijimos es una filosofı́a
abstracta que no esta basada en el código sino en el entendimiento del dominio. DDD se basa en
la colaboración y exploración con los expertos del Dominio ”Domain Experts”10 , experimentación
para producir un modelo útil.
La mayorı́a de los escritos sobre DDD son de Eric Evans, donde se ve conceptos de dominio
empresarial y el intento de mapearlos en artefactos de software. Abarca modelos y diseños de
dominio, desde el punto de vista conceptual y de diseño. Se discute los principales elementos en
DDD como Entidad, Objeto de Valor, Servicio, etc. y se habla de conceptos como Lenguaje Ubicuo,
Contexto Limitado y Capa Anticorrupción.
Las directrices, mejores prácticas, los marcos y las herramientas que los técnicos y los arquitec-
tos pueden utilizar en el esfuerzo de implementación usando DDD están influenciados por varios
aspectos arquitectónicos, de diseño e implementación tales como[51]:

Reglas de negocio

Persistencia

Almacenamiento en caché

Gestión de transacciones

Seguridad

Generación de Código

Desarrollo Impulsado por Pruebas


9 Balas de plata, una expresión para decir no me engañes que no existen soluciones mágicas en tecnologı́a
10 Expertos del dominio, los que saben la lógica del negocio.

C.U. Marı́a Lorena Garcı́a TDD 37


Capı́tulo 3. Investigación de TDD

Figura 3.2: Ciclo iterativo de DDD - Elaboración Propia

Refactorización

Como dijimos anteriormente el diseño con DDD está impulsado por el dominio y existen un
conjunto de patrones para crear aplicaciones empresariales desde el modelo de dominio la aplicación
de ellos permitirá construir sistemas que realmente satisfacer las necesidades de la empresa[16].
Los principales patrones de DDD, resumidos y simplificados [51]:

Códigos y Modelos

El modelo es el conjunto de conceptos que serán seleccionados para ser implementados en el


software, representados en código y/o cualquier otro artefacto de software utilizado para construir
el sistema a ser entregado. En otras palabras, el código es el modelo. A los modelos los podemos
trabajar con editores de texto o usando herramientas mas modernas que proporcionan muchas
visualizaciones (diagramas de clase UML, diagramas de entidad-relación, Struts / JSF, etc.).
Significa ser capaz de mapear - idealmente literalmente - los conceptos del modelo a un diseño /
código. Obviamente un cambio en el modelo significa un cambio en el código y el diseño. Y cambiar
el código que el modelo cambio. DDD no obliga a usar OO11 , pero como la mayorı́a de los lenguajes
11 Orientación a Objetos

C.U. Marı́a Lorena Garcı́a TDD 38


Capı́tulo 3. Investigación de TDD

Figura 3.3: Modelo vs Vistas del modelo - Elaboración propia

predominantes están basados en OO, la mayorı́a de los modelos serán en OO. Los conceptos del
modelo entonces se representarán con clases e interfaces, y las responsabilidades como miembros
de las clases.

Hablando el idioma

DDD aboga para que los expertos y desarrolladores del dominio se comuniquen conscientemente
utilizando los conceptos dentro del modelo. Ası́ los expertos de dominio hablan de la propiedad y
el comportamiento subyacente que se requiere en un objeto de dominio y los desarrolladores no
hablan de nuevas variables de instancia de una clase o columnas en una tabla de base de datos,
sino que usan un lenguaje ubicuo.
Si una idea no puede expresarse fácilmente, entonces indicarı́a un concepto faltante en el modelo
de dominio y el equipo deberá trabajar en conjunto para averiguar cúal es el concepto. Una vez
que está establecido el nuevo campo en pantalla o la columna en la tabla de la base de datos, se
seguirá la idea de eso.
Al igual que gran parte de DDD, esta idea de desarrollar un lenguaje omnipresente no es
realmente una idea nueva: los XPers lo llaman un ”sistema de nombres”, y los DBAs han reunido
durante años diccionarios de datos.

C.U. Marı́a Lorena Garcı́a TDD 39


Capı́tulo 3. Investigación de TDD

Modelos y contextos

Siempre que discutimos un modelo siempre está dentro de algún contexto. Este contexto suele
inferirse del conjunto de usuarios finales que utilizan el sistema. Estos usuarios se relacionan con
los conceptos del modelo de una manera particular, y la terminologı́a del modelo tiene sentido para
estos usuarios, pero no necesariamente para cualquier otra persona fuera de ese contexto. DDD
llama a esto Contexto limitado (BC). Cada modelo de dominio vive exactamente en un BC, y un
BC contiene precisamente un modelo de dominio.
La idea es que hay varios BCs en un sistema de información, que interactúan enviando archivos,
pasando mensajes, invocando APIs, etc. Ahora, si sabemos que hay dos BCs que interactúan entre
si, sabemos entonces que hay que tener cuidado de traducir entre los conceptos de un Dominio y
los de otro Dominio de otro BC.
Entonces se plantea el discutir las relaciones entre los BCs. DDD de hecho identifica un conjunto
completo de relaciones entre BCs, para que podamos racionalizar lo que debemos hacer cuando
necesitamos vincular nuestros diferentes BCs juntos:

Publicado : los BCs que interactúan están de acuerdo en un lenguaje común (por ejemplo, un
montón de esquemas XML sobre un bus de servicios empresariales) mediante el cual pueden
interactuar entre sı́;

Open host service: un BC especifica un protocolo mediante el cual cualquier otro BC puede
usar sus servicios;

Kernel compartido : dos BC utilizan un kernel común de código (por ejemplo, una biblioteca)
como una lingua-franca común, pero de otra manera hacen sus otras cosas en su propia manera
especı́fica;

Cliente / proveedor : un BC utiliza los servicios de otro y es un stakeholder (cliente) de ese


otro BC. Como tal, puede influir en los servicios proporcionados por ese BC;

Conformista : un BC utiliza los servicios de otro pero no es un accionista a ese otro BC. Como
tal, utiliza ”tal cual”(se ajusta a) los protocolos o APIs proporcionados por ese BC;

Capa anti-corrupción : un BC utiliza los servicios de otro y no es un stakeholder, sino que tiene
como objetivo minimizar el impacto de los cambios en el BC de lo que depende al introducir
un conjunto de adaptadores - una capa anticorrupción.

A medida que descendemos en esta lista, podemos ver que el nivel de cooperación entre los dos
BCs se reduce gradualmente.
Sin embargo, cuando llegamos al conformismo , sólo vivimos con nuestra suerte; Una BC es
claramente subordinada a la otra. Para no depender tanto de un BCs significa tener mas código
que implementar, por supuesto es mas costoso, pero reduce el riesgo de dependencia. Una capa
anticorrupción también es mucho más barata que la reintroducción de ese sistema heredado, algo

C.U. Marı́a Lorena Garcı́a TDD 40


Capı́tulo 3. Investigación de TDD

que en el mejor de los casos distraerı́a nuestra atención del dominio central y en el peor terminarı́a
en fracaso.
DDD sugiere que elaboremos un mapa de contexto para identificar nuestros BC y aquellos de
los cuales dependemos o dependemos, identificando la naturaleza de estas dependencias.
Lo que llamamos mapas de contexto y BCs es DDD estratégico. Averiguar la relación entre BCs
es bastante polı́tico cuando se piensa en ello: ¿qué sistemas de upstream de mi sistema dependen, es
fácil para mı́ integrarme con ellos, tengo influencia sobre ellos, ¿ confı́o en ellos? Y lo mismo es cierto
en sentido descendente: ¿qué sistemas utilizarán mis servicios, cómo expongo mi funcionalidad como
servicios, tendrán influencia sobre mı́? No entender esto o su aplicación podrı́a ser un fracaso.

Capas y hexágonos

Viendo hacia adentro y considerar la arquitectura de nuestro propio BC (sistema). DDD sólo
está realmente preocupado por la capa de dominio y no tiene mucho que decir sobre las otras capas:
presentación, aplicación o infraestructura (o capa de persistencia).
La mayorı́a de la lógica del negocio parece filtrarse en la capa de aplicación o (aún peor) capa
de presentación. DDD trata de que no haya ninguna lógica de dominio en la capa de aplicación o
de presentación. En su lugar la capa de aplicación se hace responsable de cosas como la gestión
de transacciones y la seguridad, o como en algunas arquitecturas también puede asumir la res-
ponsabilidad de asegurar que los objetos de dominio recuperados de la capa de infraestructura /
persistencia se inicialicen correctamente antes de interactuar.
Un inconveniente de la arquitectura en capas es que sugiere un apilamiento lineal de dependen-
cias, desde la capa de presentación hasta la capa de infraestructura.
En lugar de considerar nuestra aplicación como un conjunto de capas, una alternativa es verlo
como un hexágono.

Bloques de construcción

La mayorı́a de los sistemas DDD como dijimos probablemente utilizarán un paradigma OO.
Como tal, muchos de los bloques de construcción para nuestros objetos de dominio pueden ser bien
conocidos, como entidades, objetos de valor y módulos. Objetos de valor son cosas como cadenas,
números y fechas; Y un módulo es un paquete.
Sin embargo, DDD tiende a poner más énfasis en los objetos de valor de lo que podrı́a estar
acostumbrado. Por lo tanto, sı́, puede usar una cadena para contener el valor de la propiedad
FirstName de un cliente , por ejemplo, y eso probablemente serı́a razonable. Pero ¿qué pasa con
una cantidad de dinero, por ejemplo, el precio de un producto ? En su lugar, debemos introducir un
tipo de valor de Money , el cual encapsula la moneda y las reglas de redondeo (que serán especı́ficas
de la moneda ).
Además, los objetos de valor deben ser inmutables, y deben proporcionar un conjunto de fun-
ciones de efectos secundarios libres para manipularlos.

C.U. Marı́a Lorena Garcı́a TDD 41


Capı́tulo 3. Investigación de TDD

Los valores también deben tener semántica de valor, lo que significa (en Java y C #, por
ejemplo) que implementan equals () y hashCode () . También son a menudo serializable, ya sea en
un bytestream o tal vez ay desde un formato String . Esto es útil cuando tenemos que persistir.
La introducción de objetos de valor permite ampliar nuestro lenguaje omnipresente, el compor-
tamiento de los valores mismos. Si decimos que el dinero nunca puede ser negativo, esta implemen-
tación estarı́a dentro de objeto de valor Money, y no deberı́amos asegurarnos que no sea negativo
en cada parte que se use Money.
Ahora las entidades no necesitan explicarse mucho, suelen ser persistentes, normalmente mu-
tables y tienden a tener una vida de cambios de estado. En su libro Evans habla de contornos
conceptuales , una frase elegante para describir cómo separar las principales áreas de interés del
dominio. Los módulos son la forma principal en la que se realiza esta separación, junto con las
interfaces para asegurar que las dependencias de módulos sean estrictamente acı́clicas.

3.4.3. NDD (Need-Driven Development )


Ya se menciono que TDD surge en ambientes orientados a objetos, aun siendo una practica
independiente del paradigma utilizado el mayor uso es en proyectos orientados a objetos (OO).
En la programación orientada a objetos se pone enfasis en el comportamiento de los objetos
mas que en el estado.
En el marco de TDD lo primero que hacemos es establecer la interfaz de nuestros objetos y
escribir pruebas sobre ellos suponiendo que tienen esa interfaz. Por lo tanto, el encapsulamiento de
los objetos se debe garantizar con ejemplos antes de pasar a la implementación.
Tradicionalmente en UTDD o en TDD se suele verificar el comportamiento de los objetos veri-
ficando el cambio de estado provocado por determinados mensajes recibidos por ellos. Esta forma
de verificación tiene dos problemas, no siempre le comportamiento de un objeto puede evaluarse
por el cambio de sus estados o por los valores que devuelve. Un ejemplo es un objeto receptor debe
imprimir algo,o enviar un mail o almacene ciertos datos en la base de datos. El chequeo de valores
devueltos no nos sirve para evaluar el comportamiento. Para chequear el estado en que queda un
objeto luego del envı́o de un mensaje, hay ocasiones en que necesitamos métodos de consulta que la
clase del objeto no tiene, y nos vemos obligados a cambiar la interfaz de la misma solamente para
las pruebas. Esto es contrario al principio del encapsulamiento.
Como propuesta de solución para esto nace NDD (Need-Driven Development) en castellano
”Desarrollo guiado por las necesidades”, en OOPSLA 2004, Steve Freeman y otros tres autores
presentaron un trabajo con ese nombre en el que plantean que el comportamiento de los objetos
deberı́a estar definido en términos de cómo envı́a mensajes a otros objetos, además de los resultados
devueltos en respuesta a mensajes recibidos, esto último propio de UTDD.
La diferencia con UTDD tradicional es que pretende definir de antemano que mensajes emi-
tirá un objeto sometido a prueba cuando reciba un mensaje en particular.
NDD propone implementarlos como objetos ficticios a partir solamente de la interfaz requerida.

C.U. Marı́a Lorena Garcı́a TDD 42


Capı́tulo 3. Investigación de TDD

Al probar un objeto de forma aislada, el programador se ve obligado a tener en cuenta las


interacciones de un objeto, posiblemente antes de que existen aquellos con los que interactuará.
NDD usa objetos Mock12 orienta el diseño de interfaz por los servicios que requiere un objeto, no
sólo los que proporciona. Este proceso resulta en un sistema de interfaces relacionadas y cada una
de los cuales tiene un papel en la interacción.
El procedimiento a seguir para la prueba de cada método con NDD serı́a entonces[24]:

Escribir las expectativas para describir los servicios que el objeto receptor requiere del resto
del sistema.

Representar los servicios como Mock Objects, mediante sus interfaces.

Crear el resto del contexto para que la prueba corra.

Definir las postcondiciones que sean necesarias.

Verificar las expectativas y las postcondiciones.

Cuando llegas a un punto en el que necesitas una función, o un módulo que no existe, sim-
plemente haces el desarrollo de la simulación y continuas con el módulo actual. El desarrollo de
esta manera tiene ventajas distintas. En primer lugar, permite que cada módulo evolucione de for-
ma natural, como segunda ventaja ahorra tener que predecir la interfaz de un módulo, el cual se
necesitará antes de tiempo.
Los objetos Mocks también mejoran el proceso de desarrollo al facilitar una metodologı́a conoci-
da como pruebas basadas en la interacción. Las pruebas simplemente verifican que un módulo dado
interactúa con otros módulos de una manera esperada y produce un resultado esperado basado en
un conjunto dado de entradas.

3.4.4. TDM (Test Driven Maintenance)


TDM en castellano Mantenimiento dirigido por pruebas nace de la estadı́sticas de que la mayor
parte de los trabajos que se hacen vienen con código heredado,y de las inquietudes de cómo hacer
para mejorar el código que tenemos.
La idea de usar TDM es obtener resultados similares a los que se genera utilizando TDD, pero
cabe aclarar que no es un desarrollo guiado por pruebas, el código existe. Cuando hacemos TDD
no tenemos código.
TDM se basa en adaptar las tecnologı́as utilizadas en TDD para el mantenimiento del código,
sabiendo que el código heredado es el caso más común en que estaremos en un entorno laboral, de
hecho es casi imposible que no exista y de que este este documentado. Ahora para garantizar que
esta metodologı́a funcione se debe primero estudiar el código existente.
Para empezar existen dos prinicipios, primero priorizar la creación de los casos de prueba para
comprender cómo funciona el código y segundo, antes de introducir cualquier cambio en el código
12 Objeto Simulado, objetos que imitan el comportamiento de objetos reales de una forma controlada

C.U. Marı́a Lorena Garcı́a TDD 43


Capı́tulo 3. Investigación de TDD

heredado se debe construir un set de pruebas unitarias que cubran el comportamiento del objeto
que deseamos modificar.[39]
Esto puede ser muy ambiguo y para cada caso muy diferente de encarar, mas si el código es
extenso, pero para clarificar un poco debemos enfocarnos en que funciones debemos dedicar nuestros
esfuerzo en hacer el set de pruebas que parte del código. Para esto TDM recurre a las heurı́sticas,
como por ejemplo el tamaño de la función, la frecuencia de modificación, frecuencia de corrección
de defectos, entre otros.
Una clasificación utilizada es :

Modificación:

• MFM - (Most frequently modified) Las funciones que fueron modificadas más veces desde
el inicio del proyecto, tienden a decaer con el tiempo permitiendo la aparición de defectos.
• MRM - (Most recently modified) Las funciones que fueron modificadas recientemente,
tienen mayor tendencia a tener defectos (debido a los cambios recientes)..

Corrección de Defectos:

• MFF - (Most frecuently fixed) Las funciones que fueron corregidas más veces desde el
inicio del proyecto y las funciones que fueron corregidas muchas veces en el pasado,
tienen más probabilidades de tener defectos en el futuro.
• MRF - (Most recently fixed) Las funciones que fueron corregidas recientemente, tienen
más probabilidades de tener defectos en el futuro.

Tamaño:

• LM - (Largest Modified) Las funciones modificadas más grandes, en términos de número


total de lı́neas de código (incluyendo comentarios y lı́neas en blanco) y las funciones más
grandes tienden a tener más defectos que las funciones más pequeñas.
• LF - (Largest fixed) Las funciones corregidas más grandes, en términos de número total
de lı́neas de código (incluyendo comentarios y lı́neas en blanco) y las funciones más
grandes que necesitaron ser corregidas tienden a tener más defectos que las funciones
más pequeñas que han tenido menos correcciones.

Riesgos:

• SR - (Size Risk) Funciones de mayor riesgo, definidas por el número de cambios de


corrección de defectos dividido por el tamaño de la función en lı́neas de código. Como las
funciones más grandes pueden naturalmente necesitar más correcciones que las funciones
más pequeñas, se normaliza el número de corrección de defectos por el tamaño de la
función. Esta heurı́stica señalará las pequeñas funciones que se corrigen mucho (es decir,
las que tienen alta densidad de defectos).

C.U. Marı́a Lorena Garcı́a TDD 44


Capı́tulo 3. Investigación de TDD

• CR - (Change Risk) Las funciones más riesgosas definidas por el número de corrección
de defectos divididas por el total de número de cambios. Por ejemplo, una función que
cambia 10 veces y 9 de ellas era para corregir defectos, deberı́a tener una prioridad
mayor de ser testeada que una función que fue cambiada 10 veces, pero sólo una fue
para corregir defectos.

Aleatorio:

• Random - Seleccionar funciones de manera aleatoria para escribir casos de prueba puede
considerarse como el escenario de lı́nea base, por lo tanto usamos el rendimiento de la
heurı́stica aleatoria para comparar el rendimiento de las otras heurı́sticas. Entre las cosas
que encontré mientras escribı́a este artı́culo, hay una afirmación en la que se expresa que
de todos los métodos anteriormente descriptos, los que mejores resultados generan son
LM (Largest Modified) y LF
• (Largest Fixed) “Aún combinando diferentes criterios para intentar mejorar el rendi-
miento, LM y LF se mostraron imbatibles”.

El uso de TDM reduce la cantidad de errores mejorando la calidad del producto. El resultado final
es un sistema más sólido ya que garantiza que por el despliegue de las pruebas, el momento y la
forma en que se realizan los cambios funcionen, en comparación con los métodos tradicionales en
los que el código sólo se prueba mucho tiempo después de su ejecución, obligando al desarrollador a
pensar en pequeños trozos de código que pueden ser probados de manera aislada e independiente.
En resumen su metodologı́a sigue los siguientes 5 pasos, que se repiten a modo de ciclo:

1. Se extrae información histórica (de nuestro repositorio de código y base de datos de bugs
registrados).

2. Se calculan las heurı́sticas (criterios seleccionados).

3. Como resultado se obtiene un listado de métodos a probar.

4. Se aı́slan los métodos y se escriben sus pruebas unitarias.

5. Se marcan los métodos como ya considerados.

6. Vuelta al paso 1

El principal obstáculo de esta metodologı́a es la reticencia inicial del equipo para adoptar ésta
técnica. Principalmente porque los desarrolladores que deben escribir más código de lo usual. La
curva de aprendizaje es alta, y los lenguajes de programación que no contemplan el marco de
pruebas unitarias puede ser una tarea difı́cil.
Se suele decir que el mismo código es la documentación del sistema, pero muchas veces no suele
ser suficiente para entender la funcionalidad, por lo que naturalmente hay un rechazo a modificar
una porción de código al no querer generar errores en otras partes del sistema.

C.U. Marı́a Lorena Garcı́a TDD 45


Capı́tulo 3. Investigación de TDD

Pero todos estos miedos y rechazos a implementar TDM hay que superarlo ya que los beneficios
pueden ser muchos, como por ejemplo menos errores y perı́odos de mantenimiento más cortos, es
lo que nos dice Michael Feathers en su libro ”Working Effectively with Legacy Code”.

3.4.5. BDD, ATDD, NDD ¿ sus diferencias?


Hay muchos otros terminos que también suelen utilizarse como sinonimos por ejemplo Specifi-
cation by Example (SBE)[1], Story Test Driven Development (STDD) o ATDD, Example-Driven
Development (EDD), Agile Acceptance Testing,Test-Driven Requirements (TDR) y muchos otros,
todos ellos se enfocan en tener un ejemplo o historia de usuario desde la perspectiva del desa-
rrollador y el cliente, en la captura de los requisitos. BDD da una compresión mas clara, intenta
garantizar coherencia entre lo que se espera del software y las pruebas de desarrollo, lograr que las
pruebas representen las funcionalidades requeridas.
Parecen ser todo lo mismo, las diferencias son los enfoques de sus autores, el nivel de abstracción
sobre los requisitos donde los que participan del proyecto colaboran en determinar las pruebas que
guiaran el desarrollo.
Las más conocidas BDD y ATDD, cuales son sus diferencias? Alguos puntos de ambas son
bastante diferentes, ATDD son pruebas de aceptación que se hacen con los usuarios (o sus repre-
sentantes) antes de comenzar a desarrollar, un requisito importante es que estas se automaticen.
Por otro lado, BDD busca un lenguaje común para unir la parte técnica y la de negocio, y que sea
desde ese lenguaje común desde donde arranque el Testing, destacando el Testing unitario y, desde
ahı́, el desarrollo, nos orientamos entonces, como parece razonable a un TDD.
Es como si BDD fuera el puente entre TDD y ATDD ya que combina las practicas de ambas.
Pero hay autores como Markus Gärtner que dice en el libro ATDD by Example explı́citamente
que ATDD es conocido por varios nombres, destacando algunos como: – Behavior-Driven Develop-
ment (BDD) – Specification by Example – Agile Acceptance Testing – Story Testing
Diferencias mas claras que expone Carlos Fontela13 entre ATDD y BDD:

13 Docente en la Universidad de la Plata, Especialista en Ingenierı́a de Software.

C.U. Marı́a Lorena Garcı́a TDD 46


Capı́tulo 3. Investigación de TDD

ATDD BDD

Test-First con pruebas de aceptación Test-First con pruebas de comportamiento

Automatizadas o no Automatizadas al estilo de TDD

Requerimiento (US)14 =¿Pruebas de acepta- US con lenguaje del negocio =¿UAT con len-
ción (UAT)15 guaje de comportamiento

Idea de especificación basada en ejemplos Idea de especificación basada en comporta-


miento

Si se automatiza: especificación ejecutable

Cuadro 3.1: Comparación de ATDD y BDD.

C.U. Marı́a Lorena Garcı́a TDD 47


Capı́tulo 4

Prácticas y técnicas con TDD

Los principales puntos en el desarrollo ágil es la entrega continua y regular de valor. Por ello
existen muchas técnicas como la integración continua (CI), la cual nos ayuda a tener un software
compilable en todo momento. Pero no basta con que el software únicamente se pueda compilar,
de hecho es el primer paso de toda una serie de elementos y caracterı́sticas que debe cumplir el
software.
Otra práctica que mitiga los niveles de riesgos introducidos por los cambios con modificaciones
solicitadas o realizadas durante un sprint de desarrollo, es el ejecutar constantemente pruebas de
software automatizadas, las que deben estar presentes en las diferentes fases del ciclo de vida del
software. Aquı́ es donde aparece TDD como una práctica de software para algunos o metodologı́a
según otros,y por consiguiente la refactorización.
La refactorización es un tema bastante interesante y complejo, que lleva a una serie de muchos
otros como son los patrones de diseño, los ”malos olores.en el código, etc. que estaremos desarrollando
en este capı́tulo.
Lo más recomendable es que la propia refactorización sea parte del proceso de desarrollo que
surja como algo natural .

4.1. Refactorización
En la refactorización el objetivo es reescribir el código de manera de obtener un mejor diseño. Un
código más simple sin ninguna lı́nea innecesaria, siempre tratando de minimizar y dar eficiencia. La
idea es, no hay que buscar errores y corregir sino reescribir el código, idea de los gurús del software
libre[47].
El convencimiento de que la inclusión de pruebas (que nos da TDD), y que la corrección de
errores será algo mucho más costoso en el futuro que la propia reescritura ayuda al que el software
sea mantenible.
Tener un sistema mantenible, simple habré muchas posibilidades. Los nuevos desarrolladores

48
Capı́tulo 4. Prácticas y técnicas con TDD

que entren al proyecto y quieran realizar aportes no se verán contra una pared con el código.
En refactorización no es necesario tener el conocimiento de toda la infraestructura para poder
aportar un código simple y fácil de entender, ni de tenerla creada antes de refactorizar. Complicado
serı́a tener que crear una infraestructura que pueda preveer todas las funcionalidades futuras,
incluso las que todavı́a no se han llegado a pensar, por lo que si no refactorizamos acabará siendo
un impedimento.
Con la refactorización continua se podrı́a evitar que aplicaciones enteras sean reescritas, porque
los errores de diseño, la calidad del código y otros parámetros hacen imposible mantener la antigua
versión.
En el caso de un sistema legacy la refactorización permite tomar diseños defectuosos, con códi-
go mal escrito (duplicidad, complejidad innecesaria, por ejemplo) y adaptarlo a uno bueno, más
organizado.
La refactorización también muestra que el diseño no se da solo al inicio, sino también a lo largo
del ciclo de desarrollo, durante la codificación, de manera tal que el diseño original no decaiga.
Antes de hablar un de los pasos o consejos sobre que refactorizar, vamos a definir los tipos de
refactorización.

Refactorización de código: El tipo de refactorización más conocido, comprende el código fuen-


te.

Refactorización de base de datos: Cambios en el esquema (Schema) de base de datos que


mejoran su diseño.

Refactorización de Interfaz de usuario: Cambios de estandarización de la presentación, man-


teniendo la funcionalidad, por ejemplo alinear campos, alinear tamaños de botones, entre
otros.

En este trabajo nos enfocaremos en la refactorización de código fuente.

4.1.1. Refactorización segura


Una de las técnicas más importantes en el desarrollo ágil de software y en particular del Test
Driven Development (TDD) es la refactorización, la cual consiste en hacer modificaciones al código
existente para mejorar su diseño de forma tal que no afecte su comportamiento externo.
La refactorización, se realiza en pequeños pasos, simples, uno a uno: extraer código de un método
para convertirlo en un método independiente, mover código arriba o abajo en una jerarquı́a, reunir
código duplicado en un mismo lugar. En TDD como mencionamos anteriormente la refactorización
es el paso siguiente a la verificación de que los test pasan.
El problema es que esta tarea de refactorizar se hace siempre de forma manual, en ocasiones
con alguna ayuda del entorno de programación. Es el programador quien debe averiguar cuándo
se deben aplicar técnicas de refactorización sobre el código, en qué partes del mismo y qué técnica
concreta de refactorización utilizar en cada caso.

C.U. Marı́a Lorena Garcı́a TDD 49


Capı́tulo 4. Prácticas y técnicas con TDD

La refactorización tiene como prioridad la conservación del comportamiento del codigo, por
lo que primeramente deberiamos tener clara idea de lo que esto significa. Opdyke[41] definió y
demostró la preservación del comportamiento del código a través del proceso de refactorización.
Opdke dice:

1. Hay una única superclase

2. Las clases tienen nombres distintos

3. Los miembros de una misma clase y las funciones deben tener nombres distintos.

4. En las redefinición de una función, las signaturas deben ser compatibles (para preservar el
principio de substitucón de Liskov[41])

5. Se debe conservar el tipo en las asignaciones

6. Las operaciones y referencias deben ser semánticamente equivalentes1 .

La refactorización es una herramienta peligrosa y a la vez poderosa, no se puede aplicar sin


analizar. En los tipos de refacorizaciones descriptos por Opdyke se definen precondiciones, las
cuales deben ser cumplidas para preservar el comportamiento del programa[41].
Opdyke divide en dos grandes categorı́as:

1. low-level refactorings (refactorizaciones de bajo-nivel), el comportamiento se conserva si pre-


condiciones son respetadas.

2. composite refactorings (refactorizaciones compuestas) los cuales se construyen con las de bajo-
nivel. Dado que las compuestas están construidas usando refactorizaciones que preservan el
comportamiento, entonces el comportamiento se conserva si también las precondiciones son
cumplidas.

Se define una cierta metodologı́a particular de cuando y cuanto refactorizar, es una secuencia
similar a la siguiente:

1. Revisar código y diseño para identificar refactorizaciones.

2. No cambiar la funcionalidad al aplicar una refactorización.

3. Correr los test sin excepción.

4. Repetir los pasos anteriores para encontrar más refactorizaciones que aplicar.

Además, existen algunas importantes heurı́sticas a tener en cuenta durante el proceso, que tienen
mucha relación con lo anteriormente expuesto.
1 Opdyke define equivalencia semántica, cuando una función es llamada dos veces, una antes y otra después, y en

ambas llamadas se obtiene el mismo conjunto de valores de salida.

C.U. Marı́a Lorena Garcı́a TDD 50


Capı́tulo 4. Prácticas y técnicas con TDD

No añadir funcionalidad a la vez que se refactoriza. La prioridad de la refactorización como


se dijo, es no cambiar el comportamiento del código. Si el comportamiento cambia entonces
será imposible asegurar que la refactorización no ha estropeado lo que antes ya funcionaba
(Wampler, 2002; Deursen y Moneen 2002).

Uso estricto de las pruebas. Al realizar pruebas en cada paso se reduce el riesgo del cambio,
siendo este un requisito obligatorio tras la aplicación de cada refactorización individual.

Refactorizar es aplicar muchas refactorizaciones simples. Cada refactorización individual pue-


de realizar un pequeño progreso, pero el efecto acumulativo de aplicar muchas refactorizaciones
resulta en una gran mejora de la calidad, legibilidad y diseño del código.

Martin Fowler también define en su libro una serie de pasos sistemáticos que se pueden realizar
en la refactorización, pero desde el punto de vista de criterios para modificar el código. Con técnicas
que están claramente definidas.
Fowler [37] habla de ‘bad smells’, código que ‘huele mal’, y nos da pistas sobre como localizarlo:
código duplicado, métodos o clases demasiado extensas, listas de parámetros muy grandes, son
pistas de que es necesaria una intervención importante. La idea es crear un codigo cohesivo y
modular, también se revisan nombres inadecuados y acoplamiento. [26]
Fowler realizó un estudio sobre las técnicas de refactorización dando patrones de modificación
de código con el fin de obtener un resultado con la misma funcionalidad pero con un diseño más
simple y sencillo de comprender.

4.1.2. ¿Qué refactorizar?


Antes de preguntarnos que refactorizar, nos preguntaremos cuando debemos hacerlo. Para poder
cumplir la regla de oro de la refactorización, que consiste en no modificar el comportamiento del
software, el programador debe diferenciar el momento en que esta refactorizando con el momento
en donde necesita agregar una nueva funcionalidad.
Por lo tanto no puede refactorizar (modifica código ) y al mismo tiempo agregar una funciona-
lidad. Cuando se añade código nuevo, NO se debe modificar el existente. Si se esta arreglando el
existente, NO se debe añadir nuevas funcionalidades.
Hay que arreglar el código con frecuencia, hacerlo sistemáticamente, que estando en TDD es casi
natural hacerlo. Deberı́amos refactorizar al momento de añadir cualquier nuevo código que pase el
test que recién hemos creado, cuando se agrega un método/función, cuando algo ”huele mal”, o al
revisar el código.
Una forma de guiarnos sobre que refactorizar son los “Design Smells”2 de Fowler. Estos Design
smells incluyen problemas de bajo nivel o locales, tales como “Code smells”3 que suelen ser sı́ntomas
2 Soluciones pobres de diseño para problemas software generalizados y recurrentes
3 Código que huele mal.

C.U. Marı́a Lorena Garcı́a TDD 51


Capı́tulo 4. Prácticas y técnicas con TDD

de defectos de diseño a un nivel más global, como los antipatrones4 . Dichos Code smells son indi-
cadores o sı́ntomas de la posible presencia de Design smells. Fowler presenta veintidós Code Smells
en su libro [37], todos ellos estructuras en el código fuente que sugieren la posibilidad de refacto-
rizaciones. Duplicated code, long methods, large classes, y long parameter lists, son sólo algunos
sı́ntomas de Design smells y de oportunidades de refactorización de entre los veintidós presentados.
“Se utiliza el término “smell” para designar tanto los errores en código (Code smells) como los
Design smells. Este uso no excluye que, en un contexto particular, un smell pueda ser la mejor
forma de diseñar o implementar de manera efectiva un sistema” [38].
Además hay otros Design Smells a tener en cuenta como Bad Pattern Usage(Referente a la mala
aplicación de un patrón en el código a analizar como puede suceder, por ejemplo, con el patrón
Singleton, lo que nos lleva a los antipatrones) o Metrics Warnings (Donde la herramienta detecta
defectos a través del cálculo de métricas).
También estan las Disharmonies: “Defectos de diseño que afectan a entidades individuales tales
como clases y métodos”[33].
Para tener una guia de que refactorizar se puede empezar con listas de antipatrones (que se
pueden encontrar en [11] [56], Bad Smells y de Disharmonies. Debido a su proceso de constante
ampliación y a su gran variedad existe un catalogo de ellos. Se podra consultarlos en el Anexo I de
este trabajo.
Ahora para aplicar refactorización con TDD nos enfocaremos en los que nombra Fowler[37].

Código Duplicado (Duplicated Code): El principal ”mal olor.es el código duplicado. Si el


mismo código aparece en más de un lugar, de seguro el código quedará mejor si se encuentra la
manera de unificarlos. El código duplicado mas simple es cuando se tiene la misma expresión
en dos métodos de la misma clase. Corresponde entonces .Extraer el Método.en invocar el código
en ambos lugares. También ocurre la duplicación cuando se tiene dos subclases hermanas, se
puede usar también el método de extracción, o cuando se tiene dos algoritmos que realizan lo
mismo pero son diferentes, se puede elegir el más claro. Lo mismo podrı́amos aplicar cuando
tenemos dos clases que comparten un método que es similar, podrı́amos extraerlo de una
clase, o evaluar si realmente deberı́a ir dentro de una de ellas, la otra clase invocarlo o que
el método pertenece a una tercera clase que debe ser referido por ambas clases originales. Es
una tarea manual, de decidir donde el método tiene sentido, asegurarse que tiene que estar
donde es conveniente y ningún otro lugar. En el ciclo de TDD la refactorización se lleva paso
a paso, el control de buscar código duplicado es mas sencillo y llevadero.

Método largo (Long Method): Los programas con orientación a objetos viven mejor y
tienen mantenibilidad, estabilidad son los que tienen métodos mas cortos. Se suele decir que
en algunos objetos nunca ocurre ningún calculo, que hay infinitas secuencias de delegación,
pero cuando se ha estado con un programa por muchos años, se aprende lo valioso que es
4 “Un antipatrón es una forma literaria que describe una solución recurrente que genera consecuencias negativas
[11]

C.U. Marı́a Lorena Garcı́a TDD 52


Capı́tulo 4. Prácticas y técnicas con TDD

tener pequeños métodos. Lo beneficios de la indirección: explicación, compartir y la elección


se apoyan en pequeños métodos. Una cosa importante de los métodos pequeños es un buen
nombre, si tiene un buen nombre, casi no se necesita mirar el cuerpo. El beneficio de tener
un método corto viene asociado a que un método largo es difı́cil de entender. Hay que ser
mas agresivo con la idea de descomponer métodos, una heurı́stica que se sigue es que cuando
se siente la necesidad de comentar algo, debemos escribir un método en su lugar. La clave
aquı́ no es la longitud del método sino la distancia semántica entre lo que el método hace y
cómo lo hace[37]. El mayor tiempo en refactorización es acortar los métodos, por la técnica
de método de extracción, juntar lo que parecer ir .agradablemente junto hacer un nuevo
2

método. Si se tiene un método con muchos parámetros y variables temporales, elementos que
se interponen en la forma de extraer métodos, a veces terminas pasando tantos parámetros
y variables temporales como parámetros al método extraı́do que el resultado es escasamente
más legible que el original. Para esto se puede reemplazar las variables utilizando un objeto
que las contenga. ¿Cómo identificar porciones de código para extraer?, una técnica es buscar
comentarios, a menudo indican una porción de código que realiza una determinada función
que puede ser extraı́da, otra forma es buscar condiciones y bucles. En un bucle se puede
extraer el código dentro del bucle y ponerlo en un método nuevo.

Clase extensa (Large Class): Cuando una clase está tratando de hacer demasiado, a
menudo se ve una larga lista de instancias de variables y cuando esto ocurre seguro puede
haber código duplicado. Se puede agrupar algunas variables usando .Extracción de Clase”,
crear una nueva clase o subclase Usando extracción de método, se puede reducir un montón
el código de una clase. Si se tiene muchos métodos con un montón de código en común, se
puede convertirlos en métodos de diez lı́neas con otros métodos de dos lı́neas extraı́dos del
original. Un forma util es determinar cómo los clientes usan la clase y ası́ determinar como se
puede romper la clase.

Lista de parámetros larga (Long Parameter List): Se nos ha enseñado a pasar a una
rutina tantos parámetros como necesite, es comprensible porque la alternativa era variables
globales, y esto es malo, hasta podrı́amos decir doloroso de mantener, refactorizar, y entender.
Con los objetos podemos cambiar esta situación, porque si necesitamos algo podemos pedı́rselo
a un objeto. En los programas orientados a objetos, las listas de parámetros tienden a ser
mucho más pequeñas que en programas tradicionales. Esto es bueno porque las listas de
parámetros largos son difı́ciles de entender, porque se vuelven inconsistentes y difı́ciles de
usar, y esto es para siempre por que se necesita cambiar continuamente a medida que necesite
más datos. La mayorı́a de los cambios se eliminan pasando objetos porque es mucho más
probable que necesite hacer sólo un par de peticiones para obtener una nueva pieza de datos.

Cambio Divergente (Divergent Change): Estructuramos nuestro software para facilitar


el cambio; después de todo, el software está destinado a ser mantenible, mejorable. Cuando
hacemos un cambio, queremos ser capaces de saltar a una punto en el sistema y realizar el

C.U. Marı́a Lorena Garcı́a TDD 53


Capı́tulo 4. Prácticas y técnicas con TDD

cambio. Cuando no se puede hacer esto es porque algo está .oliendo mal”. El cambio diver-
gente ocurre cuando una clase es comúnmente cambiada de diferentes maneras por diferentes
razones. Si se observa una clase y ocurre que en ella se tendrá que cambiar algunos métodos
cada vez que se modifique algo en la base de datos, y otros métodos cada vez que cambie una
lógica de negocio, es probable que tengamos una situación en la que dos objetos son mejores
que uno. De esta manera cada objeto se cambia sólo como resultado de un tipo de cambio.
Por supuesto, esto se descubre por haber agregado varias veces cambios en la base de datos o
instrumentos de lógica de negocio. Cualquier cambio deberı́a preveer un cambio en una sola
clase y toda una nueva clase expresar la variación. Para refactorizar esto,se debe identificar
todo lo que cambia por una causa en particular y usar Extract Class para juntarlos.

Cura de un escopetazo (Shotgun Surgery): También traducido al castellano como ci-


rugı́a de escopeta es similar a un cambio divergente, pero en el sentido contrario. Ocurre cada
vez que se necesita hacer un tipo de cambio, se tiene que hacer muchos pequeños cambios a
muchas clases diferentes, y cuando los cambios son difı́ciles de encontrar, y es fácil perderse en
él. En este caso hay que utilizar el método de ”mover un método ”mover un campo”para po-
2

ner todos los cambios en una sola clase. Si ninguna clase actual parece ser un buen candidato,
se crea una. A menudo se puede usar el método Ïnline Class”, que es clase que proporciona
una base que contiene un montón de comportamientos juntos. De este modo se realiza un
poco de cambio divergente, pero se puede manejar más fácilmente cuando es una clase la
que sufre muchos tipos de cambios, y la cirugı́a de escopeta es un cambio que altera muchas
clases. Un ”mal olorçlásico es un método que parece estar más cómodo o interesado en una
clase distinta de la que realmente está.

Caracterı́stica envidiada (Feature Envy): Otro enfoque es cuando un método sufre


.envidia”porque invoca media docena de métodos alojados en otro objeto. La cura a esto,
es obvia, claramente hay que mover el método porque quiere ser otro. A veces solo parte de
el método sufre de envidia; en ese caso se utiliza el método Extrac Method y se lo mueve al
hogar donde quiere estar. A menudo un método utiliza caracterı́sticas de varias clases, por
lo que uno se pregunta en que clase deberı́a estar. La heurı́stica que utilizamos es determi-
nar qué clase tiene la mayor parte de los datos y poner el método con esos datos. La regla
fundamental es poner las cosas juntas que cambian juntas.

Agrupaciones de datos (Data Clumps): Los datos tienden a ser como los niños; disfrutan
colgando alrededor en grupos juntos. A menudo,se ve los mismos tres o cuatro datos juntos
en un montón de lugares: campos en un par de clases, parámetros en muchas firmas de
métodos. Los grupos de datos que cuelgan juntos deberı́an ser un objeto. Utilizar extraer
clase en los campos para convertir los agregados en un objeto. Luego introducir el objeto
como parámetro. El beneficio inmediato es que se reduce muchas listas de parámetros y se
simplifica las llamadas a métodos. Una buena prueba es considerar la eliminación de uno de

C.U. Marı́a Lorena Garcı́a TDD 54


Capı́tulo 4. Prácticas y técnicas con TDD

los valores de los datos. Evaluar si los demas tendrian sentido, si no lo tienen es una señal
segura de que hay un objeto decidido a nacer.

Obsesión primitiva (Primitive Obsession): Muchos lenguajes de programación tienen lo


que se conoce como tipos de datos primitivos. Es muy común no utilizar pequeños objetos para
representar pequeñas funcionalidades, como puede ser definir una clase ’Money’que combine
una cantidad y una moneda, y en lugar de esto utilizan tipos de datos primitivos. El problema
de esto es que después aparecen en diferentes lugares, se utilizan en estos valores ciertos
chequeos que se repiten y que podrı́an ser encapsulados en un pequeño objeto.

Sentencias switch (Switch Statemetns): Una de las consecuencias más obvias del código
orientado a objetos es la falta de comparaciones switch (o caso). El problema con las sentencias
switch es esencialmente de la duplicación. A menudo se encuentra la misma instrucción switch
en diferentes lugares. Si se agrega una nuevo caso se tiene que encontrar en todas las partes
donde aparece el mismo switch y cambiarlo. La programación orientada a objetos tiene una
solución elegante a esto, usando polimorfismo.

Jerarquı́as de herencia paralelas (Parallel Inheritance Hierarchies): Es un caso


especial de cirugı́a de escopeta. En este caso, cada vez que se hace una subclase de una
clase, también se tiene que hacer una subclase de otra. La estrategia general para eliminar la
duplicación es asegurarse de que las instancias de una jerarquı́a se refieren a instancias de la
otra.

Clase perezosa (Lazy Class): Cada clase que se crea cuesta dinero, mantenimiento y
entendimiento. Una clase que no está haciendo lo suficiente para pagar esto por sı́ misma,
entonces debe ser eliminada. A veces la clase tenı́a un sentido en un principio, pero luego de
algunas refactorizaciones perdió responsabilidad y sentido. Lo que se puede hacer es colocar
esa responsabilidad en otra clase. En este caso se utiliza un Inline Class y se lleva esto a esa
última clase, eliminando definitivamente a la clase perezosa.

Especulación generalizada (Speculative Generality): Este ”mal olor.aparece cuando


los programadores se plantean funcionalidades a futuro, cuando dicen çreo que necesitaremos
esto algún dı́a por lo tanto quieren contemplar todos los casos especiales para manejar cosas
2

que no fueron requeridas. El resultado de esto, es un código difı́cil de entender y por lo tanto
de mantener. La complicación viene cuando aparece un nuevo requerimiento y este debe
incorporase a toda esa funcionalidad .agregada”, que contempla cosas no pedidas. Claro que
siempre está la opción de refactorizar, pero el criterio serı́a no hacer cosas de mas, y esperar
a que los requerimientos nuevos lleguen.

Campo Temporal: Existen variables de instancia que parecen usarse sólo en algunos casos,
esto se vuelve confuso de entender en cuáles. Es mejor usar el extraer método y poner estas
variables en otra clase para crear un hogar para las variables huérfanas. Poner todo el código

C.U. Marı́a Lorena Garcı́a TDD 55


Capı́tulo 4. Prácticas y técnicas con TDD

que se refiere a las variables en el componente. Un caso común de campo temporal se produce
cuando un algoritmo complicado necesita varias variables. Porque el ejecutor no quiere pasar
alrededor de un enorme lista de parámetros.

Cadenas de mensajes (Message Chains): Estas cadenas aparecen cuando un cliente pide
un objeto a otro objeto y a su vez llama a éste último para obtener otro objeto. De esta
manera, el cliente se acopla a toda esta estructura de navegación y cualquier cambio en ella le
afectará. Es mejor crear un objeto delegado que encapsule la navegación y abstraiga al cliente
de ella.

”Hombre en el medio”(Middle Man): Tiene que ver con el caso anterior, no es necesario
que se cumpla estrictamente. A veces, si existen muchos métodos que delegan a una misma
clase, es mejor quitarnos el delegado y referirnos a ella directamente.

Intimidad inapropiada (Inappropiate Intimacy): Cuando una clase se dedica a hurgar


en partes de otra clase que parecen ser privadas, ha llegado el momento de desacoplar dichas
clases, por ejemplo, a través de una tercera que contenga la funcionalidad común de las dos
anteriores. La herencia a menudo puede conducir a un exceso de intimidad. Las subclases
siempre van a saber más acerca de sus padres de lo que sus padres quisieran que supieran.

Clases alternativas con interfaces diferentes (Alternative Classes with Different


Interfaces): Cuando tenemos dos métodos que hacen los mismo pero se llaman de forma
distinta, es mejor unificarlos para que se use siempre un único método.

Clase de librerı́a incompleta (Incomplete Library Class): A veces una clase no realiza
todo lo que necesitamos y debemos adaptar su uso a lo que se requiere, ya que no podemos
modificarla.

Clase de datos (Data Class): Las clases que solo tienen datos getters y setters son mani-
puladas en gran medida por otras clases. Podemos buscar este comportamiento para llevarlo
a las clases que contienen los datos.

Legado rechazado (Refused Bequest): A veces una subclase no usa todos los métodos que
hereda de su clase padre. Esto puede significar que la jerarquı́a no es correcta y los métodos
de las clases se deben mover a donde se usan realmente.

Comentarios (Comments): Los comentarios suelen marca el área en el código que se puede
usar el método de Extract Method. Es mejor invertir el tiempo en mejorar este código que en
comentarlo.

4.1.3. Herramientas de Refactorización


Visual studio (Microsoft)

C.U. Marı́a Lorena Garcı́a TDD 56


Capı́tulo 4. Prácticas y técnicas con TDD

JustCode (Telerik)

ReSharper (JetBrains)

CodeRush (DevExpress)

Visual Assist X (Whole Tomato)

4.2. Integración Continua


La automatización de actividades es básica para mejorar la producción, la calidad y garantizar
el correcto cumplimiento de reglas. Lo ideal es reducir el tiempo de desarrollo del software y esto
se puede lograr automatizando las actividades.
Han surgido nuevas prácticas a lo largo de los últimos años, además de herramientas que tienden
a satisfacer esta necesidad de mejora continua del proceso de desarrollo de software.
La Integración Continua o CI (Continuous Integration) el tema que vamos a hablar ahora, ocupa
un lugar cada vez más importante en la construcción del software.
CI es una práctica que debe conllevar que los proyectos posean una estructura de directorios
adecuada para establecer ordenes de ejecución, de prueba y además de facilitar el mantenimiento e
incorporación de nuevas funcionalidades.
Para poder dar soporte a TDD, un enfoque donde las pruebas son primordiales se necesita tener
una mı́nima infraestructura que permita automatizar la ejecución del elevado número de pruebas
que se diseñan y la toma de medidas que permitan conocer el nivel de calidad que está alcanzando
el desarrollo.
La ejecución correcta, seguir el hilo de ejecución y prueba del software facilita que el proceso de
construcción de software logre transparencia para el equipo de desarrollo.
Los programadores pueden entender incluso la lógica de negocio de partes del software que no
haya codificado. El programador se involucra en el desarrollo del ”todo no solo de las funciona-
2

lidades que esta incorporando. Por supuesto también tendrá el feedback necesario cuando una de
sus funcionalidades pueda ocasionar errores en resto del sistema.
Ahora si vamos a un enfoque más técnico, ¿qué es Integración Continua?. Dijimos que era una
práctica de desarrollo, en ella los miembros del grupo de desarrollo integran (compilan y ejecutan)
los componentes de un proyecto con una frecuencia especificada.
Cada programador en su estación de trabajo ”baja.el código fuente del proyecto, integra a este
el código de su autorı́a y luego compila. Luego debe correr los tests en su máquina a fin de detectar
errores de integración lo antes posible, serı́a la primera integración que se realiza, en la maquina
del programador.
Esto reduce significativamente los problemas de integración al detectar errores en la maquina
local del programador, permite tener un software cohesivo más rápido.
Un escenario tı́pico de CI[3][21]se compone de la siguiente manera:

C.U. Marı́a Lorena Garcı́a TDD 57


Capı́tulo 4. Prácticas y técnicas con TDD

Primero, un desarrollador realiza un çommit”de su trabajo al repositorio de control de versión


a la vez que el servidor de CI verifica cambios en el repositorio, por ejemplo cada 5 minutos.

El servidor de CI detecta los cambios en el repositorio de control de versión, extrayendo el


último commit que se ha realizado y ejecutando una build script que se encarga de integrar
los distintos componentes del software en desarrollo.

El servidor de CI genera feedback con los resultados del proceso de building, el cual es enviado
a los miembros que se especifique del proyecto.

El servidor de CI revisando cambios en el repositorio de control de versiones.

4.2.1. Mejora de la calidad en el desarrollo del software


¿Qué nos ofrece aplicar CI en nuestro desarrollo?. Como dijimos anteriormente conlleva a una
mejora de la calidad del software.

Calidad de proceso

Otorga visibilidad al proceso de desarrollo, por el hecho de que todos los pasos que se siguen
para implementarlo se siguen desde que se empieza a programar un requerimiento hasta que el
software está en producción.
Todos los miembros del equipo saben que fases pasa el código, y el estado de desarrollo en cada
momento. Podemos saber si compila, si pasa las pruebas, que versión incorporó ciertas funcionali-
dades, el origen de un error (si se da a partir de cierta incorporación de código), que versión paso
las pruebas completas, etc.
También se puede ver que necesidades se tienen en la gestión de configuración, que polı́ticas de
control habrı́a que implementar, necesidades de instalación de componentes particulares incorpo-
rados a cada versión, entre otras cosas más.
Si el equipo no conocı́a los pasos para la configuración del software que deben estar definidas,
con la CI todos deben saberlo. Es importante destacar que en una fase de integración también
estamos realizando una prueba de sistema, de compatibilidad.

Software con más calidad

Por otro lado, también se mejora la calidad del producto software[20]. El principal objetivo de
la CI es detectar los errores lo más pronto posible, en fases tempranas del desarrollo, para poder
solucionarlos rápidamente.
Con la introducción de pruebas y comprobaciones de compatibilidad, de recursos, los riesgos
se van minimizando, el software resultante tiene menos errores y una mayor confiabilidad. Todo
esto lo conseguimos con la CI. Pero si en fases mas avanzadas de CI se incorporan herramientas
que sirvan para inspecciones continuas de código, análisis periódicos para detectar problemas de

C.U. Marı́a Lorena Garcı́a TDD 58


Capı́tulo 4. Prácticas y técnicas con TDD

calidad en él; incluso se puede impedir que desarrolladores suban el código al control de versiones
si no cumplen los estándares de calidad definidos por la empresa.

Mejores programadores

El equipo se mejora, se hace mas eficiente, esta mejor preparado, ya que la contribución continua
del código facilita el aprendizaje continuo, el conocimiento de la lógica de negocio y la capacitación,
el equipo acaba aprendiendo a hacer distintos tipos de pruebas (unitarias, de integración),se dan
mejores prácticas de programación y en general se desarrolla código de mayor calidad.
Los desarrolladores obtienen mas confianza en su código al realizar distintas comprobaciones y
al saber que el resto del equipo también pudo ver y revisar su código, por ende el equipo tiene mas
confianza. Serán capaces de afrontar nuevos retos, mejoras, cambios y estarán más motivados.
Sin hablamos de tiempo, seguro estarı́amos de acuerdo que los tiempos en un desarrollo de
software con CI es mucho mas productivo y menor, a un desarrollo sin ella. Los procesos repetitivos
son automatizados, dejando más tiempo para hacer otras cosas.

4.2.2. Buenas Practicas


La CI tiene una serie de pasos en los cuales se apoya para realizar todo este proceso automatizado
los cuales son:

1. Repositorio de código: La herramienta que permite que el equipo trabaje de forma total-
mente sincronizada, pero a la vez sencilla. Cada uno trabaja en su parte y puede actualizar los
cambios sin necesidad de que otros desarrolladores tengan que esperar por estos y viceversa.

2. Sistema de construcción automatizado: Se define un conjunto de etapas (pipeline5 )por


las que va pasando el software que se automatizarán. Un ejemplo de una etapa serı́a que el
código sea obtenido del repositorio, se compile.Se cree la base de datos, los datos necesarios
para la ejecución de las pruebas y si esta todo bien, se realiza una serie de pruebas unitarias
(generalmente las que se incorporan junto al código), luego otra etapa podrı́a ser desplegar el
código a otro entorno y disparar las mismas pruebas.

3. Commits diarios: No todos los requisitos se basan en tener un determinado tipo de he-
rramienta, algunos se basan en saber cómo utilizar una determinada herramienta. Una vez
que tenemos un control de versiones hay que recordar que el almacenamiento de los cambios
debe ser diario, idealmente un desarrollador debe hacer incluso varias subidas al repositorio
de código al dı́a.
Si tenemos un repositorio de código, pero cada desarrollador sube sus cambios cada dos
semanas seguimos en el mismo problema de antes, la integración del proyecto se retrasa
durante todo ese tiempo, perdiendo toda opción de obtener información inmediatamente.
5 Segmentación

C.U. Marı́a Lorena Garcı́a TDD 59


Capı́tulo 4. Prácticas y técnicas con TDD

Además, retrasar la integración tanto tiempo genera más conflictos entre los ficheros editados
por los desarrolladores. Debido a que con cada actualización del repositorio se hace una
integración del proyecto completo, cada mı́nimo cambio que no desestabilice el proyecto debe
ser subido para que se compruebe que todo sigue funcionando correctamente.

4. Pruebas unitarias: Hemos hablado todo el tiempo de comprobar que el proyecto funciona
correctamente y al mismo tiempo de automatizar todo el proceso lo mejor posible. Para
poder comprobar que el proyecto funciona de forma automática necesitamos pruebas unitarias
(muchas veces incluso pruebas de integración).
Existen muchas maneras diferentes de incluir tests en el proyecto, personalmente creo que
TDD es la manera más adecuada, pero si el equipo no tiene experiencia y crea las pruebas
después de haber realizado la implementación tampoco es un método inválido. La premisa
fundamental es que toda nueva funcionalidad debe tener una baterı́a de pruebas que verifique
que su comportamiento es correcto.

5. Servidor de integración: Esta es la pieza más polémica, mucha gente cree que no es ab-
solutamente necesaria para hacer CI correctamente, por ejemplo, algunos equipos hacen la
integración de forma manual con cada subida al repositorio de código. En mi opinión es un
paso tan sencillo y barato de automatizar que no merece la pena ahorrárselo. Montar algún
servidor de integración, como por ejemplo Jenkins o Cruise Control, es gratuito y tan senci-
llo como desplegar un fichero en un servidor. Por contra las ventajas son grandı́simas. Para
empezar el proceso está totalmente automatizado, lo que evita el error humano. Y por otro
lado reduce la cantidad de trabajo, ya que tenemos una solución prefabricada sin necesidad
de tener que crear nosotros mismos complejas soluciones caseras.

4.2.3. Beneficios
La lista de beneficios identificados según diversos autores de usar CI son los siguientes:

Reducción del riesgo: Nos referimos al riesgo intrı́nseco que todo proyecto tiene por su
carácter de temporal y único. Esto da origen a la necesidad de una gestión de riesgo como
algo fundamental en la gestión de proyectos [44]. En el desarrollo de software todavı́a no se
tiene la visión global de un proyecto debido a que los requerimientos pueden ir cambiando,
por lo que no se tienen en cuenta los riesgos que hay que asumir. Los riesgos que se puedan
asumir al integrar diferentes componentes no son analizados. La integración de componentes
se hacen durante las últimas etapas en el desarrollo. Muchos proyectos de desarrollo fracasan
debido a tiempos lejos de los estimados en la entrega, lo que suma costos no previstos. La
CI permite reducir el riesgo en la integración de componentes por que los problemas son
detectados antes.

Eliminación de errores: Eliminar defectos, detectarlos con anticipación es mucha más fácil

C.U. Marı́a Lorena Garcı́a TDD 60


Capı́tulo 4. Prácticas y técnicas con TDD

con CI. El hacer pruebas en periodos cortos de tiempo aumenta garantı́as de que los fallos
serán mucho menos o que los mismos aparecerán tempranamente.
Andres Hunt con David Thomas ambos firmantes del manifiesto ágil dicen en el libro ”Prag-
matic Programming”que Üno de los beneficios de detectar problemas lo antes posible es que
un puede estrellarse antes. Y muchas veces, estrellar su programa es el mejor cosa que puedes
hacer.”, .Es mucho más fácil encontrar y diagnosticar el problema al estrellarse temprano”.

Mejores relaciones con los clientes: Normalmente se escribe software para personas, a
menudo uno se acuerda de obtener los requisitos de ellos. Realizar pequeñas entregas ayuda
a eliminar barreras entre los clientes y los desarrolladores, las caracterı́sticas del software son
rápidamente visibles, creando un ambiente colaborativo.

Mejora en la calidad del trabajo: El uso de CI, supone un aumento en la comunicación


entre desarrolladores debido a que los mismos tienen la llegada al código producido por
el equipo, pueden manejar mejor la compresión del código, la información y transferir el
conocimiento. El desarrollo de algoritmos es mejor y más rápido, hay un aumento de la moral
que por ende genera programadores con más confianza[40].

Estimaciones más acertadas: Cada integración es verificada con una secuencia de tareas de
construcción automática la cual es acompañada de pruebas para detectar errores tan rápido
como sea posible. Además, se generan informes para mostrar el resultado de cada integración.
Al tener una dea mas real del estado del proyecto desarrollado se puede estimar cuanto tiempo
falta para acabar con las funcionalidades requeridas, esto se puede lograr con mayor certeza.
La CI evita la aparición del llamado Big Bang que se origina cuando se realiza una unica
integracion al final del desarrollo[45].

Última versión (HEAD): En CI se puede obtener las distintas versiones de un prorgama,


hay sistemas que identifican las revisiones con un contador (Ej. Subversion). Hay otros sis-
temas que identifican las revisiones mediante un código de detección de modificaciones (Ej.
Git usa SHA1). A la última versión se le suele identificar de forma especial con el nombre
de HEAD. También existe una versión a la que se llama ”baseline”(lı́nea base) que es una
revisión aprobada de un documento o fichero fuente, a partir del cual se pueden realizar cam-
bios subsiguientes. Con las distintas versiones, o con la última resulta mucho más fácil hacer
pruebas, demostraciones, liberación de versiones, etc.

Reducción de costos: Al detectar algunos de los errores lo antes posible gracias al uso de
CI trae el beneficio de una reducción de costos ya que este aumenta exponencialmente en
cada fase en la que aún no se haya descubierto dicho fallo según Barry Boehm, 20026 En
otras publicaciones se han confirmado las teorı́as de Boehm, se explica que reparar un defecto
6 Barry W. Boehm (n. 1935) es un ingeniero informático estadounidense y también es profesor emérito de esta

materia en el departamento de ciencias tecnológicas en la Universidad del Sur de California. Es conocido por sus
múltiples aportes a este campo.

C.U. Marı́a Lorena Garcı́a TDD 61


Capı́tulo 4. Prácticas y técnicas con TDD

durante la etapa de desarrollo de un módulo podrı́a tener un coste aproximado de un dólar.


Por lo tanto, reparar costarı́a más de cien dólares cuando ya se ha integrado todo el código y
miles de dólares si el defecto se detecta cuando el software ya se ha distribuido.

4.2.4. Inconvenientes
Desmejoramiento de la arquitectura:Los desarrolladores se centran más en la resolución
de las cosas en el corto plazo, debido a esto la arquitectura sufre una degeneración.

Posible sobrecarga del sistema: Se hacen continuamente integraciones del código, esto
puede hacer que el sistema este sobrecargado en ciertos momentos, no suele ser un problema
muy importante.

Requerimientos de Servidores:Se puede necesitar de acuerdo al despliegue que se desea


hacer varios servidores, suelen usarse el servidor de desarrollo que es al que acceden los
desarrolladores en la fase de codificación, un servidor para el despliegue de pruebas y un
servidor para producción.

Miedo a subir código erróneo: Los desarrolladores generalmente suelen resentirse a subir
su código al repositorio ya que debe coexistir con él todo, surgen dudas y miedos de causar
problemas con el código de los demás. Pese a todo, siempre será más problemático subir el
código completo en una única iteración que hacerlo progresivamente con la práctica de la CI.

Problemas en la utilización de repositorios: Existen problemas al hacer las operaciones,


por ejemplo un çommit”que es cuando una copia de los cambios hechos a una copia local
es escrita o integrada sobre el repositorio y esta copia contiene errores que producen una
falla en la construcción final. Este problema se evita concienciando a los desarrolladores de la
necesidad de realizar pruebas.

4.3. Herramientas para Integración continua


En este modelo informático propuesto CI iniciado por Martin Fowler, como se dijo anterior-
mente consiste en hacer integraciones automáticas de un proyecto lo más a menudo posible para
ası́ poder detectar fallos cuanto antes. Y recalcamos que entendemos por integración la compilación
y ejecución de pruebas de todo un proyecto.
Este despliegue suele ser cada cierto tiempo (horas), se descargan las fuentes desde un servidor
de versiones por ejemplo CVS, Git, Subversion, Mercurial o Microsoft Visual SourceSafe entre otros
y es compilado, luego se ejecutan pruebas y hasta se pueden generar informes.
Para esto se utilizan algunas herramientas como Solano CI, Bamboo, Continuum, Hudson,
Jenkins, CruiseControl, Anthill, etc. según el tipo de proyectos que se encargan de controlar las
ejecuciones, apoyadas en otras herramientas como Ant, Maven, Nant, MSBUILD, que también

C.U. Marı́a Lorena Garcı́a TDD 62


Capı́tulo 4. Prácticas y técnicas con TDD

depende del tipo lenguaje utilizado que se encargan de realizar las compilaciones, ejecutar las
pruebas y realizar los informes.
Para cada tipo de tarea o proceso existen herramientas, a continuación se detallarán algunas de
ella segun las funciones que cumplen dentro del proceso de CI.

4.3.1. Gestión de requisitos


Entre las muchas opciones de Herramientas que apoyan el desarrollo de un proyecto de software
están las que acompañan la Gestión de Requisitos. El uso de estas herramientas permite mejorar
la calidad del desarrollo. En cuanto a calidad en estos momentos nos referimos a que el software
hará lo que se pidió en los requerimientos.
La Gestión de Requisitos es un componente vital en el desarrollo de un proyecto software, provee
la dirección y alcance del proyecto. El uso de herramientas para auxiliar la gestión de requisitos se
ha convertido en un aspecto importante de la Ingenierı́a de sistemas y el diseño. Considerando el
tamaño y la complejidad del desarrollo, el uso de herramientas viene siendo algo esencial.
Estas herramientas nos permiten tener el seguimiento de hitos, tareas, incidencias, repositorios,
calendarios y mucho más. Dependen de cada plataforma y de las funciones que proveen.
Para seleccionar una herramienta hay que evaluar las necesidades de nuestro proyecto, el tamaño
del equipo de desarrollo, la metodologı́a utilizada y también el cliente final. Si se necesita mostrar
los avances del proyecto deberemos decidir cual es la mejor herramienta.
Las herramientas que los gestores de requisitos son herramientas CASE (Computer- Arded
Software Enginnering) que facilitan el trabajo de especificación, organización, almacenamiento y
gestión de requisitos. A través de la trazabilidad en el desarrollo y el uso de estas herramientas se
puede evaluar el posible impacto de los cambios en los requisitos, en los procedimientos, costes y
personal.
En este trabajo se desarrollarán algunas de las herramientas más conocidas en el desarrollo ágil
de software. Se analizará que nos pueden aportar cada una para la gestión de proyectos, en nuestro
caso sobre el desarrollo de un proyecto de software. Muchas de las herramientas que mencionaremos
pueden ser utilizadas para otro tipo de proyectos, donde también se definen hitos y objetivos que
cumplir. Una de las herramientas utilizadas es el diagrama de Gantt que incorpora por ejemplo
Redmine.
Las utilidades en las cuales nos enfocaremos para evaluar las herramientas y su funcionamiento
son la de usabilidad, manejo de tareas,seguimientos, alertas, calendarios o diagrama de Gantt.

Gestión de usuarios: Facilidad de manejar usuarios,funciones como añadir, eliminar y ad-


ministrar.

Gestión de tareas : Facilidad de administración de tareas, funciones como añadir, modificar,


eliminar y discutir acerca de las tareas y los problemas. La posibilidad de enviar correo
electrónico, que la visualización de la administración sea comprensible.

C.U. Marı́a Lorena Garcı́a TDD 63


Capı́tulo 4. Prácticas y técnicas con TDD

Utilidades de seguimiento: Seguimiento con diagrama de Gantt, calendario para visualizar


el progreso de cada tarea y hacer control.Exponer el tiempo de dedicación previsto para
diferentes tareas o actividades a lo largo de un tiempo total determinado.

Documentación: Si posee utilidades para la documentación,

Búsquedas: Posibilidad de hacer búsquedas de distintos tipos y filtros según criterios como
usuarios.

Las herramientas investigadas son:

Readmine

Redmine es una aplicación Web flexible de Gestión de Proyectos. Se escribio usando Ruby on
Rails, es multiplataforma y cross-database[29]. Tiene licencia GNU (General Public License v2
(GPL), de código abierto.
Caracterı́sticas:

Soporta múltiples proyectos

Control de acceso basado en roles flexible.

Seguimiento de problemas flexible.

Gráfico Gantt y calendario.

Gestión de noticias, documentos y archivos

Feeds y notificaciones por correo electrónico

Página Wiki por proyecto.

Foros de proyectos

Tomando Quenta de tiempo

Campos personalizados para problemas, entradas de tiempo, proyectos y usuarios

Integración SCM (SVN, CVS, Git, Mercurial y Bazaar)

Creación de emisión por correo electrónico

Soporte de autenticación LDAP múltiple

Soporte de auto-registro del usuario

Soporte multilingüe

Soporte de múltiples bases de datos

C.U. Marı́a Lorena Garcı́a TDD 64


Capı́tulo 4. Prácticas y técnicas con TDD

Como primera visualización del funcionamiento de RedMine se consultó la página de web


www.redmine.org, sitio oficial de la aplicación en la cual hay a disposición luego de una registración
gratuita una versión Demo de la aplicación.
Una vez registrada una cuenta sencilla de prueba, ingresamos a la aplicación automaticamente.

Figura 4.1: RedMine - Nuevo Proyecto - Captura versión Demo

En la captura podemos ver que los módulos disponibles para un proyecto son ”Peticiones”,
que se refiere a errores reportados, nuevas caracterı́sticas o cambios solicitadas en un proyecto, el
manejo de Documentos, Foros, Control de tiempo, Archivos, visualización de Calendario, Noticias,
Wiki y el diagrama de Gantt.
La aplicación cuenta con un Dashboard o Vistazo, donde podemos visualizar las peticiones
realizadas, la lista de miembros del proyecto, y el tiempo dedicado al mismo. Las peticiones son
ordenadas por su tipo : Bugs, Caracterı́sticas, Support.
También cuenta con la opción de menú para ver el diagrama de Gantt según las peticiones
ingresadas, un resumen de las listas de Actividades ( conjunto de peticiones).
Los estados de cada petición son Nuevo (New), Resuelto (Resolved), En Progreso (In Progress),
retroalimentación (FeddBack), Cerrado (Close), Rechazado (Reject).
La herramienta Redmine es intuitiva, reúne las necesidades básicas para la gestión de tareas y
el seguimiento de proyectos. Cuenta con la opción de incorporar plugins que aumentan las funcio-
nalidades. También podemos mejorar su visualización con temas.
Easy Redmine es una versión mejorada de Redmine, es un plugin gigante y siempre es compatible
con la última versión de Redmine.

C.U. Marı́a Lorena Garcı́a TDD 65


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.2: RedMine - Vistazo - Captura versión Demo

Figura 4.3: RedMine - Modificación de Petición - Captura versión Demo

C.U. Marı́a Lorena Garcı́a TDD 66


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.4: RedMine - Diagrama de Gantt - Captura versión Demo

La siguiente lista muestra algunas de las caracterı́sticas que incorpora Easy Redmine[22]

Plantillas de proyecto (ahorro de tiempo)

Organizador rápido de proyecto (ahorro de tiempo)

Recordatorios rápidos de tareas pendientes

Estadı́sticas de proyecto

Gráficos y tablas de proyecto (información

Administración de clientes (recursos y asistencia)

Administración de clientes (CRM, escritorio de ayuda, facturación, contactos)

Administración de finanzas (presupuestos, circulación de dinero, cálculos, historial de pagos,


facturación, finanzas personales)

Con Easy Redmine, Redmine se convierte en herramienta poderosa y amigable. Podemos decir
entonces que Redmine cumple con todas las caracterı́sticas que se eligieron para analizar.

C.U. Marı́a Lorena Garcı́a TDD 67


Capı́tulo 4. Prácticas y técnicas con TDD

BaseCamp

Basecamp es una aplicación que está muy bien considerada y valorada como organizador, gestor
de tareas para equipos de personas que trabajan de manera colaborativa. Desde su aparición en
2004, esta herramienta de gestión de proyectos online, cuenta con 5 millones de usuarios. Fue
desarrollado por 37 Signals, una pequeña empresa americana con sede en Chicago que predica la
simplificación de las herramientas de productividad y de los métodos de trabajo.
Es una aplicación comercial, que ofrece herramientas básicas de gestión de proyecto (lista de
tareas, compartir archivos, etc.) se basa en una receta simple: la utilidad óptima más que la multi-
plicación de funcionalidades que no siempre son explotadas y la circulación de la información fluida
entre colaboradores, gerentes y clientes[6].
En la misma página oficial de BaseCamp se puede realizar la registración en forma gratuita por
un periodo de 30 dı́as.
En BaseCamp se puede administrar proyectos, equipos de desarrollos, lista de clientes y podcast7
y clientes. Una vez que se ingresa a la aplicación se puede gestionar un calendario personal, la
actividad reciente, cuales tareas se nos fue asignada y otras opciones mas.

Figura 4.5: BaseCamp - Inicio - Captura versión trial

Basecamp es una herramienta que cuenta con la funciones básicas y hasta algunas más avanzadas
para la gestión de proyectos. Su principal diferencia con RedMine es que tiene una sección de
7 El podcasting o podcast consiste en la distribución de archivos multimedia (normalmente audio o vı́deo que

suelen ser de corta duración, que pueden incluir texto como subtı́tulos y notas) mediante un sistema de redifusión
(RSS) que permite opcionalmente suscribirse y usar un programa que lo descarga para que el usuario lo escuche

C.U. Marı́a Lorena Garcı́a TDD 68


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.6: BaseCamp - Proyecto Opciones - Captura versión trial

Figura 4.7: BaseCamp - Lista de Actividades - Captura versión trial

C.U. Marı́a Lorena Garcı́a TDD 69


Capı́tulo 4. Prácticas y técnicas con TDD

Clientes, aunque Easy RedMine incorpora funcionalidades para el manejo de Clientes.


En el análisis de caracterı́sticas, encontramos que BaseCamp en una herramienta de Gestión de
Requisitos que cumple con todas ellas,sin embargo no se aprecia del todo intuitiva y con la virtud
de poder apreciar todas las funcionalidades en pantalla.

GitLab

GitLab es un proyecto de software libre de la compañı́a del mismo nombre que está programado
en Ruby, es una suite completa que permite gestionar, administrar, crear y conectar repositorios
de código con diferentes aplicaciones y hacer todo tipo de integraciones con ellas. Incluye módulos
para revisar ficheros con facilidad, revisar diffs entre los mismos de una manera muy visual de todos
los commits, y ver dónde se producen los cambios.
Incluye un completo sistema de integración continua que cubre todas las fases, desde el test
hasta el despliegue y que además es compatible con Docker8 , tanto como para correr todos los tests
en el ambiente que nosotros queramos como para crear máquinas Docker dentro del registro de
contenedores que provee GitLab.
GitLab es una herramienta online orientada a la administración de nuestro código, depende
mucho el alcance de lo que denominamos gestión de requisitos, si incluimos principalmente código,
hitos y seguimiento de problemas, Gitlab puede satisfacer la necesidad. Es posible completar Gitlab
con herramientas de terceros que se integran con su API como Taiga9 , con esta nueva herramienta
GitLab se convierte en una aplicación de gestión de requisitos más completa al incorporarse otros
módulos como backlogs, wiki, videoconferencia, actualización de equipo y gracias a su potente API
permite la integración con servicios de terceros como Slack, GitHub, GitLab, Bitbucket, HipChat,
Gogs, Hall entre otros.
Como se puede ver en la captura GitLab es una herramienta para gestionar las versiones de
código alojadas en distintos tipos de servidores de control de versiones. Con las opciones de gestión
de equipos avanzada.
Taiga en cambio incorpora muchas funcionalidades que hacen a GitLab-Taiga una completa
herramienta para la gestión de proyectos de desarrollo de software. Taiga posee las funcionalidades
básicas de las metodologı́as Scrum y Kanban, incorpora la filosofı́a de ambas.
Una vez que nos registramos gratuitamente en Taiga sitio web tree.taiga.io, elegimos que me-
todologı́a utilizar. A modo de ejemplo se eligió SCRUM. Al igual que Redmine permite gestionar
estados en las Historias de Usuarios creadas en el proyecto.
El conjunto GitLab+Taiga[52] proveerı́a de revisiones de código y una completa herramienta
para gestión de proyectos en metodologı́as SCRUM y Kanban. Con la opciones de control de flujo
8 Docker es un proyecto de código abierto que automatiza el despliegue de aplicaciones dentro de contenedores de
software, proporcionando una capa adicional de abstracción y automatización de Virtualización a nivel de sistema
operativo en Linux.
9 Taiga es una herramienta de software libre y código abierto, creada para gestionar y colaborar en proyectos

ágiles, principalmente aquellos que utilizan metogologı́a Scrum y Kanban, además permite gestionar issues.

C.U. Marı́a Lorena Garcı́a TDD 70


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.8: GitLab - Inicio - Captura versión online

Figura 4.9: GitLab - Inicio - Captura versión online

C.U. Marı́a Lorena Garcı́a TDD 71


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.10: Taiga - Inicio - Captura aplicación online

Figura 4.11: Taiga - Scrum - Captura aplicación online

C.U. Marı́a Lorena Garcı́a TDD 72


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.12: Taiga - Nueva Historia de Usuario - Captura aplicación online

Figura 4.13: Taiga - BackLog - Estados - Captura aplicación online

C.U. Marı́a Lorena Garcı́a TDD 73


Capı́tulo 4. Prácticas y técnicas con TDD

de trabajo fuerte o complejo en torno al desarrollo incluyendo el equipo de validaciones, informes


y flujo de trabajo de grano fino que sirve para involucrar clientes en la gestión de proyectos.
Como resultado de la revisión a grandes rasgos de GitLab, encontramos que sin la incorporación
de la herramienta Taiga serı́a una aplicación para la gestión de código no ası́ para la gestión de
requisitos, por no contar con varias de las caracterı́sticas básicas que se busca, pero junto a Taiga se
convierte en un paquete casi completo y fácil de utilizar en los proyectos de desarrollo de software.

Collabtive

Collabtive es un software de gestión de proyectos basado en la Web, publicado como software


libre . Proporciona una alternativa de código abierto a herramientas propietarias como Basecamp
, Asana y Trello .
Collabtive permite a los equipos trabajar en estrecha colaboración. La herramienta represen-
ta proyectos por tareas, hitos, archivos relacionados y mensajes. El tiempo trabajado puede ser
rastreado en una base de tarea por tarea.
El lenguaje de programación principal de Collabtive es PHP 5. Los elementos AJAX en la
interfaz de usuario convierten a Collabtive en una aplicación de Internet enriquecida.
En el sitio oficial collabtive.o-dyn.de se puede ingresar a la versión demo de la aplicación.
Como se puede en las siguientes imagenes,permite la gestión de proyectos, hitos, tareas y usuarios
. Tiene un calendario que previsualiza los hitos y tareas.

Figura 4.14: Collabtive - Incio - Captura versión demo online

C.U. Marı́a Lorena Garcı́a TDD 74


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.15: Collabtive - Calendario - Captura versión demo online

Figura 4.16: Collabtive - Hitos - Captura versión demo online

C.U. Marı́a Lorena Garcı́a TDD 75


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.17: Collabtive - Lista de Tareas - Captura versión demo online

Figura 4.18: Collabtive - Usuarios - Captura versión demo online

C.U. Marı́a Lorena Garcı́a TDD 76


Capı́tulo 4. Prácticas y técnicas con TDD

Collabtive sus funciones para la gestion de proyectos son muchas, permiten planificar, organizar
y coordinar todo tipo de proyectos de una manera fácil, automatizada y colaborativa.
Si bien Collabtive cuenta con una interfaz de trabajo muy intuitiva y con módulos que facilitan
el desarrollo y gestión de proyectos de todo tipo. Siendo una alternativa muy buena y destacable
frente a las opciones comerciales existentes, no incorpora funciones para la gestión de requisitos
como son los diagramas de Gantt y la posibilidad de asignar estados a las tareas que quizás para
la emisión de informes y la comunicación con el cliente pueden llegar a ser importantes.

JIRA Software

JIRA es una aplicación online comercial para el seguimiento de errores, de incidentes y para
la gestión operativa de proyectos. Jira también se utiliza para el desarrollo de software, sirviendo
de apoyo para la gestión de requisitos, seguimiento del estatus y más tarde para el seguimiento de
errores. Jira puede ser utilizado para la gestión de procesos y para la mejora de procesos, gracias a
sus funciones para la organización de flujos de trabajo.
Jira está basado en Java EE que funciona en varias bases de datos y sistemas operativos. La
herramienta dispone también de paneles de control adaptables, filtros de búsqueda, estadı́sticas,
RSS y función de correo electrónico.
Presume ser la herramienta de desarrollo de software lı́der de los equipos ágiles, las metodologı́as
con las que trabaja son SCRUM y Kanban.
Permite la creación de historias de usuario e incidencias, planificar sprints y distribuir tareas
entre un equipo de software.
Cada equipo cuenta un proceso único para lanzar software. Utiliza un workflow predefinido o
adaptado a la forma de trabajar de un equipo[5].

Figura 4.19: Jira Software - Tablero Scrum[5]

JIRA es una completa herramienta para la gestión de proyectos de software, se basa la filosofı́a

C.U. Marı́a Lorena Garcı́a TDD 77


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.20: Jira Software - Sprint Reportes Scrum[5]

Figura 4.21: Jira Software - Sprint Scrum[50]

C.U. Marı́a Lorena Garcı́a TDD 78


Capı́tulo 4. Prácticas y técnicas con TDD

de las metodologı́as ágiles de SCRUM y Kanban. Permite la planificación, organización de Sprint


(SCRUM) y es posible utilizarlo también para todo tipo de proyectos de una manera fácil.
De lo que se pudo apreciar de capturas y resúmenes y manuales online, JIRA cuenta con una
interfaz de trabajo muy intuitiva, y se postula como una herramienta de apoyo para la gestión de
requisitos, seguimiento del estatus y más tarde para el seguimiento de errores. Contiene funcionali-
dades para el manejo de usuarios, creación de proyectos e incidencias. Especı́ficamente contiene un
modulo para la Gestión de Proyectos.
Es una alternativa completa para la gestión de requisitos, cumplen con las caracterı́sticas que
estamos analizando.

Trello

Trello: aunque es una herramienta más orientada a favorecer la colaboración de equipos de


trabajo, puede adaptarse hasta cierto punto para la gestión de proyectos. Permite la gestión de
usuarios y tareas.
Es una aplicación Web muy sencilla pero también muy básica, el registro puede ser con una cuen-
ta de Gmai, permite rápidamente la creación de tableros dentro de un Proyecto, tareas, miembros,
etc.
Las caracterı́sticas más importantes:

Tableros, listas, tarjetas, miembros, checklists, adjuntos.

Potenciadores básicos

Integraciones básicas con Box, Drive y Dropbox

Tiene una versión gratuita y dos versiones comerciales, una incorpora aplicaciones integradas,
resúmenes de equipos y mayor seguridad, y otra versión para empresas.
Esta herramienta está diseñada para hacer uso del método Kanban, proporcionando un mejor
flujo de trabajo al dividir un proceso productivo en varias fases perfectamente delimitadas.
Cada tarea es una tarjeta a la cual se le puede dar una puntuación, se le añade un miembro, y se
debe mover a una lista que representará el estado en la que la tarea se encuentra, por ejemplo ”TO
DO”(Para hacer). Una tarea puede cambiar de lista según los estados establecidos. De esta forma
se ve el flujo de trabajo, se puede revisar si se cumplen los requisitos, cuando las tareas (tarjetas)
pasan por las listas.
Las tareas que requieran documentos, imágenes u otros materiales se agregan como adjuntos.
Todos los miembros de una tarjeta reciben notificaciones de actividad de la misma.Se puede usar
las fechas de vencimiento para tareas con un deadline especı́fico.
Trello es una completa y fácil herramienta para la gestión de proyectos sin embargo, la carac-
terı́sta importante en la gestión de proyectos que no está disponible por defecto en Trello es un

C.U. Marı́a Lorena Garcı́a TDD 79


Capı́tulo 4. Prácticas y técnicas con TDD

Figura 4.22: Trello - Dashboard - Captura version gratuita

Figura 4.23: Trello - Dashboard - Captura version gratuita

C.U. Marı́a Lorena Garcı́a TDD 80


Capı́tulo 4. Prácticas y técnicas con TDD

gráfico de Gantt. Sin embargo, esta plataforma de trabajo flexible se integra con muchas aplica-
ciones de terceros que ofrecen un diagrama de Gantt para facilitar la planificación, coordinación y
seguimiento de las tareas programadas.
A través de complementos, extensiones o integraciones, Trello compensa su funcionalidad simple
y básica. Al parecer, ahora está siendo utilizado por todo tipo de equipos donde para algunos un
gráfico de Gantt es un componente esencial. Algunos de los complementos gráficos que funcionan
bien con esta herramienta PM son Elegantt10 , Ganttify11 , Placker12 , etc.
Trello junto a los complementos se convierte en alternativa completa para la gestión de requi-
sitos, su version gratuita es bastante fácil de usar siempre en cuando se entiendan los conceptos
que representan las tarjeta y listas en un proyecto. Cumple con las caracterı́sticas que estamos
analizando.

4.3.2. Servidor de Versiones


Un servidor de Versiones se encarga de llevar la gestión de los diversos cambios por lo que pasa
un elemento de algún producto o una configuración del mismo. Una version, revisión o edición es
el estado en el que se encuentra el mismo un determinado momento.
Existen herramientas que facilitan esta gestión dando lugar a los sistemas de control de versiones
o VCS (Version Control System). Estas herramientas facilitan la administración de las versiones
de los productos desarrollados. Ejemplos de este tipo de sistemas son entre otros: CVS,Subversion,
SourceSafe, ClearCase, Darcs,Bazaar,Plastic SCM, Git, SCCS, Mercurial, Perforce, Fossil SCM,
Team Foundation Server.
El control de versiones nace principalmente en la informática, la necesidad de controlar las
distintas versiones del código desarrollado.
En CI uno de los componentes importantes es un sistema de control de versiones del código, de
esta forma existe la posibilidad de recuperar versiones anteriores del código fuente desarrollado, la
posibilidad de volver a una versión anterior ante un error, y poder contar con una copia resguardo.
Para ello se necesita un servidor de versiones.
Los sistemas de control de versiones almacenan los datos e información en un repositorio central.
Las operaciones que se realiza bajo un servidor de versiones son:

Bajar una version del código.

Actualizar cambios.

Subir cambios.
10 Elegantt plugins genera automáticamente gráficos de Gantt para los tableros Trello de un usuario.
11 Ganttify es un complemento gratuito que convierte un tablero Trello en un gráfico de Gantt.
12 Complemente para Trello que tiene una vista de la carta de Gantt que exhibe un tablero, las listas y los detalles

de la tarjetas también. Desde el gráfico de Gantt, los usuarios pueden ajustar fácilmente las fechas de inicio y
finalización, cambiar el porcentaje completado y crear dependencias.

C.U. Marı́a Lorena Garcı́a TDD 81


Capı́tulo 4. Prácticas y técnicas con TDD

Es una de las mejores practicas que puede llevar a cabo un equipo de desarrolladores. Existen
diversas herramientas que proveen estas funcionalidades:

Servidor para almacenar el código fuente.

Proveer un historial de lo que se ha hecho.

Permitir el trabajo en paralelo de los desarrolladores

En este proyecto definiremos algunas de las herramientas mencionadas.

CVS (Sistema de Versiones Concurrentes)

CVS (Concurrent Versioning System)(1986-1990) es un sistema de control de versiones, un


componente importante de SCM (Source Configuration Management). Puede grabar el historial de
archivos y documentos.
CVS es un sistema de calidad de producción de uso amplio en el mundo, incluido en muchos
proyectos de software libre.
Mientras CVS almacena el historial de archivos individuales en el mismo formato que RCS,
ofrece las siguientes ventajas significativas sobre RCS[60]:

Ejecuta secuencias de comandos para suministrar registros de operaciones CVS o hacer cum-
plir polı́ticas especı́ficas.

El CVS cliente / servidor permite a los desarrolladores ubicados en diferentes lugares funcionar
como un solo equipo. El historial de versiones se almacena en un único servidor central y las
máquinas cliente tienen una copia de todos los archivos en los que están trabajando los
desarrolladores.

En los casos en que varios desarrolladores o equipos quieren mantener cada uno su propia
versión de los archivos, debido a la geografı́a y / o polı́tica, las ramas de proveedores de CVS
pueden importar una versión de otro equipo (incluso si no usan CVS ) y entonces CVS puede
combinar los cambios de la rama del proveedor con los archivos más recientes si eso es lo que
se desea.

Se puede trabajar en un archivos varios programadores al mismo tiempo.

CVS proporciona una base de datos flexible de módulos que proporciona un mapeo simbólico
de nombres a componentes de una distribución de software más grande. Aplica nombres a
colecciones de directorios y archivos. Un solo comando puede manipular toda la colección.

Los servidores CVS se ejecutan en la mayorı́a de las variantes de Unix, y los clientes Windows.

C.U. Marı́a Lorena Garcı́a TDD 82


Capı́tulo 4. Prácticas y técnicas con TDD

Las limitaciones son que los archivos en el repositorio sobre la plataforma CVS no pueden ser
renombrados, estos deben ser agregados con otro nombre y luego eliminados. El protocolo CVS no
provee una manera de que los directorios puedan ser eliminados o renombrados, cada archivo en
cada subdirectorio debe ser eliminado y re-agregado con el nuevo nombre. Soporte limitado para
archivos Unicode con nombres de archivo no ASCII.
Actualmente CVS es una opción desactualizada. Fue una buena alternativas en su momento
siendo la única alternativa, pero actualmente han sido sobrepasada de largo por otras opciones. Lo
mismo ocurre con Microsoft Visual SourceSafe (VSS), que también es una herramienta de Control
de versiones que forma parte de Microsoft Visual Studio aunque está fue sustituida por Visual
Studio TFS (Team Foundation Server).
El cambio natural entre herramientas serı́a, si se usa CVS pasar a Git, y si se usaba VSS pasar
a TFS, existe la documentación para realizar las migraciones correspondientes.

SVN (Subversión)

Apache Subversión (abreviado frecuentemente como SVN, por el comando svn) es una herra-
mienta de control de versiones open source basada en un repositorio cuyo funcionamiento se asemeja
enormemente al de un sistema de ficheros. Es software libre bajo una licencia de tipo Apache/BSD.
Subversión se desarrolla como un proyecto de la Apache Software Foundation , y como tal forma
parte de una rica comunidad de desarrolladores y usuarios.
La siguiente lista son algunas de las caracterı́sticas de SVN y cómo funcionan los sistemas de
control de versiones en general[25].

La mayorı́a de las caracterı́sticas de CVS, como ya explicamos arriba es un sistema de control


de versiones relativamente básico. En su mayor parte, Subversión ha igualado o superado el
conjunto de caracterı́sticas de CVS, donde esas caracterı́sticas continúan aplicándose en el
diseño particular de Subversion.

Los directorios están versionados. Subversión versiones directorios como objetos de primera
clase, al igual que los archivos.

Las acciones de copia, eliminación y cambio de nombre

Subversión permite que los metadatos arbitrarios (”propiedades”) se adjunten a cualquier


archivo o directorio. Estas propiedades son pares clave / valor, y se versionan como los objetos
a los que están conectados.

Impacto del commit. Ninguna parte de un commit tiene efecto hasta que todo el commit haya
tenido éxito. Los números de revisión son por commit, no por archivo, y el mensaje de log de
commit está conectado a su revisión.

C.U. Marı́a Lorena Garcı́a TDD 83


Capı́tulo 4. Prácticas y técnicas con TDD

Ramificación y etiquetado: Las ramas y las etiquetas se implementan en términos de una


operación subyacente de çopia”. Una copia ocupa una cantidad pequeña y constante de espa-
cio. Cualquier copia es una etiqueta; y si empiezas a comprometerse en una copia, entonces
también es una rama.

Seguimiento de la fusión. Subversión 1.5 introduce el seguimiento de la mezcla (merge): la


asistencia automatizada para gestionar el flujo de cambios entre lı́neas de desarrollo y la fusión
de las ramas en sus fuentes.

Bloqueo de archivos. Subversión soporta (pero no requiere) el bloqueo de archivos para que
los usuarios pueden ser advertidos cuando varias personas intentan editar el mismo archivo.
Un archivo puede ser marcado como requiriendo un bloqueo antes de ser editado, en cuyo caso
Subversión presentará el archivo en modo de sólo lectura hasta que se obtenga un bloqueo.

Opción de servidor de red Apache, con protocolo WebDAV / DeltaV. Subversion puede uti-
lizar el protocolo WebDAV / DeltaV basado en HTTP para las comunicaciones de red y el
servidor web Apache para proporcionar servicio de red del lado del repositorio. Esto da a
Subversion una ventaja sobre CVS en interoperabilidad y permite que ciertas caracterı́sti-
cas (como autenticación, compresión de hilos) sean proporcionadas de una manera que ya es
familiar para los administradores

Opción de servidor independiente ( svnserve ). Subversión ofrece una opción de servidor


independiente usando un protocolo personalizado, ya que no todo el mundo quiere ejecutar
un servidor Apache HTTPD. El servidor autónomo puede ejecutarse como un servicio inetd
o en modo daemon y ofrece el mismo nivel de autenticación y funcionalidad de autorización
que el servidor basado en HTTPD. El servidor independiente también puede ser tunelizado
sobre ssh.

Se mantiene el indicador ejecutable. Subversion notifica cuando un archivo es ejecutable, y


si ese archivo se coloca en el control de versiones, su ejecutabilidad se conservará cuando se
realiza el check-out a otras ubicaciones. (El mecanismo que Subversion usa para recordar esto
es simplemente propiedades versionadas , por lo que la ejecutabilidad se puede editar manual-
mente cuando sea necesario, incluso desde un cliente que no reconoce la capacidad de ejecución
del archivo, por ejemplo, cuando tiene la extensión incorrecta en Microsoft Windows).

Los archivos binarios se manejan de manera eficiente. Subversión es igualmente eficiente en


binario como en archivos de texto, ya que utiliza un algoritmo de difusión binaria para trans-
mitir y almacenar revisiones sucesivas.

Git

Git es un sistema de control de versiones distribuidas de código abierto y libre diseñado para
manejar desde proyectos pequeños hasta muy grandes con rapidez y eficiencia. Git es fácil de apren-

C.U. Marı́a Lorena Garcı́a TDD 84


Capı́tulo 4. Prácticas y técnicas con TDD

der y tiene una huella muy pequeña con un rendimiento rápido .Tiene funciones como ramificación
local barata , áreas de puesta en escena convenientes y múltiples flujos de trabajo.
Posee las funcionalidades de todo SCM, agrega algo importante que es la ramificación y fusión.
Git permite tener múltiples ramas locales que pueden ser totalmente independientes entre sı́.
La creación, la fusión y la supresión de esas lı́neas de desarrollo toma segundos.
Esto significa que se puede hacer cosas como[14]:

Cambio de contexto sin problemas . Se puede crear una rama para probar una idea, comenzar
varias veces, cambiar de nuevo a donde se ramificó, aplicar un parche, cambiar de nuevo a
donde se está experimentando y fı́jar.

Lı́neas de base basadas en funciones, por ejemplo una version que va ala producción, una
versión que va al servidor de pruebas y varias más pequeñas para el trabajo diario.

Flujo de trabajo basado en funciones . Una rama para cada nueva función en la que se trabaje
para cambiar sin problemas entre ellas y la opción de a continuación eliminar cada una de las
çopiasçuando se fusiona con la lı́nea principal.

Experimentación descartable . Crear una rama para experimentar, verificar si funciona, eli-
minarlo, abandonarlo.

Mercurial

Mercurial es una herramienta con licencia GPLv2, gratuita y distribuida de control de versiones
de código fuente. Maneja eficientemente proyectos de cualquier tamaño y ofrece una interfaz fácil e
intuitiva.
Mercurial maneja proyectos de cualquier tamaño y tipo . Cada clon o copia contiene toda la
historia del proyecto, por lo que la mayorı́a de las acciones son locales, rápidas y convenientes.
Soporta una multitud de flujos de trabajo y puede mejorar su funcionalidad con extensiones .
Al ser de arquitectura distribuida y no como Subversión de arquitecturas cliente-servidor con un
servidor central para almacenar las revisiones de un proyecto, Mercurial es realmente distribuido
dando a cada desarrollador una copia local de toda la historia del desarrollo. De esta manera fun-
ciona independientemente del acceso a la red o de un servidor central. Las funciones de ramificación
y fusión son rápidas y baratas.
Es de plataforma independiente, por lo tanto, la mayor parte de Mercurial está escrito en Python,
con una pequeña parte en C portátil por razones de rendimiento. Como resultado, las versiones
binarias están disponibles en todas las plataformas principales.
Algunas de sus caracterı́sticas son[8]:

Extensible:La funcionalidad de Mercurial se puede aumentar con extensiones, ya sea acti-


vando las oficiales que se envı́an con Mercurial o descargar algunas de la wiki o escribiendo
personalizadas . Las extensiones están escritas en Python y pueden cambiar el funcionamiento

C.U. Marı́a Lorena Garcı́a TDD 85


Capı́tulo 4. Prácticas y técnicas con TDD

de los comandos básicos, agregar nuevos comandos y acceder a todas las funciones principales
de Mercurial.

Fácil de usar, cómodo y las acciones potencialmente peligrosas están disponibles a través
de extensiones que necesita habilitar, por lo que la interfaz básica es fácil de usar, fácil de
aprender y difı́cil de romper.

TFS (Team Foundation Server)

Team Foundation Server (comúnmente abreviado a TFS ) es un producto de Microsoft que


proporciona un conjunto de herramientas para la gestión de código fuente (ya sea con el control de
versiones de TFS o Git ), la presentación de informes, gestión de requisitos , gestión de proyectos
(ágiles o tradicionales), despliegue automatizado, pruebas y capacidades de gestión de liberación.
Cubre todo el ciclo de vida de un software y permite capacidades de DevOps13 . TFS se puede
utilizar como un back-end a numerosos entornos de desarrollo integrado (IDE), pero está diseñado
para Microsoft Visual Studio y Eclipse en todas las plataformas.
Algunas de las herramientas son[43]:

Control de versiones: Permite almacenar y colaborar en códigos con repositorios privados. Usa
GIT para realizar un control distribuido de las versiones o el control de versiones de Team
Foundation (TFVC) para controlar las versiones de forma centralizada.

Herramientas para equipos de Agiles: Capturar, priorizar y realizar un seguimiento del trabajo
con trabajos pendientes y paneles Kanban personalizables.

Integración continua: Compilar, empaquetar, probar, liberar, repetir. Automatizar todas las
implementaciones y realiza un seguimiento con la administración de versiones.

Compatibilidad con Java: Herramienta para desarrollar en cualquier plataforma. Lo que po-
sibilita usar el IDE que se prefiera: Eclipse, IntelliJ, Android Studio, Visual Studio Code, etc.
Luego compilar el código con Ant, Maven y Gradle desde sus repositorios de GIT, Subver-
sion y TFVC. Implemente CI/CD con capacidades nativas o por medio de integraciones con
sistemas como Jenkins14 . También admite lenguajes móviles y multiplataforma, incluidos los
siguientes: C++15 , PHP16 , Python17 , Go18 , Swift19 y muchos más.
13 DevOps es un acrónimo de inglés de development (desarrollo) y operations (operaciones), que se refiere a una
cultura o movimiento centrado en la comunicación, colaboración e integración entre desarrolladores de software y los
profesionales en las tecnologı́as de la información (IT).
14 Jenkins es un software de Integración continua open source escrito en Java.
15 C++ es un lenguaje de programación extendención del lenguaje de programación C, el C++ es un lenguaje

hı́brido.
16 PHP es un lenguaje de programación de propósito general de código del lado del servidor originalmente diseñado

para el desarrollo web de contenido dinámico.


17 Python es un lenguaje de programación interpretado.Posee una licencia de código abierto, denominada Python

Software Foundation License


18 Go es un lenguaje de programación concurrente y compilado inspirado en la sintaxis de C. Ha sido desarrollado

por Google y sus diseñadores iniciales son Robert Griesemer, Rob Pike y Ken Thompson.
19 Swift es un lenguaje de programación multiparadigma creado por Apple enfocado en el desarrollo de aplicaciones

C.U. Marı́a Lorena Garcı́a TDD 86


Capı́tulo 4. Prácticas y técnicas con TDD

Abierto y extensible: Es muy fácil integrar una herramienta personalizada o servicio de ter-
ceros con Team Foundation Server mediante estándares abiertos, como la API de REST y
OAuth 2.0.

Team Foundation Server Express : Gratis para usuarios individuales y equipos pequeños

Bitbucket

Bitbucket es un servicio de alojamiento basado en web, para los proyectos que utilizan el sistema
de control de revisiones Mercurial y Git. Bitbucket ofrece planes comerciales y gratuitos. El servicio
está escrito en Python.2
Sistema de control de versiones distribuido con modelos de despliegue flexibles para equipos de
cualquier tamaño y con todo tipo de necesidades. Alojado en la nube o en servidores privados.

4.3.3. Pruebas Automatizadas


Si los errores aparecen lo antes posible más sencillo será encontrar su origen y erradicarlos. Por
lo tanto el verdadero poder de la CI está en la realización de pruebas automatizadas, el diseño,
elaboración y despliegue.
La automatización de pruebas unitarias son una forma de probar el correcto funcionamiento de
un módulo de código, mediante el uso de marcos de trabajo como NUnit, JUnit o PHPUnit. Ahora,
para autorizar las pruebas de componente es mucho más complicado que las pruebas unitarias, pero
es posible al usar herramientas como JUnit, NUnit, DbUNit y NDbUnit para el caso de base de
datos. Con las pruebas de sistema la automatización el tiempo es mucho mayor que en los tipos
anteriormente mencionados porque envuelven varios componentes. Tienen por objetivo verificar
que comportamiento externo del software satisface los requisitos establecidos por los clientes (un
código de calidad también es un requisito establecido, pero el cliente da por hecho que es lo que
obtendrá, y es algo que no puede verificar) y futuros usuarios del mismo. En la automatización de
pruebas de funcionalidad, se realizan desde la perspectiva del usuario, las herramientas que se usan
actualmente son Selenium (para Web) y Abbot (para GUI).
En la automatización de pruebas se crean categorı́as de pruebas de modo de facilitar la ejecución
y agruparlas de acuerdo a complejidad y tiempo. Se suele ejecutar las pruebas más rápidas primero,
las que requieren menos tiempo de ejecución.
Sin las pruebas automatizadas es muy difı́cil para los diseñadores u otros equipos de trabajo
tener confianza en los cambios que se realizan en el software. La mayorı́a de los diseñadores que
utilizan un sistema de CI utilizan herramientas para realizar pruebas unitarias como JUnit, NUnit
y otros marcos de trabajo del grupo xUnit. También se puede ejecutar categorı́as diferentes de
pruebas en un proceso de CI para acelerar sus compilaciones.
A continuación se describen las herramientas mencionadas para la realización de las pruebas
automatizadas, estas son:
para IOS y MacOS.En el año 2015 pasó a ser de código abierto.

C.U. Marı́a Lorena Garcı́a TDD 87


Capı́tulo 4. Prácticas y técnicas con TDD

JUnit

Marco de trabajo para pruebas unitarias creado por Erich Gamma y Kent Beck, herramienta
de código abierto que se ha convertido en el estándar para las pruebas unitarias en Java y que es
soportado por la mayorı́a de los Entorno de Desarrollo Integrado (IDEs), como Eclipse o Net-Beans.
Consiste en un conjunto de clases, fácil de usar y aprender que les permite a los programadores
escribir sus pruebas unitarias en el lenguaje Java. Posee una comunidad mucho mayor que el resto
de los marcos de trabajo de pruebas en Java.

PhpUnit

Marco de trabajo para las pruebas unitarias en especı́fico a PHP, es de licencia BSD. Es uno
mas de los marcos de trabajo de xUnit. Se integra con varias aplicaciones de pruebas. Facilita la
creación de pequeños scripts que ayudan a probar las aplicaciones y analizar los resultados.

NUnit

NUnit es un marco de pruebas unitarias para todos los lenguajes .Net. Inicialmente portado
de JUnit. Es un software de código abierto y NUnit 3 es liberado bajo la licencia del MIT . Las
versiones anteriores usaban la licencia NUnit .

doctest

El marco de prueba doctest es un módulo de Python que viene preenvasado con Python. Permite
la fácil generación de pruebas basadas en la salida del intérprete de estandar de Python.
doctest busca partes de texto que parecen sesiones de Python interactivas y luego ejecuta esas
sesiones para verificar que funcionan exactamente como se muestra. Hay varias maneras comunes
de usar doctest:
Las pruebas unitarias son llamadas en los comentarios. Se escribe la documentación de un
paquete, ampliamente ilustrado con ejemplos de entrada y salida. Dependiendo de si se enfatizan
los ejemplos o el texto expositivo, esto tiene el sabor de ”pruebas alfabetizadas.o ”documentación
ejecutable”[10].

FitNesse

Es una herramienta de colaboración, puesto que FitNesse es un servidor web wiki, tiene una
entrada y una curva de aprendizaje muy baja, lo que la convierte en una excelente herramienta
para colaborar con, por ejemplo, las partes interesadas del negocio. También es una herramienta
de prueba, las páginas de wiki se convierten en pruebas que son ejecutadas. Las especificaciones
pueden ser probadas en contra de la aplicación en sı́, lo que resulta en un viaje de ida y vuelta
entre las especificaciones y la implementación.

C.U. Marı́a Lorena Garcı́a TDD 88


Capı́tulo 4. Prácticas y técnicas con TDD

Proyecto de código abierto. La base de código no es propiedad de ninguna compañı́a. La co-


munidad de FitNesse comparte mucha información. Es extremadamente adaptable y se utiliza en
áreas que van desde las pruebas Web / GUI hasta la prueba de componentes electrónicos.
Se puede especificar y verificar los criterios de aceptación de la aplicación (requisitos). Su servidor
wiki hace que sea fácil documentar el software. Su capacidad de testexecution le permite verificar
la documentación contra el software, asegurando que la documentación permanezca actualizada y
el software no esté enfrentando regresión.
Para que esto funcione, las pruebas deben definirse en un nivel de negocios, en conjunto con
los clientes. Son básicamente requisitos de negocio, presentados de una manera fácil de entender
por todas las partes interesadas. Cuando sus requisitos no son ambiguos, pueden ser verificados
automáticamente con su aplicación.
Para que sea fácil para todos los interesados interactuar con FitNesse , los requisitos se pueden
crear y editar a través del navegador web. Las especificaciones se pueden escribir en la sintaxis
de wiki o en un editor de texto enriquecido, por lo que no se necesita ningún conocimiento de la
sintaxis wiki[46].

Selenium

Selenium es una herramienta que automatiza los navegadores.Principalmente, es para la auto-


matización de aplicaciones web para fines de pruebas, aunque no se limita a eso. Cuenta con el apoyo
de algunos de los proveedores de navegadores más grandes que han tomado (o están tomando) los
pasos para hacer Selenium una parte nativa de su navegador. También es la tecnologı́a principal en
innumerables herramientas de automatización de navegadores, APIs y frameworks.
Se ejecuta en muchos navegadores y sistemas operativos puede ser controlado por muchos len-
guajes de programación y marcos de prueba.
La mayorı́a de las aplicaciones de software hoy en dı́a se escriben como aplicaciones basadas
en la web. La eficacia de la prueba de estas aplicaciones varı́a ampliamente entre empresas y
organizaciones. En una era de procesos de software altamente interactivos y sensibles donde muchas
organizaciones están utilizando algún tipo de metodologı́a Agile, la automatización de pruebas se
está convirtiendo en un requisito para los proyectos de software.
Selenium es posiblemente la solución de código abierto más utilizada por las aplicaciones web.
Pero Selenium es un conjunto de herramientas diferentes cada una con un enfoque diferente
para apoyar la automatización de pruebas. La mayorı́a de los ingenieros de Selenium QA se centran
en una o dos herramientas que más satisfacen las necesidades de su proyecto. Todo el conjunto
de herramientas resulta en un rico conjunto de funciones de pruebas especı́ficamente orientadas a
las necesidades de las pruebas de aplicaciones web de todo tipo. Estas operaciones son altamente
flexibles, permitiendo muchas opciones para localizar elementos de interfaz de usuario y comparar
los resultados esperados de la prueba con el comportamiento real de la aplicación. Una de las
caracterı́sticas clave de Selenium es el soporte para ejecutar sus pruebas en múltiples plataformas
de navegación.

C.U. Marı́a Lorena Garcı́a TDD 89


Capı́tulo 4. Prácticas y técnicas con TDD

Las herramientas de Selenium son[49]:

Selenium WebDriver (Selenium 2): Es hacia donde va el proyecto y la adición más reciente al
conjunto de herramientas Selenium. Esta nueva herramienta de automatización ofrece todo
tipo de caracterı́sticas impresionantes, incluyendo una API más cohesiva y orientada a objetos,
ası́ como una respuesta a las limitaciones de la antigua implementación.

Selenium RC (Remote Control) (Selenium 1): Biblioteca de Javascript que podrı́a impulsar
las interacciones con la página, permitiéndole volver a ejecutar automáticamente pruebas
contra varios navegadores. Esa biblioteca finalmente se convirtió en Selenium Core, que sub-
yace a toda la funcionalidad de Selenium (RC) y Selenium IDE. Selenium RC fue innovador
porque ningún otro producto le permitió controlar un navegador desde un idioma de su elec-
ción. Ahora Selenium 1 está obsoleto y no se admite activamente (sobre todo en modo de
mantenimiento).

Selenium IDE (Integrated Development Environment): Es una herramienta de creación de


prototipos para crear scripts de prueba. Es un complemento de Firefox y proporciona una
interfaz fácil de usar para el desarrollo de pruebas automatizadas. Selenium IDE tiene una
función de grabación que registra las acciones de los usuarios a medida que se realizan y luego
las exporta como una secuencia de comandos reutilizable en uno de los muchos lenguajes de
programación que se pueden ejecutar posteriormente.

Selenium Grid: Permite que la solución Selenium RC sea escalable para grandes suites de
prueba y para suites de prueba que deben ejecutarse en múltiples entornos. Selenium Grid
le permite ejecutar sus pruebas en paralelo, es decir, se pueden ejecutar diferentes pruebas
al mismo tiempo en diferentes máquinas remotas. Esto tiene dos ventajas. En primer lugar,
si tiene una suite de pruebas grande o una suite de pruebas de ejecución lenta, puede au-
mentar considerablemente su rendimiento utilizando Selenium Grid para dividir su suite de
pruebas para ejecutar diferentes pruebas al mismo tiempo utilizando esas diferentes máqui-
nas. Además, si debe ejecutar su suite de pruebas en varios entornos, puede tener distintas
máquinas remotas soportando y ejecutando sus pruebas en ellas al mismo tiempo. En cada
caso, Selenium Grid mejora en gran medida el tiempo que tarda en ejecutar su suite haciendo
uso del procesamiento paralelo.

4.3.4. Construcción y despliegue automatizados


Consiste en automatizar el proceso de todas las tareas que se realizan y de esta forma conseguir
construir un sistema que automatice el despliegue a partir del código que ha sido desarrollado, de
forma que este sea desplegado y este disponible para ser utilizado.
Despliegue continuo suele confundirse con entrega continua, la diferencia radica en que cuando
hablamos de despliegue continuo una vez que se realizan cambios y se atraviesa exitosamente lo

C.U. Marı́a Lorena Garcı́a TDD 90


Capı́tulo 4. Prácticas y técnicas con TDD

que se denomina “Pipeline”20 . Despliegue continuo significa entonces que se tiene la capacidad de
realizar despliegues frecuentemente, aunque en general esta acción debe pasar primero por una apro-
bación por parte del negocio, quien determina cuántos y cuándo se hacen efectivos los despliegues
al ambiente productivo.
Para automatizar estos procesos existen algunas herramientas las cuales permiten llevar a cabo
la mayorı́a de las tareas que se ejecutan de forma manual, estas son:

Ant

Apache Ant es una herramienta usada para la realización de tareas mecánicas y repetitivas, nor-
malmente durante la fase de compilación y construcción (build). Es similar a Make pero desarrollado
en lenguaje Java y requiere la plataforma Java.
Esta herramienta, hecha en el lenguaje de programación Java, tiene la ventaja de no depender de
las órdenes del shell de cada sistema operativo, sino que se basa en archivos de configuración XML y
clases Java para la realización de las distintas tareas, siendo idónea como solución multi-plataforma.

Maven

Apache Maven es una herramienta de gestión de proyectos de software y de comprensión. Basado


en el concepto de un modelo de objetos de proyecto (POM), Maven puede gestionar la compila-
ción, la elaboración de informes y la documentación de un proyecto a partir de una información
central[32].
Es capaz de encargarse de la gestión de dependencias, construcción de los artefactos, generación
de la documentación, etc. Su configuración es más simple, reutilizable y consistente que la de Ant.
Una vez instalado y configurado, no es necesario mantenerlo. Es rápido el acceso a los paquetes ya
descargados. Tiene licencia Apache 2.0. Es independiente de conexión a Internet, excepto cuando
se necesita algún paquete nuevo.

4.3.5. Servidores de Integración


Existen muchos servidores de integración, en el sitio web continuousintegrationtools.com se
puede ver una catalogo dividido entre los que son comerciales y los opensource. La lista publicada
por el sitio se puede encontrar en el Anexo II. Abordaremos solo una selección de ellos, bajo el
criterio de popularidad y de facilidad de implementación.

Cruise Control

CruiseControl es una aplicación de código abierto basado en Java que permite la compilación au-
tomática de proyectos Java, utilizando Ant o Maven. Es una herramienta que se utiliza comúnmente,
20 Son cada uno de los pasos que forman el flujo de trabajo de construcción y entrega del software. Cada uno de

estos pasos se ocupa de realizar una tarea concreta, por ejemplo: un primer paso podrı́a ser la descarga de código,
un segundo paso la compilación del código descargado, etc

C.U. Marı́a Lorena Garcı́a TDD 91


Capı́tulo 4. Prácticas y técnicas con TDD

que en cada cierto tiempo que es configurable o si la indicación es cuando haya cambios obtiene de
un servidor de versiones como CVS o Subversión una copia del código fuente a la cual compila y eje-
cuta los test, o incluso lo que este configurado con Ant o Maven. Una vez terminada este despliegue
de procesos, el resultado puede ser visualizado en HTML o enviado por correo electrónico[15].
Actualmente, existe también una versión de CruiseControl para .Net llamada CruiseControl.Net.
Soporta medios de almacenamiento como por ejemplo servidores Protocolo de Transferencia de
Archivos (FTP) o Web. Su fácil proceso de instalación y configuración a partir de Lenguaje de
Marcas Extensibles (XML), en el que se definen, entre otras cosas, las tareas a realizar en el ciclo
de construcción para cada uno de los proyectos registrados.

Jenkins

Jenkins es un servidor de CI gratuito, open-source y actualmente uno de los más empleados


para esta función. Popular por su facilidad de uso. Se puede descargar del sitio jenkins-ci.org .
Es el sucesor de una herramienta llamada Hudson ideada por una persona que trabajaba en Sun,
años después cuando Oracle comprará a Sun decide renombrar el proyecto a Jenkins. El código es
migrado a GitHub y desde ahı́ se continua el trabajo desde ahı́. No obstante, Oracle ha seguido
desde entonces manteniendo y trabajando en Hudson.
La base de Jenkins son las tareas, donde indicamos qué es lo que hay que hacer en un build. Un
ejemplo, es chequear el servidor de versiones cada cierto tiempo, de manera que si un desarrollador
incorporó un cambio este se compile y ejecute pruebas. Si el resultado no es el esperado o hay algún
error, Jenkins notificará al desarrollador, al equipo de QA, por email o cualquier otro medio para
que lo solucione.
Además de ayudar a integrar el código periódicamente, actúa como herramienta de enlace de
todo el proceso de desarrollo. Se puede indicar el lanzamiento de métricas de calidad y visualizar
los resultados dentro de la misma herramienta.
Se puede visualizar el resultado de los tests, generar y visualizar la documentación del proyecto
o incluso pasar una versión estable del software.

Travis-CI

Herramienta que da una forma simplificada de hacer Integración Continua. Travis CI es una
plataforma en la nube que funciona de manera gratuita para repositorios GitHub públicos, también
con planes pagados para repositorios privados, la cual opera asi:

1. Hacer git push21 al proyecto.

2. Travis CI detecta el git push y analiza el proyecto por una máquina virtual en la nube. Se
construye y se verifica si compila.
21 Comando que sube los cambios hechos en un ambiente de trabajo a una rama de trabajo en un equipo remoto

C.U. Marı́a Lorena Garcı́a TDD 92


Capı́tulo 4. Prácticas y técnicas con TDD

3. Incorporación de más tareas antes y después de la verificación, por ejemplo tests unitarios
o despliegue de plataformas, todo esto es controlado por el archivo .travis.yml que va en el
directorio raı́z del repo del proyecto.

4. Revisación en la web de Travis CI si el build del proyecto fue exitoso o falló. En caso de falla,
se hará llegar una notificación por correo electrónico.

Entre sus funciones estan[54]:

Se miran las pruebas correr.

Mantenimiento de configuración del código.

Envios de correos electronicos.

Una máquina virtual limpia para cada compilación.

Ejecución de pruebas en paralelo.

Soporte para Linux, Mac y iOS.

API y herramienta de lı́nea de comandos.

4.3.6. Control de Calidad


SonarQube

Heramienta para una inspección continua, SonarQube proporciona la capacidad no sólo para
mostrar la salud de una aplicación, sino también para resaltar los problemas introducidos recien-
temente. Con una puerta de calidad en su lugar, puede arreglar la fuga y por lo tanto mejorar la
calidad del código sistemáticamente.
Los problemas planteados por SonarQube se encuentran en un código incorrectamente demos-
trable o en un código que es más probable que no tenga el comportamiento deseado. Los ejem-
plos incluyen desreferencias, pérdidas de memoria y errores lógicos. Búsqueda de código con ”mal
olor”que hace (probablemente) lo que deberı́a, pero será difı́cil de mantener. Los ejemplos incluyen
código duplicado, código descubierto por pruebas unitarias y código demasiado complejo.
Puede detectar las vulnerabilidades de seguridad en más de 20 lenguajes de programación.
Ofrece informes sobre código duplicado, estándares de codificación , pruebas unitarias, cobertura
de código, la complejidad del código, comentarios, errores y vulnerabilidades de seguridad. Graba
historial de métricas y proporciona gráficos de evolución. El mayor activo de SonarQube es que
proporciona análisis totalmente automatizados e integración con Maven , Ant , Gradle, MSBuild y
herramientas de integración continua ( Atlassian Bamboo , Jenkins , Hudson , etc.).
También se integra con Eclipse , Visual Studio y IntelliJ IDEA entornos de desarrollo a través
de los plugins SonarLint y se integra con herramientas externas como LDAP , Active Directory ,
GitHub , etc.

C.U. Marı́a Lorena Garcı́a TDD 93


Capı́tulo 4. Prácticas y técnicas con TDD

ReSharper

Herramienta comercial de análisis de calidad de código disponible en C#, VB.NET, XAML,


ASP.NET, JavaScript, TypeScript, CSS, HTML y XML. ReSharper le permite saber si su código
puede ser mejorado y sugiere arreglos rápidos automáticos.
Los arreglos instantáneos ayudan a eliminar errores y ”mal olores.en el código. Advierte cuando
hay problemas en el código, y proporciona soluciones rápidas para resolverlos automáticamente.
Aplicar refactorizaciones de el proyecto o transformaciones de código más pequeñas para cambiar
con seguridad la base de código.
Utiliza el formato de código y limpieza para eliminar código no utilizado y garantizar el cum-
plimiento de los estándares de codificación.

C.U. Marı́a Lorena Garcı́a TDD 94


Capı́tulo 5

Guı́a práctica

En capı́tulos anteriores hemos desarrollado las metodologı́as TDD, ATDD, BDD entre otras y
sus variantes, junto a las herramientas para Integración Continua, sus ventajas e inconvenientes de
usarla. Por lo que antes de ir a la parte práctica, se hará una propuesta de Guı́a para la utilización
de TDD. En lo que respecta a CI se recomienda consultar la documentación de cada herramienta
para poder realizar su instalación. El conjunto de herramientas que se eligen en CI depende mucho
del equipo de desarrollo, del conocimiento de los desarrollo en el uso de servidores de versiones,
base de datos, etc.
Partiremos desde una visión general que nos permita evaluar si es conveniente en un caso
particular utilizar las metodologı́as y herramientas explicadas. Y luego los pasos que debemos
abordar para aplicarlas a un ejemplo práctico.

5.1. Evaluación previa


Antes de abordar una metodologı́a ágil de desarrollo nos debemos preguntar si es la adecuada
para nuestro equipo o para el sistema que se pretende desarrollar. Trataremos de determinar que
preguntas deberı́amos hacernos primero.
Un equipo de desarrolladores puede variar entre una persona a 50, pero en cualquier numero
siempre existirá una serie de roles o funciones que deben estar y que estos estén bien identificados.
El identificar los roles permitirá al grupo tener una estructura y crear conciencia de las responsa-
bilidades. Si no tengo claro cuales son mis funciones, puedo ”suponer”que no las tengo, que no hay
responsabilidad en mi con una función y el equipo fallará cuando esa función no este resuelta. El
tener una responsabilidad ayuda a evitar errores en una versión final.
Entonces una de las primeras preguntas que nos podemos hacer es, ¿tenemos roles identifi-
cados?. Ahora como estamos pensando en aplicar una metodologı́a, entonces la siguiente pregunta
podrı́a ser ¿por qué esta metodologı́a?
A menudo grupos grandes o pequeños, todos poseedores de la idea de que se puede mejorar,

95
Capı́tulo 5. Guı́a práctica

por que simplemente es beneficioso para todos. Es mejor para el cliente, para entenderse mejor,
para evitar malos entendidos, por eso mismo todo equipo tiene el afán de caer en el mal uso de
metodologı́as simplemente por considerar que pueden ser soluciones mágicas. Existe quien dice que
”los equipos que eligieron esta metodologı́a les fue bien”, es una afirmación que puede resultar
peligrosa, es generalizar mucho, intervienen muchos factores en un grupo de personas y en un
momento particular. No hay garantı́as, todos los equipos son distintos.
Entonces debemos evaluar si nuestro equipo cumple con las condiciones necesarias para aplicar
TDD, y de llevar el desarrollo bajo CI. TDD es un conjunto de practicas, es flexible, más bien su
definición es un algoritmo ”primero el test, luego el código, y refactorizamos”. CI es un conjunto de
herramientas, algunas mejores para ciertos proyectos, óptimas en grupos pequeños o no, y muchos
otros puntos para analizar más, pero todas tienen su tiempo de implementación y de conocimiento.
Entonces, algunas de las preguntas que nos debemos hacer son:

1. ¿Mi grupo de desarrollo entiende la filosofı́a de TDD?

2. ¿Sabé aplicar TDD?

3. ¿Porque queremos usar TDD?

4. ¿Tengo automatización en algún nivel en mi desarrollo? ¿Se cuenta con experiencia en el


tema?

5. ¿Es un equipo nuevo?¿Hay gente que tiene experiencia en TDD?

6. ¿Se utiliza o utilizó alguna metodologı́a ágil?

7. ¿El cliente participará en el desarrollo del software? ¿Estará dispuesto a hacerlo?

Análisis de las preguntas

Tanto la pregunta 1 como la pregunta 2 están enfocadas al equipo. El equipo deberá entender
la filosofı́a de TDD y además de entenderla .adoptarla”. No es algo fácil, porque TDD supone un
cambio radical en la forma de programar. Se acostumbra a hacer código, ejecutarlo, modificarlo,
agregarle mas funcionalidades, y cuando llega el momento de la entrega recién revisarlo, a buscar
errores, probarlo. Para ese entonces el código es complejo, tiene muchas clases que no se sabe bien
que hacen, para que están, muchos métodos que se llaman entre sı́. Buscar código duplicado ya
no es sencillo, reestructurar un método que es utilizado por varios componentes tampoco, todo
esto si se busca las ventajas que nos da refactorizar. Hay mucha información de TDD, experiencias
personales, técnicas, ”tips”. Lo cierto es que TDD es simple de explicar pero difı́cil de aplicar.
TDD es una disciplina que promueve una forma de desarrollar software con altos niveles de
calidad, simplicidad de diseño y productividad del programador. Dijimos que suena simple, pero
cuando se esta aprendiendo a tomar el enfoque de TDD nos encontramos realmente con lo que
significa tener disciplina, porque es fácil cometer un ”desliz escribir código funcional sin escribir
2

C.U. Marı́a Lorena Garcı́a TDD 96


Capı́tulo 5. Guı́a práctica

primero una nueva prueba. Una de las ventajas de programar de pares es que la pareja ayuda a
permanecer en el camino. Entonces no es algo que aplicamos “según como nos sentimos”, es algo
que debe formar parte integral de la profesión o arte[48].
En un inicio se acostumbra a ir verificando que el código funciona, sin nada de por medio
que çertifique”que es ası́. Cada vez que el resultado es el esperado aumenta la autoconfianza en
el desarrollador, es una motivación a seguir programando. El problema es que desarrolladores se
confı́an, se disponen a crear código y más código sin ninguna comprobación con el propósito de
optimizar tiempo y además porque, se piensa, el código .esta bien”. Lo que pasa al final es que, ya
no se comprueba por medio de los resultados si el código funciona bien, total lo hizo antes, esto de
comprobar cada rato es para novatos. No es necesario revisar el código[2].
Para la pregunta 3, hay que tener claro el motivo por el que se busca incorporar TDD y
CI. Se puede decir que ambos conceptos buscan lo mismo, el primero se adentra en lo que es
codificación y el otro en la producción, ambos buscan calidad, producción, reducción de riesgos. Si
no existe motivo alguno para aplicar estás metodologı́as, entonces no hay porque seguir. ¿Lo solicito
el Cliente o algún superior?. Si es ası́, lo que corresponderı́a es analizar si es conveniente e informar
la conclusión de esto a quién solicitó el uso de la metodologı́a. Si en cambio se está convencido y
los motivos que se tienen son suficientes para incorporar TDD seguro se irá por buen camino.
La pregunta del punto 4 habla de automatización, cuando se habla de TDD se asume que
hay una parte de automatización, porque las pruebas se corren todas al final de cada nueva imple-
mentación. Pero no es un requisito necesario y obligatorio la utilización de automatización. Aquı́ es
donde se recuerda todo lo que se investigó de Integración Continua.
CI hace foco en dos cosas: una es la ejecución de pruebas cada vez que realiza una integración
o un cambio en el código y por otro lado se resalta la frecuencia con que esto se realiza. Ambos
puntos son sin dudas los ejes principales de esta práctica, ya que ambos en conjuntos son los que
permiten detectar errores lo antes posible de manera de minimizar los riesgos. Como podemos
ver de la definición de automatización lo que estamos haciendo es sustituyendo el esfuerzo fı́sico
humano. Lo importante es aplicar la práctica más allá de la herramienta que sea seleccionada para
tal fin, porque los beneficios son dignos de tener en cuenta: reducción de riesgos de despliegue, mas
flexibilidad al cambio, progreso creı́ble, feedback con el cliente, más tiempo para resolver errores.
Deberı́amos hacer automatización sin importar que metodologı́a sea la que adoptemos, si no estamos
capacitados para aplicarla, debemos comenzar a hacerlo.
Pregunta 5, nos enfoca nuevamente en el equipo. Cuando el equipo es nuevo puede ser algo
bueno o algo no dirı́a malo pero quizás más desafiante. Por un lado si es nuevo hay que conocerse
y aprender a trabajar juntos, la parte buena serı́a que no están .acostumbrados.a trabajar de una
manera, y serı́a mucho más fácil si todos arrancaran desde el inicio con TDD o la metodologı́a
elegida, tengan o no experiencia previa. Si en el equipo hay varios miembros también es relevante,
es mucho más fácil llegar a un acuerdo entre 3 personas que llegar aun acuerdo en una reunión
entre 15 personas.
La pregunta del punto 6 nos acerca a las metodologı́as ágiles. Si el equipo (sea nuevo o

C.U. Marı́a Lorena Garcı́a TDD 97


Capı́tulo 5. Guı́a práctica

no) tiene experiencia en metodologı́as ágiles es un punto a favor en cuanto al aprendizaje, los
preconceptos podrı́an interferir, pero los paradigmas actuales ya vienen enfocados en la aplicación
de metodologı́as ágiles, lo vemos en la vida laboral cotidiana. La sociedad se ve abrumada con
la cantidad de información y estı́mulos que recibe por los medios digitales, tienes infinidad de
herramientas para aplicar metodologı́as ágiles (no necesariamente en desarrollo de software), y
necesitas aplicarlas a veces para sobrevivir en el trabajo diario.
En la pregunta 7 nos lleva a pensar en el miembro quizás más importante del equipo: el cliente.
Estamos hablando de TDD una metodologı́a ágil como algunos prefieren considerarla o práctica
ágil por otros, pero en lo que si están de acuerdo es que es ”ágil”. Si nos vamos por el camino de
que es una metodologı́a ágil, el manifiesto ágil, en el primero de sus postulados dice Ïndividuos e
interacciones sobre procesos y herramientas..Este valor inspira uno de 12 postulados donde tenemos
:”La prioridad es satisfacer al cliente mediante tempranas y continuas entregas de software que
le aporte un valor. Un proceso es ágil si a las pocas semanas de empezar ya entrega software
que funcione aunque sea rudimentario. El cliente decide si pone en marcha dicho software con la
funcionalidad que ahora le proporciona o simplemente lo revisa e informa de posibles cambios a
realizar.”. Ahora si la vemos como una práctica ágil, estarı́amos yendo por el mismo camino. La
conclusión a esta pregunta es obvia, si aplicamos una metodologı́a ágil o práctica ágil, el cliente es
un ingrediente esencial en la receta, tiene que estar en ella, y ser parte de ella lo más continuamente
posible.

5.2. Tipos de test


No existe una nomenclatura de tests que sea clara, las convenciones de a que denominar tests
depende de cada equipo, de que convención se adopta. Por ejemplo los aspectos para la denominación
de los mismos pueden ser a quien pertenece el test. Existen muchas nomeclaturas, algunas tan
extensas. Todo depende de la comunidad, Carlos Ble[12] sugiere que la comunidad de los que
practican TDD tengan sus propios términos, diferente a los que hacen testing.
Un mismo test puede ser de varios tipos, sin embargo es conveniente que tener una idea de cómo
es cada tipo de test, según las convenciones que se hayan elegido, para ser coherentes a la hora de
escribirlos.
Cuando se programa un test hay que estar convencido por qué se lo escribe y qué se está pro-
bando. Es importante tener claro qué aserción/es se usarán y por qué lo hacemos de esa manera.
Si no se consigue darle un porque y un nombre a lo que se hace tal vez no se deberı́a hacer. Las
razones a que no sepa determinar qué tipo de test se programará pueden ser que no se tenga claro el
diseño que se quiere, no se esté probando lo que corresponde, o quizás se escriben tests por escribir,
más de los necesarios.
En el ámbito de TDD no se habla de test desde el aspecto de la visibilidad como lo son los test
de caja blanca y caja negra. Se usan otros términos, aunque se tiene entendido que un test de caja
negra podrı́a coincidir con un test unitario basado en el estado. Y un test de caja blanca podrı́a

C.U. Marı́a Lorena Garcı́a TDD 98


Capı́tulo 5. Guı́a práctica

entenderse como un test unitario basado en la interacción[12].


En el siguiente apartado se verá los términos más comunes dentro de la comunidad TDD y sus
significados.
Dijimos que hay denominaciones de tipos test desde el punto de vista de a quien pertenecen,
estos se pueden dividir entre los tests de los desarrolladores y los tests del cliente. Esto lleva a
ATDD, donde el cliente escribe los ”tests de aceptación”, y en TDD se parte de tests de aceptación
de modo que se conecta lo que el cliente ”quiereçon lo que el software deberı́a hacer, se podrı́a decir
que se escribe ”primero”los tests.
Cuando se escribe el código que ejecutará el tests, y este no falla, el cliente estarı́a aceptando
el resultado. Lo que puede llegar a ser confuso, un cliente puede resistirse a decir que .acepta”(por
muchos motivos) esa parte del producto, por eso otros autores prefieren llamarlos tests del cliente,
como Charlie Poole1 .

Figura 5.1: Tipos de Tests[12]

1 Charlie Poole es un desarrollador de software neoyorquino con más de 30 años de experiencia que está considerado

un experto mundial en el desarrollo guiado por pruebas (TTD) e involucrado muy activamente en el proyecto NUnit,
un framework de pruebas unitarias para código de la familia .NET.

C.U. Marı́a Lorena Garcı́a TDD 99


Capı́tulo 5. Guı́a práctica

5.2.1. Test unitarios

Son los más importantes en TDD, incluso son la causa de que muchos confundan TDD con
testing, pero son necesarios.
Todo test unitario debe ser rápido, atómico, inocuo e independiente (F.I.R.S.T)2 , sino cumple
con estas cuatro premisas no es un test unitario[12].
Un test tiene que ser rápido por que no se tendrı́a un feedback inmediato cada vez que se
escribe un test unitario. Lo que implicarı́a que el proceso de aprendizaje del dominio del problema
no marchará bien, también será mucho más probable que ocurra un ”desliz el desarrollador escriba
2

código antes del test. Se ejecutan muchos de ellos todo el tiempo. Tiene que ser inocuo para no
alterar el estado3 del sistema, atómico porque debe probar la mı́nima cantidad de funcionalidad
posible y por último independiente porque no debe depender de otros para su existo o fracaso.
.Esto es, probará un solo comportamiento de un método de una clase. El mismo método pue-
de presentar distintas respuestas ante distintas entradas o distinto contexto. El test unitario se
ocupará exclusivamente de uno de esos comportamientos, es decir, de un único camino de ejecu-
ción”(Carlos Ble,2010,p74)[12].
Se dice que un test unitario tiene ”menor granularidad çuando la llamada al método provoca
que internamente se invoque a otros, se dice que es menos fino [12].
Al ser un test atómico evita tener que usar un debugger4 para encontrar el error en el código que
se está probando puesto que encontrar la causa será más sencillo. El ser estrictos con la atomicidad
de un test puede generar que se tenga que abusar de los dobles de prueba5 .
Para validar la ejecución de un test unitario existen dos formas, validar el estado y validar la
interacción o comportamiento.

5.2.2. Test de aceptación

Se ha hablado de ellos en el capı́tulo 3 cuando se vio ATDD, un test de aceptación es un .ejemplo


escrito.en el lenguaje del cliente que no puede ser ejecutado.
Se vio también la importancia de ATDD (simplificando mucho TDD + requisitos de aceptación),
por que en ella apreciamos a TDD como una metodologı́a ágil y se la puede relacionar a otras como
SCRUM y XP, por que todas parten de una lista de requisitos de aceptación.
También se puede incluir atributos de calidad en los tests de aceptación que no necesariamente
están en las historias de usuario.
2 F.I.R.S.T - Acrónimo, las caracterı́sticas de los tests unitarios también se agrupan bajo estás siglas que encajan

bien: Fast(rápido), Independent(independiente), Repeatable (inocuo), Small (atómico) y Transparent(transparente)


quiere decir que el test debe comunicar perfectamente la intención del autor.
3 No altera la base de datos, ni envı́a emails ni crea ficheros, ni los borra, etc.
4 Un depurador, es un programa usado para probar y depurar (eliminar) los errores de otros programas.
5 ”La expresión “doble” se usa en el mismo sentido de los actores “dobles” en las pelı́culas de acción, ya que se

hace pasar por un colaborador del ćodigo a probar cuando en realidad no es la entidad que dice ser”(Carlos Ble,
2010,p88).

C.U. Marı́a Lorena Garcı́a TDD 100


Capı́tulo 5. Guı́a práctica

Los tests de carga6 y de rendimiento7 son de aceptación cuando el cliente los considera ası́.

5.2.3. Test funcionales


Todos los tests son funcionales, puesto que todos ejercitan alguna función del código a probar.
Un test funcional es un subconjunto de los tests de aceptación porque estos comprueban una regla
de negocio, pero no todos los test de aceptación tienen porque ser funcional, por ejemplo cuando
un test de aceptación es la capacidad de respuesta de una aplicación.

5.2.4. Test de integración


Se basan en lo que debe hacer el sistema, se prueban componentes, una porción de software
que cumple con algún requerimiento que debe cumplirse. Se pueden ver como tests de sistema
pequeños, tienen un aspecto parecido a los tests unitarios, sólo que estos no son atómicos y pueden
romper otras reglas más. Integran partes del sistema, pueden escribir y leer de base de datos para
comprobar que, efectivamente, la lógica de negocio entiende datos reales. Es el complemento a los
tests unitarios. Por tanto son de granularidad más gruesa. El número de tests de integración tiende
a ser menor que el número de tests unitarios.
Por motivos de productividad es conveniente que traten de ser inocuos y rápidos. Para lograr
esto hay herramientas que generan unas bases de datos temporales, o también se puede utilizar
script que crean y destruyen bases de datos con datos de prueba.
Hay que agrupar en suites los tests, por un lado los unitarios y por otro los de integración para
poderlos ejecutar por separado.

5.2.5. Test de sistema


Son los test que integran varias partes del sistema, incluso se puede probar toda la aplicación
o varias funcionalidades de la misma juntas. Todos ellos se comportan de manera similar y buscan
emular el comportamiento de los usuarios del sistema[12].

5.2.6. Objetos simulados


Cuando hablamos de integración tenemos el problema a veces de que un módulo con el cual otro
deberá interactuar aún no esta implementado, la solución simple planteada es construir módulos
ficticios o mocks y/o stubs8 . De está idea también nace la de crear objetos ficticios que devuelvan
valores o tengan un comportamiento limitado, como ”dobles”de un objeto que luego será imple-
mentado, que sirvan solo para probar.
6 Una prueba de carga se realiza generalmente para observar el comportamiento de una aplicación bajo una

cantidad de peticiones esperada


7 En las pruebas de rendimiento el equipo de pruebas se centra en la velocidad con la que el software bajo pruebas

realiza una tarea en condiciones particulares. La perspectiva en la que se realizan es la de determinar lo rápido y
eficiente en que se realiza una tarea en el sistema
8 Mocks con menor potencia[12]

C.U. Marı́a Lorena Garcı́a TDD 101


Capı́tulo 5. Guı́a práctica

Pero antes de decidir a usar objetos ficticios o mocks hay que pensarlo dos veces, puede resultar
difı́cil de leer un código lleno de mocks. A veces no se necesitan usar, sino que al test se puede
partir en varios test y/o reescribir una parte del código a comprobar.
Martin Fowler publicó un artı́culo que habla de los mocks “Los mocks no son stubs”(Mocks
Aren’t Stubs), donde habla de los distintos dobles, donde se extrae el siguiente listado de tipos de
doble[36]:

1. Dummy: se pasa como argumento, se usan para llenar listas de argumentos, son ficticios.

2. Fake: tiene una implementación que realmente funciona pero, por lo general, toma algún atajo
o cortocircuito que le hace inapropiado para producción (como una base de datos en memoria
por ejemplo).

3. Stub: son los que reemplazan a objetos reales del sistema, generalmente para generar entradas
de datos.

4. Mock: objeto preprogramado con expectativas que conforman la especificación de cómo se


espera que se reciban las llamadas.

5.3. Métodos prácticos de refactorización.


La refactorización es un proceso que debe darse por separado, que se realiza en TDD luego
de haber comprobado que el código recién incorporado hace pasar a las pruebas, es un proceso
unitario, donde se debe llevar a cabo la ejecución de las pruebas de manera constante, deben ser
rápidas, se recomienda utilizar patrones reconocidos de refactorización.
Se puede hablar de dos tipos de refactorización, una simple y otra compleja. Cuando hablamos
de refactorización simple nos enfocamos en el nombre de las variables, si deben ser renombradas,
si tienen el nombre acorde a lo que representan, y si cumplen las convenciones de nomeclatura
dispuestas al inicio del desarrollo, el código tiene que verse limpio y sencillo. Lo mismo se hace
con el nombre de los métodos, tiene que ser claro y transmitir cual es su funcionalidad. Se suele
cambiar el tipo de variable interna cuando se consigue mejor claridad, y representación en los
datos. Otro tipo de refactorización en variables es cuando se evalúa la externalización de ellas. En
la refactorización compleja, se suele externalizar un método, extraer una interface, y eliminar las
sentencias de control If usando polimorfismo.
Tipos de refactorizaciones:

Composición de métodos

Desplazamiento de funcionalidad entre métodos

Organización de datos

Simplificación de expresiones condicionales

C.U. Marı́a Lorena Garcı́a TDD 102


Capı́tulo 5. Guı́a práctica

Simplificación de llamadas a métodos

Generalización

5.3.1. Composición de Métodos


Extract Method

Es uno de los métodos .Extract Method”[37] principales de refactorización, apunta a agrupar o


empaquetar código apropiadamente, que este altamente relacionado. Básicamente lo que se hace es
juntar código que debe ser apartado, el cual comparte la lógica de funcionalidad y propósito.
Un ejemplo claro es si estamos en el código que emite un reporte, como manejamos la impresión
del mismo.

1
2 public void PrintReporte {
3
4 PrintEncabezado () ;
5 /* print footer */
6 console . writeline ( this . TitleFooter ) ;
7 console . writeline ( this . SubtitleFooter ) ;
8
9 }

Claramente el código en donde se imprime el titulo y el subtitulo del pie puede ser agrupado y
extraı́do para integrar un nuevo método.

1
2 public void PrintReporte {
3
4 PrintEncabezado () ;
5 PrintFooter () ;
6
7 }
8
9 public void PrintFooter {
10
11 console . writeline ( this . TitleFooter ) ;
12 console . writeline ( this . SubtitleFooter ) ;
13 }

Los pasos para realizar este método son:

C.U. Marı́a Lorena Garcı́a TDD 103


Capı́tulo 5. Guı́a práctica

1. Crear un nuevo método, nombrarlo apropiadamente según lo que hace.

2. Copiar el código extraı́do del origen a este nuevo método

3. Testear el código extraı́do por referencias a variables locales al origen.

4. Testear el código extraı́do por variables temporales.

5. Evaluar el uso de las variables, si deben ser o son modificadas, o son de lectura.

6. Pasar las variables necesarias como parámetros al nuevo método.

7. Compilar y ejecutar.

8. Hacer el llamado al nuevo método en donde estaba el código extraı́do.

Inline Method

Ocurre cuando el cuerpo de un método es tan claro como su nombre. Suele unirse el código,
contrario al método anterior. La solución entonces es eliminar el método trasladando el cuerpo a
sus invocadores.

1
2 public int GetRating {
3
4 return ( MasdeCincoEnvios () ) ? 2:1;
5
6 }
7
8 public boolean MasdeCincoEnvios {
9
10
11 return numeroDeEnvios > 5;
12 }

1
2 public int GetRating {
3
4 return ( numeroDeEnvios > 5) ? 2:1;
5 }

C.U. Marı́a Lorena Garcı́a TDD 104


Capı́tulo 5. Guı́a práctica

Replace Temp with Query

Cuando se usa una variable temporal que es el resultado de una expresión, que además es local
y a veces suele generar métodos extensos. La solución es convertir la expresión en un método y
reemplazar su uso por la invocación correspondiente.

1
2 double totalConsumo = abono + consumoMensual ;
3
4 if ( totalConsumo > 1000)
5 return totalConsumo * 0.21;
6 else
7 return totalConsumo * 0.15;

1
2
3
4 if ( TotalConsumo () > 1000)
5 return TotalConsumo () * 0.21;
6 else
7 return TotalConsumo () * 0.15;
8
9 public double TotalConsumo () {
10
11 return abono + consumoMensual ;
12
13 }

5.3.2. Desplazamiento de funcionalidad entre métodos


Move Method

Es cuando se tiene un método que suele ser usado más por otras clases que por la clase a la que
integra. Se crea el método de cuerpo similar en la clase que más lo usa y se elimina o convierte en
una delegación el antiguo método.
Puede ocurrir cuando una clase tiene muchas responsabilidades, o cuando las clases colaboran
demasiado y existe mucho acoplamiento.
Proceso:

1. Exminar lo que debe moverse a la otra clase.

C.U. Marı́a Lorena Garcı́a TDD 105


Capı́tulo 5. Guı́a práctica

2. Evaluar dependencias con subclases y superclases.

3. Declarar el nuevo metodo en la clase destino.

4. Copiar el código del origen al destino y hacer los ajustes necesarios.

5. Compilar la clase destino.

6. Determinar el vı́nculo de la clase origen a la clase destino.

7. Convertir el código origen en un delegando

8. Compilar y testear

Extract Class

Una clase realiza muchas cosas, tiene varias responsabilidades, suele hacer el trabajo de 2. Se
soluciona creando una clase, moviendo los atributos y metodos relevantes.
Demasiados métodos, muchos datos, exceso de responsabilidades.
Proceso:

1. Decidir cómo dividir las responsabilidades de la clase

2. Crear una nueva clase que exprese esa división (tal vez deban renombrarse ambas).

3. Hacer un link desde la clase vieja a la nueva (tal vez una asociación bidireccional).

4. Usar Move Field y Move Method, y compilar luego de aplicar esas refactorizaciones.

5. Revisar las interfaces y reducirlas en lo necesario.

6. Examinar la visibilidad de la nueva clase en la clase vieja.

Inline Class

Una clase no hace gran cosa, se suele moverla a otra clase y borrarla. Es la inversa de Ex-
tract Class. En esta refactorización una clase absorve a otra pues esta última no tiene muchas
responsabilidades asociadas.

5.3.3. Organización de datos


Encapsulate Field

Existe un atributo público Hacerlo privado y crear sus accesors.

1 public string nombre ;

C.U. Marı́a Lorena Garcı́a TDD 106


Capı́tulo 5. Guı́a práctica

1
2 private string nombre ;
3
4 public string GetNombre () {
5 return nombre ;
6 }
7 public void SetNombre ( string arg ) {
8 nombre = arg ;
9 }

Replace Type Code with Subclasses

Es un conjunto de datos que en su momento no fue considerado como un objeto, se suele crear
el nuevo objeto y agregarle este conjunto de datos.

Figura 5.2: Nuevo objeto - Elaboración propia

5.3.4. Simplificación de expresiones condicionales


Introduce Null Object

Cuando se realizan comprobaciones reiteradas de valor null en un objeto, se suele reemplazar el


valor null por un objeto null.

C.U. Marı́a Lorena Garcı́a TDD 107


Capı́tulo 5. Guı́a práctica

1
2 if ( cliente == null )
3 plan = BillingPlan . basico () ;
4 else
5 plan = cliente . GetPlan (
6 }

Se crea una clase NullCliente.

1
2 public class Cliente
3
4 {
5 public void GetPlan ()
6 {
7 ....
8 }
9 }

1
2 public class NullCliente
3
4 {
5 public void GetPlan ()
6 {
7 cliente . GetPlan () ;
8 }
9 }

Introduce Parameter Object

Un conjunto de parámetros suele ir junto de forma natural, entonces reemplazar al conjunto de


parámetros por un objeto.

1
2 public class Cliente
3
4 {
5 public void CantidadFacturada ( Date Ini , Date Fin ,...)

C.U. Marı́a Lorena Garcı́a TDD 108


Capı́tulo 5. Guı́a práctica

6 {
7
8 }
9 public void CantidadPagada ( Date Ini , Date Fin ,...)
10 {
11
12 }
13 }

1
2 public class Cliente
3
4 {
5 public void CantidadFacturada ( DateRango ,...)
6 {
7
8 }
9 public void CantidadPagada ( DateRango ,...)
10 {
11
12 }
13 }
14
15 public class DateRango
16 {
17 Date Inicio ;
18 Date Fin ;
19
20 }

5.3.5. Generalización
Pull up Method

Métodos con idénticos resultados en subclases. Usualmente son consecuencia de copy+paste. La


solución es trasladar los métodos a las superclases.

Push down Method

Parte del comportamiento de una clase es relevante sólo a algunas subclases. La solución es
trasladar los métodos a las subclases

C.U. Marı́a Lorena Garcı́a TDD 109


Capı́tulo 5. Guı́a práctica

Figura 5.3: Subir método - Elaboración propia

Figura 5.4: Bajar método - Elaboración propia

C.U. Marı́a Lorena Garcı́a TDD 110


Capı́tulo 5. Guı́a práctica

Extract Subclass

Una clase tiene aspectos que son usados sólo en algunas instancias. Algunas instancias los usan,
otras no, entonces lo mejor es no mezclarlas y generar clases separadas. La solución es crear subclases
para los subconjuntos de aspectos relevantes a cierta instancias.
Proceso:

1. Definir una nueva subclase de la clase origen.

2. Proveer constructores para la nueva subclase.

3. Utilizar super con los argumentos adecuados

4. Buscar todas las invocaciones a constructores de la superclase y reemplazarlo por el cons-


tructor de la subclase si es necesario. Si la superclase ya no puede ser instanciada, declararla
abstracta.

5. Aplicar Push Down Method y Push Down Field hasta que ya no sea necesario.

6. Eliminar campos que distinguı́an entre las instancias (usualmente booleans).

7. Compilar y testear luego de cada push down.

5.4. Ejemplo práctico


Hicimos hincapié en capı́tulos anteriores que TDD está mucho más relacionado con el diseño
emergente que con las pruebas, que TDD genere una gran cantidad de pruebas se dice ser efecto
secundario positivo, pero no que sea su propósito final.
Un diseño de software combinando TDD con metodologı́as ágiles podrı́a tener las siguiente
secuencia:

1. El cliente escribe su historia de usuario.

2. Se escriben junto con el cliente los criterios de aceptación de esta historia, desglosándolos
mucho para simplificarlos todo lo posible.

3. Se escoge el criterio de aceptación más simple y se traduce en una prueba unitaria.

4. Se comprueba que esta prueba falla.

5. Se escribe el código que hace pasar la prueba.

6. Se ejecutan todas las pruebas automatizadas.

7. Se refactoriza y se limpia el código.

C.U. Marı́a Lorena Garcı́a TDD 111


Capı́tulo 5. Guı́a práctica

8. Se vuelven a pasar todas las pruebas automatizadas para comprobar que todo sigue funcio-
nando.

9. Volvemos al punto 3 con los criterios de aceptación que falten y repetimos el ciclo una y otra
vez hasta completar nuestra aplicación.

A continuación veremos con más detalle cada item.

5.4.1. Historia de usuario, criterios de aceptación


Vamos a escribir una aplicación, debemos sentarnos con el cliente para escucharle hablar sobre
su problema y hacer un primer análisis.
Una vez escuchado el discurso del cliente y habiendo decidido que es lo primero a implementar
en el primer sprint o entrega, nos disponemos a formular los criterios de aceptación para que el
cliente los valide.
Estamos aprendiendo, adquiriendo conocimiento de lo que es el dominio del problema, sabemos
que es peligroso dar por sentado cuestiones de la lógica del negocio. Debemos enfocarnos exclusiva-
mente a la funcionalidad que se requiere. De esta forma nos estamos asegurando que no estaremos
creando código que no se usará (funcionalidades futuras), nuestro código será más eficiente, de
mejor calidad.
En ATDD los tests de aceptación son frases cortas y precisas, escritas con el lenguaje del dominio
de negocio. Estas deben ser sencillas de tal forma que el cliente al verlas pueda decir si son correctas
o no. Las definimos en ejemplos, estos ayudarán a que no haya ambigüedad.
Tenemos mucho trabajo de análisis por delante, lógicamente habrá muchos ejemplos. Hay que
estar conscientes que se descubrirán nuevos requisitos de negocio cuando se este implementando
código, es lo que sucede la mayorı́a de las veces. Y estos requisitos quizás tendrán que ser validados
por el cliente, y hasta aparecerán funcionalidades que ni el cliente tenia contempladas y deberá to-
mar decisiones respecto a ellas. Hay clientes que aprovechan estás situaciones para adoptar nuevas
formas de implementar una regla de negocio, o se les ocurren mejoras. Puede ser también trabajo
del equipo sugerir algunas. ¿Cómo manejar todo esto?, lo vimos en las metodologı́as ágiles.
En esta etapa nuestro interés radica en la definición de los objetivos del proyecto en particular en
el cual trabajaremos. Todos los miembros del equipo deben tener conocimiento de estos objetivos,
y ser capaces de asimilarlos.
Un objetivo tiene que decir especı́ficamente qué es lo que se está intentando hacer, describiendo
también porque se quiere hacer. Debe ser medible9 , saber si agrega una contribución positiva a la
organización. Los objetivos relevantes son los que hacen una diferencia al negocio.Y debe estar en
un plazo definido, donde se estima que será alcanzado. Un objetivo SMART10
9 Que sea posible de cuantificar los fines y beneficios
10 Los objetivos SMART son aquellos que cumplen con los siguientes requisitos: son especı́ficos (specific), me-
dibles (measurable), alcanzables (attainable), relevantes(relevant) y con un tiempo para completarlos establecido
(time-related). Esta forma de definir objetivos ha demostrado ser la más eficaz en el entorno laboral ya que evita
incertidumbres y ofrece toda la información necesaria para que puedan ser cumplidos con celeridad.

C.U. Marı́a Lorena Garcı́a TDD 112


Capı́tulo 5. Guı́a práctica

5.4.2. Test unitarios


Este será su primer proyecto TDD, puede suceder que las decisiones de diseño que se tomen
en esta guı́a difieran de las del lector, lo cual no significa que sean inapropiadas, sino simplemente
diferentes.
Debemos abrir el IDE con el cual estemos familiarizados, y por su puesto tener instalado el
framework de tests11 , el marco de trabajo para pruebas unitarias correspondiente al lenguaje de
programación que hayamos elegido para el proyecto a desarrollar. Estos frameworks permiten crear
tests unitarios y tests de integración.
Lo primero que hay que hacer es crear dos módulos, uno para la aplicación y otro para los tests.
Por ejemplo si estamos en C# serán dos DLLS, y si estamos con PHP serán dos paquetes distintos.
Luego se escoge uno de los tests de aceptación y se empieza a pensar en una lista de elementos
que tienen que estar para llevarlo a cabo. Se hace un pequeño análisis del ejemplo, y se lo divide en
otros ejemplos más pequeños, que sean buenos candidatos a tests de desarrollo, por ejemplo tests
unitarios, ası́ empezarı́amos a hacer TDD. Estamos combinando ATDD con TDD.
Esto es un paso difı́cil, el de escribir un test, porque nunca nos enseñaron a trabajar de esta
manera, es un cambio cultural grande.
La única forma de aprender TDD es haciendo, por lo tanto para seguir esta guı́a tendremos que
arrancar con un ejemplo práctico, una historia de usuario.
En el proyecto del capı́tulo 7 se implementará parte con TDD y CI, el sistema de seguimiento de
incidentes que suele llamarse también sistema de tickets. No nos extenderemos ahora sobre lo que
se trata este sistema, para entender un poco los ejemplos de esta guı́a recomiendo leer la sección
Visión pág 124.
La particularidad de este sistema de tickets es que, los usuarios que generarán un tickets perte-
necen a una Unidad Académica o de Gestión, y que parte del numero del ticket se conforma con los
datos de la organización, por ejemplo un Nro de Ticket serı́a : EXA-02316, donde EXA = Facultad
de Cs. Exactas, 023 corresponde a un número generado automáticamente de forma consecutiva, y
”16”hace referencia al año de creación del Ticket.
Primero nos enfocaremos en crear con TDD una parte de la clase Tickets. Entonces un ticket
tendrá los siguientes datos entre otros: numero, un ID, fecha, dueño (usuario), fecha de última
modificación, estado. La creación de un ticket será nuestro primer test de aceptación.
Para la guı́a estaremos usando C# (por resultar un lenguaje conocido). Pero para la aplicación
del capı́tulo 7 por conveniencia en compatibilidad y licencia libre con frameworks y plataforma
Linux, etc. se desarrollarán ejemplos prácticos en los lenguajes Perl, Python y PHP.
Vamos por el primer test de desarrollo:

1
2 using System ;
11 NUnit, unittest o JUnit, etc

C.U. Marı́a Lorena Garcı́a TDD 113


Capı́tulo 5. Guı́a práctica

3 using Microsoft . VisualStudio . TestTools . UnitTesting ;


4 using oysTickets ; // referencia al proyecto que estamos desarrollando
5
6
7 namespace TestTickets
8 {
9 [ TestClass ]
10 public class TestTickets
11 {
12 [ TestMethod ]
13 public void ObtenerNumeroTest ()
14 {
15 Tickets ticket = new Tickets () ;
16 string numero = ticket . ObtenerNumero () ;
17 Assert . IsNotNull ( numero ) ;
18 }
19
20 }
21 }

El código no compila porque todavı́a no se ha creado la clase Tickets. Sin embargo ya estamos
diseñando; decidimos su nombre, como es el constructor, si recibe o no parámetros y el resultado
que devuelve.
En la lı́nea 3 puedes ver que estamos llamando al framework de testing de .Net . Creamos una
clase llamada TestTickets y dentro de ella un método llamado ObtenerNumeroTest. En la lı́nea 17
tenemos la aserción, como se dijo antes es un código que se usa durante el desarrollo, normalmente
una rutina o una macro, que permite que un programa se revise a medida que se ejecuta. Cuando
una afirmación es verdadera, eso significa que todo está funcionando como se esperaba. Cuando es
falso, significa que ha detectado un error inesperado en el código. En nuestro caso la aserción esta
verificando que el numero del ticket no sea nulo.
Luego escribimos el mı́nimo código para que el test unitario recién creado pase (debe compilar
para pasar).

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets

C.U. Marı́a Lorena Garcı́a TDD 114


Capı́tulo 5. Guı́a práctica

9 {
10 public string ObtenerNumero ()
11 {
12 return " EXA -001/17 " ;
13 }
14 }
15 }

El código quedo lo mas simple posible. Ahora nuestro primer test pasa. Tal vez no tenga un
buen diseño, podrı́amos haber pensando directamente en hacer el test de la función que crea el
numero de tickets, o quizás la función ObtenerNumero() de la clase Tickets no sea necesaria.
¿Qué esta ocurriendo entonces?, porque me hago tantas preguntas, estamos diseñando y anali-
zando, pensando que funciones se necesitarán. Tal vez debamos volver a nuestro test de aceptación
y ver si una funcionalidad indicada serı́a ObtenerNumero. Otra forma de encarar el diseño podrı́a
haber sido en pensar en la clase Tickets y todos los atributos que deberı́a tener.
Ya comprobado que pasa el test, busco que refactorizar, no encuentro mucho, quizás el nombre
del método ObtenerNumero() no me convenza, esto puede ser algo para refactorizar, poner nombres
indicados.
Un buen nombre para un método es importante, porque con él podemos saber que hace, cual es
su propósito, y además detectar cuando necesita ser refactorizado si vemos código que no deberı́a
estar ahı́.
El código que tenemos hasta ahora es bastante simple. Justo es el momento en cuando uno
tiende a añadir más código, se me ocurre que el número de ticket puede ser un atributo y estoy
tentado a implementar esto. Pero no puedo añadir ninguna funcionalidad más, sin antes crear un
test nuevo.

1 [ TestMethod ]
2 public void CrearTicketTest ()
3 {
4 Tickets ticket = new Tickets () ;
5 Assert . IsTrue (! string . IsNullOrEmpty ( ticket . Numero ) ) ;
6 }

El test unitario CrearTicketTest hace que mi proyecto no compile, no tengo el atributo ”Numero.en
la clase Tickets, tengo que crearlo. Un criterio de aceptación serı́a que un ticket tenga un número
y este nunca pueda ser nulo o vació. El test unitario para esto es el anterior.
Este es el error que obtuvimos ”... ’Tickets’does not contain a definition for Ñumeroánd no
extension method Ñumeroáccepting a first argument of type ’Tickets’could be found”
Solucionando el error:

C.U. Marı́a Lorena Garcı́a TDD 115


Capı́tulo 5. Guı́a práctica

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets
9 {
10 public string Numero = string . Empty ;
11
12 public string ObtenerNumero ()
13 {
14 return " EXA -001/17 " ;
15 }
16 }
17 }

El test no pasa (porque aún esta vació el número del ticket) todavı́a aunque el proyecto ya
compila. Tenemos que hacer pasar el test. Entonces seguimos agregando el código necesario.

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets
9 {
10 public string Numero = string . Empty ;
11
12 public Tickets ()
13 {
14 Numero = " EXA -001/17 " ;
15 }
16 public string ObtenerNumero ()
17 {
18 return " EXA -001/17 " ;
19 }
20 }

C.U. Marı́a Lorena Garcı́a TDD 116


Capı́tulo 5. Guı́a práctica

21 }

Vamos a mirar el código y sin cambiar el comportamiento refactorizamos. Buscamos eliminar


código duplicado, o incluso escribir nuevo código pero sin cambiar la funcionalidad que tengo hasta
ahora, tampoco añadir una nueva.
Modificamos la función ObtenerNumero() para que use el atributo Numero directamente.

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets
9 {
10 public string Numero = string . Empty ;
11
12 public Tickets ()
13 {
14 Numero = " EXA -001/17 " ;
15 }
16 public string ObtenerNumero ()
17 {
18 return Numero ;
19 }
20 }
21 }

Lo que hicimos fue en el constructor de la clase darle un valor a Numero, y que la función
ObtenerNumero() devuelva el atributo.
Vamos a ver un caso mas. Los tickets tienen estado, pueden ser Nuevos, Aceptados, En Proceso,
Resuelto y quizás algún otro estado que todavı́a no estoy viendo. Haremos un test para la función
que nos devuelve el estado.

1 using System ;
2 using Microsoft . VisualStudio . TestTools . UnitTesting ;
3 using oysTickets ; // referencia al proyecto que estamos desarrollando
4
5

C.U. Marı́a Lorena Garcı́a TDD 117


Capı́tulo 5. Guı́a práctica

6 namespace TestTickets
7 {
8 [ TestClass ]
9 public class TestTickets
10 {
11 [ TestMethod ]
12 public void CrearTicketTest ()
13 {
14 Tickets ticket = new Tickets () ;
15 Assert . IsTrue (! string . IsNullOrEmpty ( ticket . Numero ) ) ;
16 }
17
18 [ TestMethod ]
19 public void ObtenerNumeroTest ()
20 {
21 Tickets ticket = new Tickets () ;
22 string numero = ticket . ObtenerNumero () ;
23 Assert . IsNotNull ( numero ) ;
24 }
25
26 [ TestMethod ]
27 public void ObtenerEstadoTest ()
28 {
29 Tickets ticket = new Tickets () ;
30 string estado = ticket . ObtenerEstado () ;
31 Assert . IsTrue (! string . IsNullOrEmpty ( estado ) ) ;
32 }
33 }
34 }

Nuevamente nuestro proyecto de test no compila, no existe el método ObtenerEstado en la clase


Tickets.

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets
9 {

C.U. Marı́a Lorena Garcı́a TDD 118


Capı́tulo 5. Guı́a práctica

10 public string Numero = string . Empty ;


11
12 public Tickets ()
13 {
14 Numero = " EXA -001/17 " ;
15 }
16 public string ObtenerNumero ()
17 {
18 return Numero ;
19 }
20 public string ObtenerEstado ()
21 {
22 return " Nuevo " ;
23 }
24 }
25 }

Los ejemplos planteados son para tener una idea de como empezar, hay muchas preguntas que
uno puede ir haciéndose a medida que desarrolla con TDD, tener la incertidumbre de como plantear
un test cuando ya ha pensado un diseño. Por ejemplo el valor del estado de un ticket podrı́a ser
una constante de una clase enums.
Me parece que la pregunta de como hacer un test unitario y hacer TDD para implementar
una funcionalidad te la harás muchas veces. Pero a medida que avances tendrás resuelto varias
situaciones de como plantear distintos casos.

1 using System ;
2 using Microsoft . VisualStudio . TestTools . UnitTesting ;
3 using oysTickets ; // referencia al proyecto que estamos desarrollando
4
5
6 namespace TestTickets
7 {
8 [ TestClass ]
9 public class TestTickets
10 {
11 [ TestMethod ]
12 public void CrearTicketTest ()
13 {
14 Tickets ticket = new Tickets () ;
15 Assert . IsTrue (! string . IsNullOrEmpty ( ticket . Numero ) ) ;
16 }

C.U. Marı́a Lorena Garcı́a TDD 119


Capı́tulo 5. Guı́a práctica

17
18 [ TestMethod ]
19 public void ObtenerNumeroTest ()
20 {
21 Tickets ticket = new Tickets () ;
22 string numero = ticket . ObtenerNumero () ;
23 Assert . IsNotNull ( numero ) ;
24 }
25
26 [ TestMethod ]
27 public void ObtenerEstadoTest ()
28 {
29 Tickets ticket = new Tickets () ;
30 string estado = ticket . ObtenerEstado () ;
31 Assert . IsTrue (! string . IsNullOrEmpty ( estado ) ) ;
32 }
33
34 [ TestMethod ]
35 public void EstadoEsValidoTest ()
36 {
37 Tickets ticket = new Tickets () ;
38 Assert . IsTrue (( Enum . IsDefined ( typeof ( Tickets . EstadosTicket ) ,
ticket . ObtenerEstado () ) )
);
39 }
40 }
41 }}

No compila, ahora vamos a crear las constantes enum en la clase Tickets.

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets
9 {
10 public string Numero = string . Empty ;
11
12 public enum EstadosTicket

C.U. Marı́a Lorena Garcı́a TDD 120


Capı́tulo 5. Guı́a práctica

13 {
14 Nuevo = 1 ,
15 Aceptado = 2 ,
16 EnProceso = 3 ,
17 Rechazado = 4 ,
18 Terminado = 5 ,
19 Pendiente = 6
20 }
21
22 public Tickets ()
23 {
24 Numero = " EXA -001/17 " ;
25 }
26 public string ObtenerNumero ()
27 {
28 return Numero ;
29 }
30 public string ObtenerEstado ()
31 {
32 return " Nuevo " ;
33 }
34 }
35 }

Nuestro test EstadoEsValidoTest no falla por que nuestro método ObtenerEstado devuelve ”Nue-
vo”que si esta como constante en nuestra clase enum. Ahora refactorizamos.

1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5
6 namespace oysTickets
7 {
8 public class Tickets
9 {
10 public string Numero = string . Empty ;
11
12 public enum EstadosTicket
13 {
14 Nuevo = 1 ,
15 Aceptado = 2 ,

C.U. Marı́a Lorena Garcı́a TDD 121


Capı́tulo 5. Guı́a práctica

16 EnProceso = 3 ,
17 Rechazado = 4 ,
18 Terminado = 5 ,
19 Pendiente = 6
20 }
21
22 public Tickets ()
23 {
24 Numero = " EXA -001/17 " ;
25 }
26 public string ObtenerNumero ()
27 {
28 return Numero ;
29 }
30 public string ObtenerEstado ()
31 {
32 return EstadosTicket . Nuevo . ToString () ;
33 }
34 }
35 }

No hemos podido refactorizar mucho. Creo que sigue agregar a Estado como un atributo de
la clase Tickets y este debe ser del tipo enum definido. Y ası́ ir pensando cada test unitario para
cada atributo de nuestra clase. Aquı́ terminamos con los ejemplos. Te invito a ver el código que se
desarrollará en el capı́tulo 7.
A continuación una captura del entorno de trabajo con el IDE Visual Studio 2015. En la figura
podrás ver la lista de los test que fuimos desarrollando y el icono de color verde de que han pasado!.

C.U. Marı́a Lorena Garcı́a TDD 122


Capı́tulo 5. Guı́a práctica

Figura 5.5: Visual Studio - oysTickets con test desarrollados

C.U. Marı́a Lorena Garcı́a TDD 123


Capı́tulo 6

Sistema de Seguimiento de
Incidentes (Tickets)

6.1. Visión
Sistema de Seguimiento de Incidentes comúnmente llamado ”Sistema de Tickets”, la particulari-
dad de este sistema es que será para una Dependencia de la Universidad Nacional de Salta llamada
Dirección de Obras y Servicios. Esta Dirección tiene a su cargo la inspección de los Servicios de: hi-
giene de espacios exteriores, interiores, mantenimiento de espacios verdes, luminarias y los servicios
en complejo universitario.
La idea con este Sistema de Tickets es poder identificar, controlar y llevar un seguimiento a
las tareas (pedidos) u ordenes de trabajo, que suelen ser de un cierta cantidad que ingresan a la
Dirección. De acuerdo a la temática de cada orden de trabajo puede surgir distintos tratamientos,
dependiendo de la escala y tipo de pedido del cual se trate. Según corresponda se deriva a una
área, las cuales pueden ser Servicios Generales, Dpto de Seguridad, Construcción y Mantenimiento,
y Dirección de Estudios y Proyectos. En Servicios Generales tenemos los talleres como ser el de
Carpinterı́a, Electricista, etc., a todos ellos los llamaremos departamentos.
Los pedidos que ingresan pasan por un criterio de derivación, por que algunos llevan asociado un
tiempo de investigación, relevamiento, documentación e incluso comunicación con los interesados
para poder ofrecer la mejor solución posible.
Algunos de los pedidos pueden terminar incluso en una obra de construcción o de mantenimiento.
Los proyectos que se convierten en Obra, se le asigna un numero de obra que los permite identificar.
El criterio histórico era asignar un número de obra de forma secuencial. El problema de esta forma
de asignación es no poder identificar de forma fácil en el numero dado a que unidad académica e
incluso a que edificio de gestión se trata.
Por lo expuesto, y a fines de comenzar a tomar acciones tendientes a mejorar la calidad de

124
Capı́tulo 6. Sistema de Seguimiento de Incidentes (Tickets)

los procesos internos de la Dirección en cuanto al manejo de la información, documentación se


consideró necesario realizar un cambio importante en la forma en que se viene trabajando y dar
una identificación a las tareas y obras.
Los cambios planteados son los siguientes:

1. Implementar un sistema de numeración interno.

2. Desarrollar un sistema web que utilice este nuevo sistema de numeración con la idea de
identificar, controlar y monitorear los pedidos que ingresan a la Dirección.

Para el ı́tem 1, se propone :

Crear un formato alfanumérico de modo de permitir la identificación intuitiva la procedencia


del pedido tanto de una unidad académica o de gestión, con un numero de pedido y año.

El formato estará constituido por los siguientes datos:

1. Un string de 3 letras para identificar la unidad académica o de gestión que solicita el


pedido. Ejemplo : HUM , que corresponde a la facultad de Humanidades
2. Un número de acuerdo al orden secuencial de ingreso. Por ejemplo: 020. Corresponde al
pedido 20.
3. Año en que ingresa el pedido, se tomarán los últimos 2 (dos) dı́gitos. Ejemplo : 17,
año 2017. Ejemplo nomenclatura completa: ING-017-001 (unidad académica o de
gestión)-(terminación del año actual)-(numeración secuencial).

Para el ı́tem 2 se propone:

• Seguimiento de los pedidos. Utilizando los atributos de estados, procedencia, destino,


depositario.
• Módulo de derivación a la área correspondiente, con asignación de responsable y paso
con autorización.
• Búsquedas por unidad académica o de gestión, estados, fecha.
• Reporte de estadı́sticas sobre ingresos, permanencias y estados.

6.2. Elección y trazabilidad entre herramientas


Las herramientas para CI analizadas en la sección 4.3 en su conjunto aportan como beneficio
principal la reducción del riesgo, además de otros como la predicción del tiempo de integración,
puesto que es algo que se realiza continuamente. La conversión de procesos repetitivos a procesos
automatizados minimizando la posibilidad de errores humanos. Contribuyen al conocimiento del
proceso de integración, convirtiéndolo en un proceso confiable, probado, versionado y repetible.

C.U. Marı́a Lorena Garcı́a TDD 125


Capı́tulo 6. Sistema de Seguimiento de Incidentes (Tickets)

Independencia con personas concretas para llevar a cabo el despliegue. Como resultado la taza de
éxito del proyecto puede verse incrementada.
En resumen muchos de los beneficios obtenidos al utilizar las herramientas son los principios y
prácticas perseguidos por la comunidad ágil.
Tras el estudio de las herramientas para el presente trabajo se han elegido unas en particular, la
primera caracterı́stica buscada es crear un entorno de desarrollo de software open-source, las otras
caracterı́sticas fueron facilidad de uso y conocimiento previo de las mismas.

Git por resultar conocido previamente y ser compatible con los entornos de desarrollos cono-
cido NetBeans.

Redmine,la elección es justificada por ser una herramienta open-source y fácil de usar.

Jenkins, por ser open-source y tener caracterı́sticas intuitivas.

6.2.1. Desarrollo de módulo de Departamento


Para el presente proyecto de tesis como ejemplo práctico se ha desarrollado el módulo de De-
partamentos, el cual contiene los métodos para ingresar, modificar y buscar un departamento de la
Dirección General de Obras y Servicios.
Existen talleres de Carpinterı́a, Herrerı́a, Sanitarista-GAS, Electricidad, Telefonı́a e Internet,
Mantenimiento y Estudios y Proyectos.
De acuerdo al pedido u orden de trabajo se deriva al departamento correspondiente, donde cada
uno de ellos tiene un responsable quién podra delegar el pedido a un agente de la Dirección.
Ahora paso a relatar como fue mi experiencia desarrollando con TDD.
Una vez teniendo claro las necesidades de la Dirección en cuanto a resolver la problemática de
las solicitud u orden de trabajo que les llega desde toda la Universidad. Se procedı́ a hacer un mapa
conceptual de todo el sistema. El mapa conceptual es una técnica usada para la representación
gráfica del conocimiento que me permite tener la red de conceptos.
Una vez que tenia el mapa conceptual, y teniendo claro que empezarı́a con el modulo de manejo
de Departamentos, necesite tener claro las funcionalidades que debı́a desarrollar, principalmente las
que me aprobarı́a mi cliente. Usando la herramienta Redmine cree las funcionalidades necesarias
para el módulo elegido.
A partir del mapa conceptual y con lo que tenia como funcionalidades básicas requeridas para
el modulo de departamentos procedi a utilizar TDD.
Concluyendo que se necesitaba las historias de usuarios, los criterios de aceptación para iniciar el
desarrollo, y una visión global de las entidades que intervendrán en el sistema. Una vez teniendo que
hay que implementar se dividen los criterios de aceptación, se separan los que lógicamente deberı́an
ir primero. Si estarı́a en un equipo de desarrollo este consenso se darı́a con todos los miembros, se
determinarı́an que criterios entrarı́an para el primer sprint o el primer prototipo.
Mis criterios de aceptación básicos para el caso práctico son:

C.U. Marı́a Lorena Garcı́a TDD 126


Capı́tulo 6. Sistema de Seguimiento de Incidentes (Tickets)

Poder crear un departamento con sus datos relevantes para la registración : Nombre, si es
publico (Para toda la Universidad o Interno), Responsable, Email para Respuesta automática,
fecha de creación, fecha de modificación.

Poder seleccionar un departamento y obtener cuales son sus datos,

Modificar los datos de un Departamento.

Estos tres criterios de aceptación fueron desarrollados con TDD puro a modo de ejemplo en
PHP, Python y Perl usando Postgresql como base de datos. El código fuente de los ejemplos esta
adjunto a este proyecto.

6.2.2. Herramientas utilizadas


Librerias de Testing propias de cada lenguaje, PHPUnit para PHP y el módulo Test para
Perl, unittest para Python.

Postgresql para la base de datos.

Git para el control de versiones

Jenkins para el despliegue.

Redmine para la organización de las tareas.

6.2.3. Conclusión
La principal dificultad que tuve al empezar con TDD fue como formular el primer test, el cual
me orientará a la creación de la clase Departamentos y como trabajarı́a ella. Lo que hice fue, crear
un test que verificará la existencia de la clase, y otro la de sus atributos.En otros tests los métodos
necesarios de forma de ir implementando.
Al hacer refactorización mi código, surge una nueva clase a la que llame SqlLProvider, ya que
los métodos de acceso a la base de datos iban a ser los mismos para todas las clases del sistema.
Las dificultades que tuve fueron, en principio como plasmar en un test el diseño que querı́a para
mi clase, y la falta de seguridad en cuanto a si estaba haciendo la cantidad de test suficientes, o si
mi test debı́a ”meterse”más en el código del método que necesitaba implementar.
En conclusión me costo al principio, debı́a frenarme y no tentarme con las ganas de seguir
agregando código, detenerme a hacer el tests primero correspondiente o mejorar en el que estaba.
Creo que TDD es algo interesante y puede sacarse mucho provecho del hecho que vas teniendo todo
tu código probado, la seguridad que obtenes de ello, solo que cuesta acostumbrarse, y hasta a veces
es frustrante.

C.U. Marı́a Lorena Garcı́a TDD 127


Capı́tulo 7

Conclusiones

Para algunos autores TDD es una práctica de programación, otros que profundizan más los
pasos del algoritmo de TDD llegan a llamarla metodologı́a ágil de diseño.
A mi modo de verlo, si la vemos como una práctica de desarrollo, es demasiado compleja de llevar
al pie de la letra, además de involucrar en su utilización muchas decisiones de diseño. A medida que
se desarrolla los test, uno tiene que hacerse preguntas de como modularizarás, que nombre darás
a tus clases, que atributos tendrán, que convenciones irás utilizando,¿és necesario implementar tal
función?, decisiones que se toman en el análisis, y en ese momento estás codificando y diseñando.
Además de otros factores que hay que tener en cuenta cómo cuando se refactoriza, usar patrones
de diseño, forzar aún más la reutilización de código, mantener la cohesión, medir el acoplamiento,
etc. Dirı́a que le queda chica la palabra ”práctica”.
Üna metodologı́a me da recetas”1 , TDD por si solo no da recetas, solo nos dice que hacer
en la siguiente interacción de su algoritmo, pero cada paso en el algoritmo trae un montón de
decisiones aparejadas como mencionamos anteriormente. Y si consideramos las variantes de TDD,
ATDD, BDD, etc. y Refactorización, se juntan muchas más recetas, herramientas y métodos, pero
TDD puro no es una metodologı́a ágil. Para considerarla metodologı́a ágil deberı́a darnos métodos
precisos para la parte de análisis, como para las otras etapas del desarrollo del software.
Podrı́amos decir que TDD es un paradigma de programación porque el conjunto de pasos que
tiene me da una forma de programar, una idea a seguir. Programar con TDD es totalmente diferente
a la forma que la mayorı́a viene acostumbrados.
En mi opinión seguir hacer TDD no te asegura calidad en tu software, hay que saber programar,
es fundamental entender y tener claro el dominio del problema, no puedes avanzar si no tienes claro
que tienes que hacer y aún teniéndolo claro puedes no saber plasmarlo, esta observación sirve para
todas las metodologı́as.
Hacer TDD se vuelve complicado cuando descnonoces el dominio del problema, o si no estas
acostumbrado al lenguaje de programación que usarás, si debes hacer TDD también sin tener un
1 Adriana Binda, 2016

128
Capı́tulo 7. Conclusiones

simple bosquejo o mapa conceptual del dominio del problema, si no tienes planes de como quieres
que funcione la aplicación en un futuro, por ejemplo agregar manejo de errores, cosas que despues
pueden llevar tiempo implementar si no las pensaste en un principio.
Además que usar TDD implica tener conocimiento en las herramientas de testing (estar acos-
tumbrado a hacer test), hay que prácticar para crear buenos test, podes hacer muchos de ellos y
no avanzar en buenos diseños. Se puede mejorar si se tiene idea de patrones de diseño, los métodos
de refactorización, saber identificar y buscar los ”malos olores.en el código. Creo que aún sabiendo
lo necesario siempre te queda la duda si generaste buenos tests, si probaste lo necesario.
Con un plugins en Jenkins que me analiza la cobertura de código en los tests pude comprobar
que aún partiendo de test, la cobertura del código no es completa. Cuando creo un test y en él
llamó un método que deberı́a estar en una clase, solo estoy diciendo que deberı́a existir en la clase,
pero no digo nada de como deberı́a hacer su función, no puedo prediseñar como realizará su tarea,
no puedo testear su eficienta, ni evitar que haga más cosas de las que deberı́a hacer, el test solo
asegurá que el resultado tiene que ser el esperado.
Entonces que paso de TDD me ayuda en crear código de calidad?, la refactorización, pero quizas
hay que mirar más a fondo, lo que da más calidad es saber de programación, conocer a fondo el
lenguaje de programación, saber de diseño, de patrones.
Aunque TDD no te asegura calidad, creo que aporta un versión de mayor calidad de tu código
que si no lo hubieras utilizado, ya que te obliga a pensar constantemente como mejorar lo que estas
haciendo, y que no debes hacer.

C.U. Marı́a Lorena Garcı́a TDD 129


Glosario

API La interfaz de programación de aplicaciones, abreviada como API del inglés: Application Pro-
gramming Interface,1 es un conjunto de subrutinas, funciones y procedimientos (o métodos,
en la programación orientada a objetos) que ofrece cierta biblioteca para ser utilizado por
otro software como una capa de abstracción.. 29

ASD Adaptive Software Development, método ágil de desarrollo de software. Es un proceso de


desarrollo de software que surgió del trabajo rápido de desarrollo de aplicaciones de Jim
Highsmith y Sam Bayer. Reemplaza al tradicional ciclo de cascadas con una serie repetitiva
de ciclos de especulación , colaboración y aprendizaje . Este ciclo dinámico proporciona el
aprendizaje continuo y la adaptación al estado emergente del proyecto. Las caracterı́sticas
de un ciclo de vida de ASD son que está centrado en la misión, basado en caracterı́sticas,
iterativo , timeboxed , conducido por el riesgo y tolerante al cambio.. 20, 21

ATDD Story Test Driven Development, metodologı́a ágil de desarrollo. Ver capı́tulo 3.. 31

BDD Behavior-Driven Development o desarrollo guiado por el comportamiento (DGC), metodo-


logı́a ágil de desarrollo.Ver capı́tulo 3.. 32

BSD Berkeley Software Distribution ( BSD ) fue un derivado del sistema operativo Unix desarro-
llado y distribuido por el Computer Systems Research Group (CSRG) de la Universidad de
California, Berkeley , de 1977 a 1995. Hoy en dı́a el término ”BSD” se utiliza a menudo no
especı́ficamente para se refieren a cualquiera de los descendientes BSD que juntos forman una
rama de la familia de sistemas operativos tipo Unix. Los sistemas operativos derivados del
código BSD original permanecen activamente desarrollados y ampliamente utilizados.. 90

CASE Computer- Arded Software Enginnering. Ingenierı́a de software asistida por ordenador (
CASE ) es el dominio de las herramientas de software utilizadas para diseñar e implementar
aplicaciones. Las herramientas CASE son similares y se inspiraron parcialmente en las he-
rramientas de diseño asistido por computadora (CAD) utilizadas para diseñar productos de
hardware. Las herramientas CASE se utilizan para desarrollar software de alta calidad, sin
defectos y mantenible. El software CASE se asocia a menudo con métodos para el desarrollo

130
Glosario

de sistemas de información junto con herramientas automatizadas que se pueden utilizar en


el proceso de desarrollo de software . . 61

CD La entrega continua ( CD ) es un enfoque de ingenierı́a de software en el que los equipos


producen software en ciclos cortos, garantizando que el software puede ser liberado de forma
fiable en cualquier momento. Su objetivo es construir, probar y liberar software más rápido
y con mayor frecuencia. El enfoque ayuda a reducir el costo, el tiempo y el riesgo de generar
cambios al permitir más actualizaciones incrementales de las aplicaciones en producción. Un
proceso de despliegue sencillo y repetible es importante para la entrega continua.. 88

CI La Integración Continua (Continuous Integration en inglés) es un modelo informático propuesto


inicialmente por Martı́n Fowler que consiste en hacer integraciones automáticas de un pro-
yecto lo más a menudo posible para ası́ poder detectar fallos cuanto antes. Entendemos por
integración la compilación y ejecución de pruebas de todo un proyecto.. 16, 55, 83, 89

CVS Concurrent Versioning System. Ver capı́tulo 4.. 83

DDD Domain Driven Design.Diseño guiado por el dominio, metodologı́a ágil de desarrollo.Ver
capı́tulo 3.. 35

GNU GNU es un sistema operativo de tipo Unix desarrollado por y para el Proyecto GNU, y
auspiciado por la Free Software Foundation. Está formado en su totalidad por software libre,
mayoritariamente bajo términos de copyleft. GNU es el acrónimo recursivo de ”GNU’s Not
Unix” (en español: GNU no es Unix),12 nombre elegido debido a que GNU sigue un diseño
tipo Unix y se mantiene compatible con éste, pero se distingue de Unix por ser software libre
y por no contener código de Unix.. 62

GPL La Licencia Pública General de GNU o más conocida por su nombre en inglés GNU General
Public License (o simplemente sus siglas en inglés GNU GPL) es la licencia de derecho de autor
más ampliamente usada en el mundo del software libre y código abierto,6 y garantiza a los
usuarios finales (personas, organizaciones, compañı́as) la libertad de usar, estudiar, compartir
(copiar) y modificar el software. Su propósito es doble: declarar que el software cubierto
por esta licencia es libre, y protegerlo (mediante una práctica conocida como copyleft) de
intentos de apropiación que restrinjan esas libertades a nuevos usuarios cada vez que la obra
es distribuida, modificada o ampliada. Esta licencia fue creada originalmente por Richard
Stallman fundador de la Free Software Foundation (FSF) para el proyecto GNU... 62

GPLv2 Pública General GNU Versión 2. La Licencia Pública General de GNU o más conocida por
su nombre en inglés GNU General Public License (o simplemente sus siglas en inglés GNU
GPL) es la licencia de derecho de autor más ampliamente usada en el mundo del software
libre y código abierto, y garantiza a los usuarios finales (personas, organizaciones, compañı́as)
la libertad de usar, estudiar, compartir (copiar) y modificar el software. Su propósito es doble:

C.U. Marı́a Lorena Garcı́a TDD 131


Glosario

declarar que el software cubierto por esta licencia es libre, y protegerlo (mediante una práctica
conocida como copyleft) de intentos de apropiación que restrinjan esas libertades a nuevos
usuarios cada vez que la obra es distribuida, modificada o ampliada. Esta licencia fue creada
originalmente por Richard Stallman fundador de la Free Software Foundation (FSF) para el
proyecto GNU.. 87

HTTPD Demonio del servidor Apache desarrollado y mantenido por una comunidad de usuarios
bajo la supervisión de la Apache Software Foundation dentro del proyecto HTTP Server
(httpd).. 86

IDE Un entorno de desarrollo integrado o entorno de desarrollo interactivo, en inglés Integrated


Development Environment (IDE), es una aplicación informática que proporciona servicios
integrales para facilitarle al desarrollador o programador el desarrollo de software.. 29

iOS Sistema operativo móvil de la multinacional Apple Inc. Originalmente desarrollado para el
iPhone (iPhone OS), después se ha usado en dispositivos como el iPod touch y el iPad.En el
año 2015 pasó a ser de código abierto.. 89

Lean La metodologı́a de desarrollo de software lean (traducción aproximada de lean: ✭✭fino✮✮ o


✭✭esbelto✮✮) es una traducción de los principios y las prácticas de la forma de producir lean,
hacia el área del desarrollo de software. Inicialmente, originado en el Sistema de Producción
de Toyota y ahora, apoyado por una corriente que está surgiendo desde la comunidad Ágil.
Este método ofrece todo un marco teórico sólido y basado en la experiencia, para las prácticas
ágiles de gestión.. 25

macOS macOS, anteriormente denominado OS X e inicialmente Mac OS X, es un entorno opera-


tivo basado en Unix, desarrollado, comercializado y vendido por Apple Inc.. 89

NDD Desarrollo guiado por necesidades. Ver capı́tulo 3.. 42

NUnit NUnit es un framework open source de Pruebas de unidad para Microsoft .NET y Mono.
Sirve al mismo propósito que JUnit realiza en el mundo Java, y es uno de muchos en la familia
xUnit.. 33, 34

QA El aseguramiento de la calidad (se usa con frecuencia el anglicismo quality assurance) es el


conjunto de actividades planificadas y sistemáticas aplicadas en un sistema de gestión de la
calidad para que los requisitos de calidad de un producto o servicio sean satisfechos. En-
tre estas actividades se encuentran la medición sistemática, la comparación con estándares,
el seguimiento de los procesos, todas actividades asociadas con bucles de realimentación de
información. Estas actividades contribuyen a la prevención de errores, lo cual se puede con-
trastar con el control de calidad, que se centra en las salidas del proceso. Ambos conceptos
suelen utilizarse de manera conjunta.. 16

C.U. Marı́a Lorena Garcı́a TDD 132


Glosario

RAD El desarrollo rápido de aplicaciones o RAD (acrónimo en inglés de Rapid Application Deve-
lopment) es un proceso de desarrollo de software, desarrollado inicialmente por James Martin
en 1980. El método comprende el desarrollo interactivo, la construcción de prototipos y el
uso de utilidades CASE (ingenierı́a asistida por computadora). Tradicionalmente, el desarro-
llo rápido de aplicaciones tiende a englobar también la usabilidad, utilidad y la rapidez de
ejecución.. 21

RCS Revision Control System. Es una implementación en software del control de versiones que
automatiza las tareas de guardar, recuperar, registrar, identificar y mezclar versiones de ar-
chivos. RCS es útil para archivos que son modificados frecuentemente, por ejemplo programas
informáticos, documentación, gráficos de procedimientos, monografı́as y cartas. RCS también
puede ser utilizado para manejar archivos binarios, pero con eficacia y eficiencia reducidas.
Las distintas versiones son archivadas mediante la ayuda de la herramienta diff.. 84

RUP El Proceso Racional Unificado o RUP (por sus siglas en inglés de Rational Unified Process)
es un proceso de desarrollo de software desarrollado por la empresa Rational Software, actual-
mente propiedad de IBM. Junto con el Lenguaje Unificado de Modelado (UML), constituye la
metodologı́a estándar más utilizada para el análisis, diseño, implementación y documentación
de sistemas orientados a objetos.. 16

SCM Source Code Management. Un componente de gestión de configuración de software, control


de versiones, también conocido como control de revisión o control de código fuente, es la
gestión de los cambios en los documentos, programas de ordenador, grandes sitios web y otras
colecciones de información.. 83

STDD Story Test Driven Development, metodologı́a ágil de desarrollo. Ver capı́tulo 3.. 31

SUnit Un diseño de Kent Beck, implementados originalmente para Smalltalk como SUnit, pero
están ahora disponibles para muchos lenguajes de programación y plataformas.. 34

TDD Test Driven Development, desarrollo guiado por pruebas.ver Capı́tulo 3.. 5, 24

TFVC Team Foundation Version Control (TFVC) es un sistema de control de versiones centrali-
zado. Normalmente, los miembros del equipo sólo tienen una versión de cada archivo en sus
máquinas de dev. Los datos históricos se mantienen únicamente en el servidor. Las sucursales
están basadas en rutas de acceso y creadas en el servidor.. 88

UML El lenguaje unificado de modelado (UML, por sus siglas en inglés, Unified Modeling Lan-
guage) es el lenguaje de modelado de sistemas de software más conocido y utilizado en la
actualidad; está respaldado por el Object Management Group (OMG).. 16

UTDD En castellano se traducirı́a como “Desarrollo guiado por las pruebas unitarias.. 34

C.U. Marı́a Lorena Garcı́a TDD 133


Glosario

VCS Version Control System. Ver capı́tulo 4.. 83

WIP Work in Progress, trabajo en proceso, productos en proceso, o inventario en proceso son los
productos parcialmente terminados que esperan la terminación y la venta eventual o el valor
de estos artı́culos.. 23

XP La programación extrema o eXtreme Programming es una metodologı́a de desarrollo de la


ingenierı́a de software formulada por Kent Beck, autor del primer libro sobre la materia,
Extreme Programming Explained: Embrace Change (1999).. 12, 24

C.U. Marı́a Lorena Garcı́a TDD 134


Bibliografı́a

[1] Gojko Adzic. Bridging the Communication Gap: Specification by Example and Agile Acceptance
Testing. Neuri Consulting Llp, 2009. ISBN 0-9556836-1-0.

[2] Alfredo Chavez. TDD Cómo y porqué: Una guı́a para los no ini-
ciados ·. 2017. URL http://artesanos.de/software/2012/02/13/
tdd-como-y-porque-una-guia-para-los-no-iniciados/.

[3] Alicia Salamon, Francisco Coenda, Patricio Maller, Alejandra Boggio, Natalia Mira, y Sofia
Perez. La integración continua aplicada en el desarrollo de software en el ámbito cientı́fi-
co–técnico. 2014. URL http://sedici.unlp.edu.ar/handle/10915/42358.

[4] Agile Alliance. BDD Learn about Behavior Driven Development. 2015. URL https://www.
agilealliance.org/glossary/bdd/.

[5] Atlassian. Jira Software: Funcionalidad. 2017. URL https://es.atlassian.com/software/


jira/features.

[6] Basecamp. Replace all over the place with ONE place. 2017. URL https://basecamp.com.

[7] Kent Beck. Una explicación de la programación extrema: aceptar el cambio. Addison Wesley,
Madrid, 2002. ISBN 978-84-7829-055-0. OCLC: 433200877.

[8] bitbucket. Mercurial SCM. 2017. URL https://www.mercurial-scm.org/about.

[9] Bob Hartman. Why Unit Test-Driven Development is Important. 2008. URL http:
//agileforall.com/why-unit-test-driven-development-is-important/.

[10] Brian Okken. doctest introduction. 2012. URL http://pythontesting.net/framework/


doctest/doctest-introduction/.

[11] William J Brown, Hays W McCormick, y Scott W Thomas. Anti Patterns Project Management.
John Wiley & Sons, Inc., 2000.

[12] Carlos Blé Jurado. Diseño Ágil con TDD. 2010. URL http://www.carlosble.com/
downloads/disenoAgilConTdd_ebook.pdf.

135
Bibliografı́a

[13] Comunidad Avanet. Charlas en Lı́nea: Esencia y Fundamentos de TDD. 2014. URL https:
//www.youtube.com/watch?v=4t0ZxUXnwN4.

[14] Software Freedom Conservancy. Git. 2017. URL https://git-scm.com/about.

[15] Damian Cervantes Rodon. Propuesta de entorno de integración continua en


el Centro de Informatización Universitaria. (PDF Download Available). 2010.
URL https://www.researchgate.net/publication/268445965_Propuesta_de_entorno_
de_integracion_continua_en_el_Centro_de_Informatizacion_Universitaria.

[16] Dan Haywood. Introducción al diseño impulsado por el dominio. 2017. URL http://www.
methodsandtools.com/archive/archive.php?id=97.

[17] Daniel. La Integración continua: Netscape, la NASA, XP y dos mayordo-


mos. 2016. URL https://danielvillahermosa.wordpress.com/2016/01/17/
la-integracion-continua-netscape-la-nasa-xp-y-dos-mayordomos/.

[18] Dave Chaplin. Test First Programming. TechZone, 2001.

[19] David Valverde. Introducción a la Programación Extrema (XP). 2007. URL http://www.
davidvalverde.com/blog/introduccion-a-la-programacion-extrema-xp/.

[20] Ana M del Carmen Garcı́a Oterino. Aprende a implantar integración continua desde cero (I):
¿Por qué integración continua? - Javier Garzás. 2014. URL http://www.javiergarzas.com/
2014/08/implantar-integracion-continua.html.

[21] Paul M Duvall, Steve Matyas, y Andrew Glover. Continuous Integration Improving Software
Quality and Reducing Risk. Pearson Education, Inc., 2008. ISBN 978-0-321-33638-5. URL
https://www.amazon.com/Continuous-Integration-Improving-Software-Reducing/dp/
0321336380.

[22] Easy Software. Easy Redmine. 2017. URL https://www.easyredmine.com/es/faq-es/


acerca-de-software/1772-como-funcionan-redmine-y-easy-redmine.

[23] Eric Evans. Domain Driven Design: Tackling Complexity in the Heart of Software. Addison-
Wesley Professional, Boston, 1 edition edón., 2003. ISBN 978-0-321-12521-7.

[24] Moisés Carlos Fontela. Estado del arte y tendencias en Test-Driven Development. 2012.

[25] Apache Software Foundation. Caracterı́sticas de Apache Subversion. 2017. URL http://
subversion.apache.org/features.html.

[26] Francisco José Gómez y Caldito Viseas. Evaluación de la calidad de código usando TDD en
el desarrollo de la lógica de negocio de un sistema de información para un club deportivo.
2013. URL https://acceda.ulpgc.es:8443/bitstream/10553/11186/1/0693029_00000_
0000.pdf.

C.U. Marı́a Lorena Garcı́a TDD 136


Bibliografı́a

[27] Hirotaka Takeuchi y Ikujiro Nonaka. The New New Product Development Game.
1986. URL http://www.wz.uw.edu.pl/pracownicyFiles/id12540-Takeuchi,%20Nonaka%
20-%20The%20new%20product%20development%20game.pdf.

[28] James Highsmith III. Adaptive Software Development. Addison-Wesley, 2013. ISBN 978-0-
932633-40-8. URL http://www.dorsethouse.com/books/asd.html.

[29] Jean Philippe Lang. Overview - Redmine. 2017. URL http://www.redmine.org/.

[30] Jose Javier Rodrı́guez Álvarez. INVESTIGACIÓN DE LOS MÉTODOS ÁGILES PA-
RA SU IMPLANTACIÓN EN UN LABORATORIO DE SEGURIDAD ELÉCTRICA.
2013. URL https://upcommons.upc.edu/bitstream/handle/2099.1/20733/TFM_metodos%
20agiles.pdf.

[31] Kent Beck. Test-Driven Development By Example. 2002. URL http://www.eecs.yorku.


ca/course_archive/2003-04/W/3311/sectionM/case_studies/money/KentBeck_TDD_
byexample.pdf.

[32] La Fundación Apache Software. Maven Welcome to Apache Maven. 2017. URL https:
//maven.apache.org/.

[33] Michele Lanza y Radu Marinescu. Object oriented metrics in practice: using software metrics
to characterize, evaluate, and improve the design of object-oriented systems. Springer Science
& Business Media, 2007.

[34] Patricio Letelier y Ma Carmen Penadés. Métodologı́as ágiles para el desarrollo de software:
eXtreme Programming (XP). 2006. URL http://www.cyta.com.ar/ta0502/v5n2a1.htm.

[35] Liz Keogh. What is BDD? 2015. URL https://lizkeogh.com/2015/03/27/what-is-bdd/.

[36] Martin Fowler. Mocks Aren’t Stubs. 2007. URL https://martinfowler.com/articles/


mocksArentStubs.html.

[37] Martin Fowler. Refactoring. 2017. URL https://refactoring.com/.

[38] Naouel Moha. DECOR Détection et correction des défauts dans les systemes orientés objet.
Tesis Doctoral, Université des Sciences et Technologie de Lille-Lille I, 2008.

[39] Hausi A. Müller, Scott R. Tilley, y Kenny Wong. Understanding Software Systems Using
Reverse Engineering Technology Perspectives from the Rigi Project. En Proceedings of the 1993
Conference of the Centre for Advanced Studies on Collaborative Research: Software Engineering
- Volume 1, CASCON ’93, págs. 217–226. IBM Press, Toronto, Ontario, Canada, 1993. URL
http://dl.acm.org/citation.cfm?id=962289.962309.

[40] John Nosek. The Case for Collaborative Programming. Communications of the ACM, 41,
1998.

C.U. Marı́a Lorena Garcı́a TDD 137


Bibliografı́a

[41] William F Opdyke. Refactoring A program restructuring aid in designing object-oriented ap-
plication frameworks. Tesis Doctoral, PhD thesis, University of Illinois at Urbana-Champaign,
1992.

[42] OTTONIEL HERNÁNDEZ ISTUPE. Scrum, una alternativa viable para la gestión de pro-
yectos de software. Tesis Doctoral, UNIVERSIDAD RAFAEL LANDÍVAR, 2009. URL http:
//bibliod.url.edu.gt/Tesis/02/08/Hermandez-Ottoniel/Hermandez-Ottoniel.pdf.

[43] Giorgia Paolini. Agile Git CI with TFS. 2016. URL https://www.visualstudio.com/es/
tfs/.

[44] Guı́a PMBOK. Guı́a de los Fundamentos de la Dirección de Proyectos. Project Management
Institute Inc, 2, 2008.

[45] Roger S. Pressman. Software Engineering: A Practitioner’s Approach. McGraw-Hill Education,


2010. ISBN 978-0-07-337597-7. Google-Books-ID: y4k AQAAIAAJ.

[46] Robert C Martin,, Micah D Martin,, y Patrick Wilson-Galés. FitNesse UserGuide. 2017. URL
http://fitnesse.org/FitNesse.UserGuide.

[47] Gregorio Robles. Programación eXtrema y Software Libre. 2002. URL


https://www.researchgate.net/profile/Gregorio_Robles/publication/228593903_
Programacion_eXtrema_y_Software_Libre/links/0deec52612004e0652000000.pdf.

[48] Scott Wambler. Introduction to Test Driven Development (TDD). 2016. URL http://www.
rivetq.com/wp-content/uploads/2016/08/TDD.pdf.

[49] SeleniumHQ. Selenium Web Browser Automation. 2017. URL http://www.seleniumhq.org/.

[50] SoftwareAdvice. Reseñas capturas de pantalla y caracterı́sticas de JIRA. 2017. URL https:
//www.softwareadvice.co/software/4315/atlassian-jira.

[51] Srini Penchikala. Domain Driven Design and Development In Practice. 2008. URL https:
//www.infoq.com/articles/ddd-in-practice.

[52] Taiga Agile. Welcome Taiga Support. 2017. URL https://tree.taiga.io/support/.

[53] Tamara Torres. Análisis y adaptación de BDD en un desarrollo semi-ágil: un caso de estudio.
Tesis, Facultad de Informática, 2016. URL http://hdl.handle.net/10915/59101.

[54] Travis CI GmbH. Travis CI Test and Deploy with Confidence. 2017. URL https:
//travis-ci.com/.

[55] Vaca, Pablo y Maldonado, Calixto. Test Driven Development Una aproximación para entender
su utilidad en el proceso de desarrollo de Software. 2017. URL http://www.carlosble.com/
downloads/disenoAgilConTdd_ebook.pdf.

C.U. Marı́a Lorena Garcı́a TDD 138


Bibliografı́a

[56] Wikipedia. Anti Patterns Catalog. 2017. URL http://wiki.c2.com/?AntiPatternsCatalog.

[57] Wikipedia. Desarrollo guiado por comportamiento. 2017. URL https://es.wikipedia.


org/w/index.php?title=Desarrollo_guiado_por_comportamiento&oldid=97913823. Pa-
ge Version ID: 97913823.

[58] Wikipedia. Desarrollo ágil de software. 2017. URL https://es.wikipedia.org/w/


index.php?title=Desarrollo_%C3%A1gil_de_software&oldid=98820458. Page Version ID:
98820458.

[59] Wikipedia. Lean software development. 2017. URL https://es.wikipedia.org/w/index.


php?title=Lean_software_development&oldid=98157535. Page Version ID: 98157535.

[60] Derek Robert Price y Ximbiot. CVS Open Source Version Control. 2017. URL http://www.
nongnu.org/cvs/.

C.U. Marı́a Lorena Garcı́a TDD 139

También podría gustarte