miércoles, 29 de mayo de 2013

TDD, ATDD e Integración Continua

TDD (Test Driven Development)

TDD (Test Driven Development - Desarrollo Guiado por Pruebas), es una técnica de desarrollo de software, que consiste en iniciar el proceso escribiendo las pruebas que el software debe pasar, antes de empezar al escribir el código que las satisface, se diferencia del enfoque tradicional, en el cual primero se escribía y código y luego se escribían las pruebas para verificarlo.

La definición de las pruebas se hace con base en los requerimientos de la clase que se está implementando y las mismas se escriben utilizando herramientas de pruebas unitarias xUnit, luego se escribe la especificación de la clase acorde a la prueba diseñada, se ejecuta la prueba, la cual debe fallar, posteriormente se implementa el código, cuando se ejecuta nuevamente la prueba ésta debe pasar satisfactoriamente. El ciclo TDD se muestra en el siguiente diagrama de actividades:




El código debe pasar diferentes casos de prueba, el abordaje del desarrollo es ir implementando el código necesario, para ir pasando cada caso de prueba que se haya definido de forma gradual, esto hace necesario ir modificando el código desarrollado a medida que se van verificando cada uno de los casos de prueba, a este proceso de modificar el código sin cambiar la interfaz de los métodos o clases se denomina Refactorizar.

Qué se busca TDD.

  • Escribir la menor cantidad de código posible, puesto que solo se debe escribir el código necesario, para satisfacer las pruebas diseñadas.
  • Favorecer que el diseño de las clases, cumpla con los principios de alta cohesión  y bajo acoplamiento.
  • Garantizar la calidad del software que se produce.
  • Minimizar el esfuerzo de los desarrolladores, puesto que el esfuerzo de codificación se centra en escribir solo el código necesario para satisfacer las pruebas, sin distraerse en otros temas.
  • Propende por la obtención de un código de calidad, limpio, claro, cada pasada dentro del proceso de refactorización, debe ir acompañada de un refinamiento del código y del algoritmo que se está implementando.
  • Reducir a cero el uso de las herramientas de debug.
  • Proporcionar una retroalimentación temprana, para la detección y corrección, de errores de codificación y diseño.

Desventajas de TDD

Lo que escribo a continuación es una posición personal de reflexión acerca de TDD, lo que a mi juicio pueden ser las desventajas de este enfoque.


  • El hecho de escribir las pruebas antes que el código y hacer que éste último las satisfaga, no es garantía de que haya un sesgo tanto en la selección de las pruebas como en el desarrollo mismo del código, sobretodo si es  la misma persona quien realiza los dos procesos. Para evitar esto, se podría apoyar o más bien complementar con técnicas como eXtreme Programming, donde haya una segunda persona que diseñe las pruebas o que verifique que las mismas sean objetivas respecto al producto que se desea obtener.
  • Es una técnica que requiere disciplina por parte de quien decide aplicarla, y es muy fácil saltarla, o no aplicarla con la debida rigurosidad.
  • Para ciertas funcionalidades, es muy difícil hacer un set de pruebas suficiente, que garantice que todos los casos posibles están cubiertos, en estos casos aunque una adecuada selección de los casos de pruebas puede ayudar, no se puede garantizar un cubrimiento total ni descartar que el código es correcto para todos los casos.
  • En el caso de las interfaces de usuario, esta técnica no es de fácil aplicación, puesto que el diseño de estas pruebas, requiere de tiempo y herramientas especiales, y la idea de TDD como apoyo a las metodologías ágiles, es propender por ciclos cortos de desarrollo y pruebas.

ATDD (Aceptance Test Driven Development)


ATDD (Aceptance Test Driven Development - Desarrollo dirigido por Pruebas de Aceptación), también conocida como BDD (Behavior Driven Development - Desarrollo Dirigido por el comportamiento)  Es una práctica donde los criterios de aceptación del software, se socializan y discuten con todo el equipo de desarrollo, luego estos criterios se aterrizan en ejemplos concretos antes de abordar las tareas de diseño y codificación,  lo que se pretende es que todos los miembros del equipo tengan la misma percepción del problema y de la solución propuesta, eta técnica es fundamental cuando se aplican metodologías ágiles de desarrollo, porque el inicio de cada ciclo debería comenzar con una discusión acerca del problema, de las estrategias propuestas para abordarlo y de lo que se espera obtener al finalizar el ciclo de desarrollo.

