Tuesday, September 27, 2011

Primero la prueba.

Me he comprado un móvil, es una preciosidad, tiene de todo. Da la sensación de que los fabricantes de hoy en día leen mi mente, todo lo que yo desearía tener en  mi móvil... ¡resulta que lo tengo!, y si no, me lo compro online, una pasada. Me pregunto cómo de complicado será diseñar y fabricar estos aparatos.

Soy un tipo raro, lo admito, en mi afán de disfrute decidí comprobar si mi nuevo dispositivo, bonito donde los hubiera, era sumergible, más aún, sumergible en salfumán, que uno nunca sabe qué líquidos pueden llegar a derramarse sobre tales aparatos. Para mi sorpresa, desde que hice la prueba, el móvil ya no se enciende, de hecho no tiene ni teclas, espero que lo ocurrido esté cubierto por la garantía...

De mi disgusto saco una conclusión: probar es normalmente mucho más fácil que fabricar. Debí haber comprado un modelo previamente probado y diseñado para resistir el salfumán. Y digo probado antes de diseñado pues imagino que esas cosas se deben hacer así, uno supone que lo que va a fabricar soporta las pruebas, así que diseña la prueba, la lanza sobre el primer intento y, casi con total seguridad: falla, modifica lo que tiene y vuelve a probar. De las pruebas exitosas sucesivas gradualmente emerge un diseño cuya calidad está avalada por las pruebas realizadas, mire usted qué cosas.

En general, podemos afirmar que en en la mayoría de casos:
Complejidad(Prueba) < Complejidad( Funcionalidad ) 

Gracias a que las pruebas son lo primero que se tiene en cuenta, el diseño se irá acomodando a superarlas, esto lo denominaremos diseño evolutivo. Pero un diseño que supera las pruebas puede no ser de buena calidad, eso complicará mucho los diseños y mantenimientos futuros. La solución a esta situación proviene de, una vez superada una prueba, mejorar la calidad lo máximo posible y volver a pasar la prueba, de forma que el diseño evolutivo se asiente en diseños previos de alta calidad. A esta etapa la denominaremos refactorización, tema en el que profundizaremos... tanto o más que mi móvil en salfumán.

Por ahora quedémonos con la síntesis de cómo se deben llevar a cabo las cosas al decidir trabajar con orientación a las pruebas:

Primero las pruebas, diseño evolutivo, automatización de tests, y refactorización sin piedad.
Lo de "sin piedad" suena a poderoso ¿verdad? Este tipo de frases es común en este tema que acontece: TDD.

Pasito a Pasito

El marco de trabajo establecido por TDD permite desarrollar código de una forma efectiva utilizando pequeños incrementos, es decir, pasito a pasito, como aprenden a andar los bebés. Estos incrementos deben ir dirigidos a realizar algo en concreto, así dispondremos de algo entregable al terminar cada uno de ellos, ya que superan las pruebas pues fue lo primero que establecimos y nos han ido dirigiendo a lo largo del pequeño viaje.

Puede que en la entrega no se hayan cumplido todos y cada uno de los requerimientos del cliente, pero dado que los ordenamos previamente antes de diseñar las pruebas, la probabilidad de que los más importantes hayan sido cubiertos es muy alta. Habiendo realizado las pruebas antes que el código y habiendo sido superadas una y otra vez en cada iteración corta habremos reducido al máximo el riesgo de incorporar código de mala calidad y errores de última hora que bien darían al traste con la entrega actual o complicarían la entrega siguiente.

Esto a mí me recuerda al cuento de Pulgarcito, que con iteraciones cortas, pasito a pasito, colocó garbanzos en el bosque que posteriormente le permitirían volver a casa.

 

Quién sabe, es probable que incluso no habiendo dado tiempo a implementar el requisito de baja prioridad pero pudiendo presentar algo que claramente funciona en los puntos más importantes, el cliente se muestre tan satisfecho que descubra que aquellos requisitos de baja prioridad simplemente eran innecesarios, o incluso que los ignore, olvide o de buena gana permita que se lleven a cabo en una etapa posterior. Imagino que hay un mundo donde el cliente es un ser bondadoso y amable. Todo es posible.

Monday, September 26, 2011

Las Perspectivas nos las dan las Pruebas

A primera vista puede resultarnos absurdo diseñar, describir e implementar las pruebas antes que código que lleva a cabo la tarea descrita por la petición del cliente. Después de todo, en un mundo perfecto, entenderíamos por completo al cliente y podríamos lanzarnos como tigres a realizar el código final, si cabe, directamente sobre el entorno de producción. De obrar así es de esperar una vida llena de altibajos y desasosiegos, una gran aventura digna de llevarse a una película, si llega a buen fin, porque las películas deben terminar bien.

Los habemos que preferimos una vida laboral más tranquila, sensata y racional. Esto en principio nos lo ofrece el disponer de las pruebas antes de realizar un producto entregable puesto que, una vez realizado y sometido a las pruebas, su calidad estará garantizada.  Las pruebas nos aportan confianza y una buena percepción del avance del proceso de desarrollo.

Un pensamiento pueril nos puede llevar a pensar que las pruebas nos roban tiempo, puestos a ser inmaduros eliminemos también la etapa de captura de requisitos, ¡programemos directamente frente al cliente! ¡Bienvenidos al LiveProgramming! La experiencia nos dicta que eso no funciona, al menos casi nunca.

Puede resultarnos osado, nuestro objetivo siempre es aumentar la productividad manteniendo las cotas de calidad deseables. En principio las pruebas pueden parecernos ir en contra de la productividad. Cada prueba es un punto de apoyo en la escalada hacia la cima donde se coloca un producto finalizado de calidad garantizada. No niego que existen maestros de la escalada capaces de llevar a cabo tal proeza sin anclajes ni puntos de apoyo (las pruebas), pero lo cierto es que aquellos que sobreviven terminan por aceptar que, con las pruebas, el proceso de desarrollo es más certero, previsible y productivo.

El Diseño Guiado por las Pruebas (a partir de ahora TDD: Test Driven Design) nos indica un marco de trabajo que permite desarrollar código en pequeños incrementos. En breve veremos su bases y en ellas radica su complejidad: hay que ceñirse a ellas y seguirlas con perseverancia y buen talante.