[vc_row][vc_column][vc_column_text]
TDD(Test-Driven Development) siempre se describe como un método de diseño para unidades, ya sean clases o métodos. En el mundo real, sin embargo, no sólo escribimos clases. Escribimos flujos completos que consisten en clases, librerías y esquemas de datos. Aún queremos los beneficios de TDD, ¿Cómo realizamos esto en el mundo real?
En el desarrollo ágil de software, se tiene las historias de usuarios (o épicas) que se deben completar, en el otro lado tenemos a TDD que permite el diseño de componentes, pero no provee una idea de todo el flujo. El poder utilizar TDD va a requerir de cierta planificación y pensar en forma creativa. Revisemos esto, paso a paso.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 1: Identificar las historias más importantes
Primero, se requiere identificar las historias más importantes (flujos), si las tenemos escritas en forma de BDD excelente, en caso de que no, se requiere tener una lista de requerimientos que sean importantes.
Con TDD, la intención es escribir el código mínimo que funcione. Sin embargo, en la integración o sistemas de prueba, se requiere diseñar el mínimo diseño que funcione. Esto significa que vamos a construir software en forma incremental, completando una historia antes de movernos a la siguiente, y NO realizando componentes para todos los requerimientos.
Es importante notar, que se deben tener las historias que cumplan un determinado flujo en el sistema, donde la información es transferida y la operación se define como completa.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 2: Definir los criterios de aceptación
Igual que en TDD, se requiere definir como se requiere que funcione y revisar el comportamiento en el cual estamos interesados. Por lo cual se requiere saber los criterios de aceptación.
Con las pruebas al estilo BDD, que son ejemplos en realidad, es sencillo. Incluso con estas pruebas, muchas veces se dejan las cosas sin terminar y solo cuando tenemos algo que conectar o con lo cual interactuar realizamos estas pruebas.
Al tener historias de usuario sencillas, corremos el riesgo de implementar algo que no es necesario. Al especificar un criterio de aceptación, obtenemos el sentido a lo que estamos implementando y cuan complejo es. Si no podemos definir como probar una historia de usuario, eso es una señal de que se requiere pensar un poco más ante de pasar al desarrollo.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 3: Identificar los componentes principales de la historia
Los componentes deben estar completos, a medio escribir o aún por empezar a ser escritos. Una historia de usuario fluye a través de los componentes y se pueden utilizar como están, o se puede necesitar la modificación o extensión de una interface, una nueva codificación o escribirlo nuevamente.
Cuando revisamos una historia de usuario a través de sus componentes, se pueden analizar opciones de diseño. Se puede ver como encajan las diferentes piezas del rompecabezas, y si hay problemas, se requiere tomar atención de estos.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 4: Re priorización de las historias
Incluso cuando las historias de usuario ya fueron priorizadas en términos de valor, existe una opinión valida que puede llegar del equipo de desarrollo.
En ocasiones, hay dependencias entre las historias de usuario, por lo cual podemos jugar con el orden si hay una buena explicación para esto. En este caso, si la prueba de la historia #1 es más sencilla de realizar sólo una vez terminada la historia #2, tal vez tengamos que desarrollar primero la historia de usuario #2.
Observe que no se esta cuestionando el valor de las historias de usuario, básicamente cuan rápido se pueden completar estas. Si se tienen historias de usuario completas, se puede tener una retro alimentación rápida y tomar decisiones en base a estas.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 5: Decisión de componentes
Una vez que empecemos la codificación podemos realizar decisiones adicionales de diseño. Por ejemplo, si la historia de usuario utiliza determinado componente, uno que no tiene una prueba, necesitamos realizar algo acerca de el. Se puede decidir incluir el componente en pruebas, reescribirlo o construir alrededor de él, dependiendo del impacto que tiene este componente con el resto del sistema.
También podemos pensar la forma en como separamos el sistema, en grandes módulos o pequeños módulos. Esto es un refactoring de la arquitectura, en donde podemos realizar cambios sin modificar la funcionalidad existente.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 6: Decisión de interfaces
Podemos empezar identificación los puntos de conexión. Esto no es la definición completa de una interface entre componentes, pero es un buen inicio. Se puede decidir entre reutilizar las interfaces actuales, agregar o modificarlas. Claro, si todo el código es nuevo, podemos definir lo que queramos.
En TDD, se define la interface de los componentes en las pruebas. No se deben definir interfaces que se tengan que discutir en cada paso o volver a probar. Las interfaces deben ser fáciles de gestionar.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 7: Escribir el código
Finalmente, empezamos a escribir código. Recuerda, sólo vamos a escribir el código suficiente para la historia. Esto es todo, no todos los componentes de una sola vez. Si quieres utilizar TDD en este punto, bien. Si las pruebas no funcionan por alguna razón, revisar el proceso y asegúrese de que escribió las pruebas en forma adecuada.
Lo peor que podemos hacer es, escribir el componente para todas las historias de usuario.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 8: Integración continua
Debemos asegurarnos de que estemos integrando siempre todas las historias de usuarios para ver si estas funcionan. De esta forma aprendemos que funciona y que se requiere modificar.
Al estar enfocados en sólo una historia, se tendrá menos código que integrar. La integración es menos compleja que integrar un gran conjunto de historias. Luego repetiremos los pasos 7 y 8 por cada historia de usuario.[/vc_column_text][/vc_column][/vc_row][vc_row][vc_column][vc_column_text]
Paso 9: Completar la historia e ir a la siguiente
«Completo» significa tener una prueba de que toda la historia funciona. La prueba debe venir en forma de una prueba automatizada de extremo a extremo y un producto a revisar para obtener comentarios. Esta retro alimentación puede cambiar las cosas, en términos de lo que viene a continuación.
Cada bloque de código es una responsabilidad. Puede contener errores, requerir cambios y nos gustaría escribir lo menos que podamos de él, solo para estar seguros que estamos en el camino correcto. TDD nos ayuda con el diseño y a mitigar los riesgos(al tener un conjunto de pruebas por realizarse) que puedan aparecer con las siguientes historias de usuarios.
Este proceso no ayuda a desarrollar TDD en el contexto correcto.
Este artículo se encuentra basado en Software Development Lifecycle: QA and Testing[/vc_column_text][/vc_column][/vc_row]