El documento presenta una introducción al desarrollo de software dirigido por pruebas (TDD), describiendo sus etapas principales: 1) Escribir especificaciones de requisitos en forma de ejemplos de uso o tests, 2) Implementar el código mínimo para satisfacer dichos tests, y 3) Refactorizar el código para mejorarlo. Explica que TDD ayuda a emerger un diseño adecuado de forma incremental y garantiza que el software sea funcional en todo momento, aunque señala que no es tan efectivo para interfaces gráficas u otros componentes
1. ESCUELA DE FORMACION CONTINUA
Licenciatura en Gestión de Tecnologías
Ingeniería de Software
PROFESORES:
ING. ROSA SANABRIA
ING. FLAVIO GARRIDO
1° CUATRIMESTRE - AÑO 2019
GRUPO APELLIDO Y NOMBRE DNI NOTA
4
Cereto, Sebastián 31.554.289
Machuca, Martín Miguel 23.842.490
Ocampo, Gustavo 25.943.032
Robertiello, Pablo Hernán 31.732.554
Salgado, Luciano Ezequiel 35.766.182
2. Trabajo Práctico Metodologías
Ágiles
OBJETIVO: Que el alumno comprenda las etapas de un modelo de proceso ágil para desarrollo
de software y pueda describirla utilizando un ejemplo real.
Metodología: Los docentes asignarán una metodología a cada grupo. Los alumnos realizaran una
investigación sobre cada una metodología ágil a elección, detallando una breve introducción de la
metodología, las etapas y características principales. Para qué tipo de sistemas es más aplicable,
especificando un ejemplo de aplicación real. Ventajas y desventajas comparándolo con un proceso
tradicional.
TDD (Desarrollo Dirigido por pruebas) Kanban
Desarrollo Dirigido por Tests: TDD
1.- Introducción
1.1.- Metodologías ágiles
El desarrollo de software dirigido por tests (pruebas) es una de las metodologías denominadas
ágiles. El agilismo surge como técnica en respuesta a las frustraciones y fracasos provocados por la
utilización del llamado modelo en cascada. Este modelo define de antemano una serie de esquemas,
requisitos y requerimientos que se irán transformando, mediante etapas de desarrollo, en el producto
de software. El problema radica en la naturaleza volátil de los requerimientos del cliente, que muy a
menudo cambian durante el proceso de desarrollo de un proyecto. Esta rigidez en la definición de
requerimientos del modelo en cascada, el no poder afrontar la dinámica cambiante de los
requerimientos, condujo muy frecuentemente al fracaso de los proyectos.
Las metodologías ágiles comprenden un amplio abanico de técnicas enfocadas principalmente a la
cercanía entre el cliente (o dueño del proyecto) y el equipo de desarrollo y también entre los
integrantes del equipo de desarrollo. Existen métodos para organizar equipos, técnicas para escribir
y mantener software. Estas técnicas estimulan la colaboración y la satisfacción del cliente,
realizando entregas parciales funcionales y revisando en cada iteración de desarrollo el estado de los
requerimientos, pudiendo, de esta forma, atacar tempranamente los problemas que surjan.
1.2.- TDD
El desarrollo Dirigido por Test (Test Driven Development o TDD) es una técnica de diseño e
implementación de software incluida dentro de la metodología llamada Extreme Programming
(XP). TDD es una técnica para diseñar software que se centra en los siguientes fundamentos:
3. Solo se implementan las funcionalidades que el cliente necesita y nada más.
Reducir la cantidad de defectos que llegan a la fase de producción en un software.
La producción de software modular, altamente reutilizable y preparado para los cambios.
El diseño del software, desde el punto de vista de TDD se va formando a partir de la
implementación de ejemplos de uso. En otras metodologías primero se analizan los requerimientos,
se elabora el diseño del sistema, se implementa el código fuente y luego se ejecuta y testea
(mediante baterías de test unitarios, por ejemplo).
En TDD, a partir de los requerimientos iniciales, lo primero que se implementa son ejemplos de uso
de cada una de las funcionalidades del sistema, según su orden de prioridad e iteración de
desarrollo. Esto quiere decir que, incluso antes de saber cual es la interfaz de un componente o
función, incluso antes de que esta exista, se programan una serie de ejemplo de usos (mal llamados
Tests). Luego se implementa la versión mínima de dicho componente/función para satisfacer la
ejecución de su ejemplo de uso/test. Seguido a esto se refactoriza la solución para mejorar el código
y satisfacer distintos ejemplos de ejecución.
De este modo la propia implementación de pequeños ejemplos, en sucesivas iteraciones, hace
emerger la arquitectura que se necesita usar.
Es un método interesante de utilizar para el desarrollo de software porque supone que a cada
momento, durante el proceso de desarrollo, se contará con una aplicación funcional (incompletas
durante el desarrollo pero funcionales). También este tipo de metodología ágil garantiza que el
acuerdo del cliente a cada momento del ciclo de desarrollo.
2.- Etapas de TDD
El algoritmo TDD tiene los siguientes pasos:
Escribir la especificación del requisito (ejemplo, test).
Implementar el código fuente según dicho ejemplo.
Refactorizar para eliminar duplicidad y hacer mejoras.
2.1.- Escribir la especificación del requisito (el ejemplo, el test)
Una vez que está claro el requisito se lo expresa en forma de código (programa). Es decir, se
programan ejemplos de uso de cada requisito/función antes que esta función exista. Este cambio de
perspectiva ayuda a comprender el dominio del problema y a que la solución se ajuste lo mas que se
pueda a la necesidad.
2.2.- Implementar el código fuente según dicho ejemplo
Teniendo ya el ejemplo codificado, se procede a implementar la solución escribiendo el mínimo
código posible para satisfacer el ejemplo/test. El mínimo código posible puede resultar en una
solución trivial o poco estructurada. Se le resta importancia a esto último en pos de obtener la
solución mínima, pues en futuras iteraciones será mejorado y refactorizado. Este método nos
garantiza que no haremos cosas de más.
4. 2.3.- Refactorizar para eliminar duplicidad y hacer mejoras
Significa que no nos quedaremos con la primer versión de cada solución, por el contrario el código
sufrirá varias iteraciones, revisiones, durante las cuales será refactorizado para volverlo robusto y
libre de código duplicado. Es en esta etapa donde se aplican las técnicas de programación como
patrones de diseño, clean code, buenas prácticas, etc.
Otra forma de pensar las fases del ciclo TDD es:
Rojo: La funcionalidad no pasa el test.
Verde: La funcionalidad pasó el test.
Refactorizar: Se debe revisar y mejorar el código en pos de pasar nuevos test, cuidando los
test que ya fueron aprobados. Es decir, que la solución va a ser aprobada por los test
anteriores y por el nuevo test.
3.- ¿Qué tipos de tests existen?
Cada comunidad utiliza términos diferentes. Una comunidad podría ser la de los que practican
TDD, otra podría ser la de los que escriben tests para aplicaciones ya implementadas y que todavía
no los tienen, por ejemplo. Un mismo test puede ser de varios tipos, incluso mirándolo desde la
perspectiva de un solo equipo de desarrollo ya que su clasificación dependerá del aspecto a
considerar. No existen reglas universales para escribir todos y cada uno de los tipos de test ni sus
posibles combinaciones.
Pese a lo dicho, es conveniente clasificar de algún modo los test que vayamos escribiendo para estar
seguros de lo que se pretende afirmar con cada test y por que se hace de determinada manera.
Test de Aceptación (ATDD): Son tests “escritos” por el dueño del producto. También
llamados “Tests de cliente” permiten comprobar que el software cumple con un requisito de
negocio. Conectan los requerimientos con la implementación y se escriben antes que nada.
Tests Funcionales: Son un subconjunto de los tests de aceptación. Son más específicos que
los ATDD y se concentran a nivel función.
Tests de Sistema: Integran varias partes del Sistema completo. Incluso pueden testear el
sistema de punta a punta. Es el mayor de los Test de Integración, pues abarca muchas partes
del sistema.
Test Unitarios: Son los tests más importantes para TDD. Verifican cada unidad de software
de manera aislada e independiente del resto de los componentes del sistema. Para considerar
un test como Unitario debe cumplir las siguientes propiedades: Atómico, Independiente,
Inocuo y Rápido. Atómico porque prueba una mínima parte del sistema. Independiente
porque no debe estar relacionado con el resto de los test o componentes/funciones del
sistema. Inocuo porque no debe modificar el estado del sistema luego de su ejecución
(modificación de bases de datos, archivos, etc.). Rápido porque serán ejecutados muchas
veces durante el proceso de desarrollo y no deberían representar una penalización en la
performance del proceso de desarrollo.
5. Test de Integración: Es el nexo que une los test unitarios con los de sistema. Como su
nombre lo indica, integración significa que ayuda a unir distintas partes del sistema. Un test
de integración, al contrario que uno de unidad, puede escribir y leer de una base de datos
para comprobar que la lógica de negocios funciona bien con datos reales, en un escenario
real.
4.- ¿Para qué tipos de sistemas es más aplicable?
La Ingeniería de Software, y específicamente la Ingeniería de Requerimientos, viene evolucionando
con los años y van apareciendo nuevas técnicas que suplantan total o parcialmente a los procesos
anteriores, en materia de metodologías de desarrollo de software.
En los últimos años se viene comprobando el éxito de las metodologías ágiles en contrapartida con
sus metodologías predecesoras (Modelo en Casada, RUP, etc.).
Los modelos ágiles en general y en TDD en particular ayudan en el desarrollo de software
minimizando dramáticamente el ratio de fracasos. Al estar atentos y tener una rápida y temprana
reacción ante la evolución de los requerimientos, TDD (y el Agilismo en general) es ideal como
metodología de trabajo en proyectos donde los requerimientos del dominio de negocio son
cambiantes; esto es en la gran mayoría de los proyectos comerciales.
Un ejemplo de proyecto real podría ser un sistema de ventas web/mobile.
6. No es recomendable usar TDD en proyectos de requerimientos estáticos, inmutables y dominios de
negocio bien definidos. Como ejemplo podemos mencionar proyectos de sistemas embebidos,
automatización y control de sistemas industriales, sistemas de uso militar, aeroespacial, etc.
5.- Ventajas de TDD
Las principales ventajas ya fueron mencionadas anteriormente pero podemos decir también que
TDD ayuda a tener un código depurado y funcional en todo momento. Por esta razón se genera
software de mayor calidad en menos tiempo, el uso de pruebas guía o ayuda a “emerger” al diseño
ideal necesario para cada proyecto, evitando la sobre dimensión del diseño (funciones que no son
necesarias).
Es un proceso de diseño basado en interfaces, donde el programador mira cada componente desde la
óptica de su utilización. Esto significa que el software se diseña estructuralmente y por “contratos”
entre componentes antes de codificar su implementación final (el comportamiento real). La
utilización de interfaces enriquece enormemente el diseño de un sistema llevándolo a una
modularidad superior, promoviendo el desacople de componentes y permitiendo la inyección de
dependencias (una práctica de programación muy efectiva, fundamentalmente para la realización de
tests unitarios).
La principal fortaleza de TDD descansa en la capacidad de avanzar en pequeños pasos el desarrollo.
Permite que el programador se centre en la tarea actual y la primera meta es, a menudo, hacer que la
prueba pase.
6.- Desventajas de TDD
TDD no es tan bueno en escenarios donde los tests no se pueden automatizar, es decir, cuando se
requiere la intervención humana para realizar las pruebas.
El desarrollo de interfaces gráficas, componentes distribuidos o pruebas sobre bases de datos son
algunos de los puntos flojos de esta metodología. Si bien existen algunas soluciones incipientes,
todavía TDD no llega a brindar el nivel de rendimiento que sí logra en el desarrollo de objetos de
negocio y de capas intermedias de los sistemas.