Al igual que TDD, ATDD exige la definición de las pruebas antes de empezar a codificar, pero estas pruebas se expresan en términos del comportamiento esperado del software, es decir, que se deben definir las pruebas de aceptación a nivel funcional antes de escribir el código. Para la codificación se sugiere que se apoye en la técnica TDD como un complemento de ATDD.


Figura que muestra el ciclo ATDD.


El ciclo ATDD consta de 4 fases:

1. Discusión: En las reuniones de planeación, se discute con el equipo de trabajo, las historias de usuario o casos de uso que se van abordar durante ese ciclo, de tal manera que todo el equipo conozca en detalle el producto que se espera obtener al finalizar el ciclo en términos de requerimientos funcionales. Como esta técnica es parte de las metodologías de desarrollo ágil, en estas reuniones de planeación, generalmente se evalúan los resultados del ciclo de desarrollo anterior, se hace la retroalimentación y se discuten los refinamientos funcionales del software que se abordarán en el ciclo que comienza.

2. Destilar:  Una vez se han discutido las pruebas funcionales de aceptación y el comportamiento esperado del software para el final del ciclo que comienza, se deben capturar estas en un formato de pruebas, para posteriormente ser aplicadas al software y verificar que él mismo las satisface, este formato debe ser público, compartido y aprobado por todo el equipo.

3. Desarrollar el código: Se debe abordar el desarrollo del código, éste puede estar apoyado en técnicas TDD con pruebas unitarias, pero el equipo de desarrollo, debe también ir verificando el software contra las pruebas funcionales diseñadas, si el software no cumple se debe refactorizar hasta que pueda pasar las pruebas funcionales.

4. Producir un Demo: Con una determinada frecuencia se debe integrar el código producido por los diferentes miembros del equipo de desarrollo, con el fin de producir una versión preliminar del software y aplicarle el set de pruebas diseñado previamente, para ver si pasa o no las pruebas funcionales de aceptación, si una o varias de las pruebas fallan, se vuelve al proceso de codificación para hacer los ajustes correspondientes, y se repite el proceso hasta que el software pase las pruebas de aceptación.

TDD y ATTD, son procesos similares, aunque con enfoques distintos, ATDD apunta al cumplimiento de requerimientos funcionales o de comportamiento del software de manera general, mientras que TDD está más orientado a las pruebas detalladas sobre los diferentes métodos de las clases, estas dos técnicas son complementarias y pueden o no ser aplicadas de forma simultánea.

La siguiente gráfica muestra la integración entre ATDD y TDD.









Continuous Integration (Integración Contínua)

La integración continua es una técnica que consiste en hacer integraciones de un proyecto con la mayor frecuencia posible, con el fin de detectar errores y problemas de forma temprana y tomar las acciones necesarias para corregirlas.  La integración consiste en la compilación de todo el proyecto y la ejecución de las pruebas sobre el mismo.

Para que la integración continua sea posible, se requiere de herramientas que permitan automatizar el proceso de integración, a estas herramientas se les conoce como servidores de integración continua, existen muchos como Jenkins, Hudson, Cruise Control, también se hace necesario un sistema de control de versiones que permita almacenar  de forma centralizada  las versiones que se van produciendo del software de tal forma que de ahí se pueda obtener la versión actualizada que va a ser compilada y probada. otro componente importante son las herramientas de pruebas que se integran a los servidores de integración continua, para permitir la automatización de las pruebas.

El proceso de integración continua, permite además detectar errores de integración de componentes, dependencias entre librerías y componentes, además que garantiza que desde etapas tempranas de desarrollo, se construyan los scripts de instalación del producto cuando este vaya a ser puesto en un ambiente de producción.

En la siguiente gráfica muestra el proceso de integración continua.



Aunque las tres técnicas mencionadas en este blog, pueden ser utilizadas de forma independiente, el uso de las tres de forma conjunta, se constituye en una buena práctica que permite garantizar que el software producido tenga una alta calidad y cumpla con las expectativas para las cuales fue construido. Estas técnicas, son fundamentales cuando se utilizan metodologías ágiles de desarrollo de software.



Referencias:

1 comentario: