Read time: 6 mins
Programas que resuelven retos

En la última entrada, hice alusión a que el debuggeo de un programa puede ser visto como una especie de juego de detectives, hay un crimen por resolver y pistas que deben llevar al origen de la falla, que luego se deberá resolver.

Resulta que en desarrollo de sistemas, las analogías de juegos abundan. Y un escenario donde también disfruto jugando es mientras sigo una metodología de trabajo en particular a la hora de estar programando.

Supongo que no soy el único que disfruta de resolver problemas y retos mentales. Muy al estilo de este, el reto de Einstein1: http://www.juegosdelogica.com/index.php/el-acertijo-de-einstein. Retos de lógica donde hay que poner un poco de esfuerzo para lograr, primero entender el problema, y segundo resolverlo.

En programación hay una técnica que consiste más o menos en lo siguiente:

  • a propósito, yo mismo me pongo un reto que mi programa debe resolver
  • Como mi programa aún ni siquiera está escrito, obviamente falla
  • Entonces me pongo a resolver el problema, para que el programa pase el reto
  • Una vez que el programa pasa el reto, me pongo otro y continúo así. Reto-Resuelvo-Reto-Resuelvo...
  • (ocasionalmente me puedo poner un nuevo tipo de reto: en vez de resolver un reto que me acabo de poner, debo reescribir mi programa para que los retos anteriormente resueltos sigan siendo superados por mi programa).

Si lo tuyo es resolver problemas, esta técnica debe resultar hasta reconfortante para programar y trabajar así.

Obviamente, si todo esto te sonó a algo que ya conocías, es probable que así sea. Se trata del Test Driven Development, una técnica ágil de programación de uso más o menos difundido hoy en día.

La técnica se basa en la importancia de crear pruebas unitarias. Entre mejor probado esté un código, mayor certeza vamos a tener de que hace lo que se supone que debe hacer, en los escenarios que tenemos contemplados al desarrollar el programa. Y el Test Driven Development tiene la gracia de que consigue una altísima cobertura de las pruebas sobre el código desarrollado.

Como hablamos de pruebas unitarias, sólo baste recordar lo siguiente:

  • por un lado vamos a tener el programa que queremos desarrollar, es donde resolveremos los retos que nos pongamos. Por convención llamémosle a este programa: código.
  • y por otro lado vamos a tener otro programa, que únicamente consistirá en la serie de pruebas que queremos que nuestro programa pase. Son los retos que nos iremos poniendo para resolver. Por convención a este programa le llamaremos: pruebas (o conjunto de pruebas).

Veamos un poco en qué consiste. El TDD tiene unas cuantas reglas que, si se llevan a cabo, logran unos beneficios al momento de programar. Obviamente se pueden obviar las reglas y no hacerlas. Pero entonces no se  estaría haciendo TDD. Y posiblemente no se obtendrían sus ventajas. No es una obligación hacer TDD, pero al ser un juego, estas son sus reglas:

  • Antes de programar lo que sea, se tiene que hacer una prueba correcta del código (si, inexistente todavía), que obviamente fallará (porque no hay código todavía).

¿Pero qué es una prueba correcta? Es una prueba que falla porque el código no está ahí, pero que no causa que nuestro programa de pruebas truene. En otras palabras si nuestro programa de pruebas requiere que exista el módulo que vamos a desarrollar en código, lo creamos. Una vez que el programa de pruebas no truene, pero si falle (porque la prueba no ha sido superada), ya tenemos una prueba correcta.

Es MUY IMPORTANTE que no se desarrolle nada de código aquí, sólo la prueba y lo necesario para que esta no truene.

  • Entonces sí, desarrollamos código para que pase la prueba. Desarrollamos y probamos. ¿Aún falla? Seguimos desarrollando. ¿Ha pasado? ¡Listo! (¡Pero no más código! ¡Nada que no sea para pasar la prueba!)
  • Creamos una nueva prueba correcta que falle, y seguimos...
  • Ocasionalmente vamos a querer que nuestro código se vea mejor, sea más eficiente, cumpla alguna convención... Entonces vamos a reescribirlo, pero en este paso el chiste es que NINGUNA de las pruebas truene, todas deben seguir pasando.
Ciclo del TDD
El ciclo del Test Driven Development

Muy a grosso modo esa es la idea detrás del TDD. Claro que hay que seguir buenas prácticas a la hora de crear las pruebas, como asegurarnos de que realmente sean unitarias y no interactúen con otros sistemas, pero esa es harina de otro costal y la dejamos para otra ocasión.

¿Qué obtenemos a cambio?

  • En primer lugar, probar nuestro código. Puede sonar extraño, pero resulta que si dejamos la fase de pruebas para DESPUÉS de haberlo desarrollado, suele suceder que no lo hacemos. O lo hacemos deficientemente. Al obligarnos a hacer las pruebas PRIMERO, estamos forzándonos a que cada cambio que hagamos, sea probado.
  • Además dichas pruebas van a tener una cobertura muy alta. Precisamente porque cada cambio implica nuevas pruebas. El grado de cobertura va a ser muy alto, sino es que del 100% si hacemos TDD durante  todo el desarrollo de nuestro código.
  • ¡Obtenemos un mejor código! Y no sólo por estar probado, sino que como resultado de la forma en que se desarrolla, el resultado será más limpio. Hacer las pruebas nos obliga a pensar en la forma en que queremos que el código responda a ciertos estímulos, y eso nos lleva a pensar también en la forma en que estructuramos el código, y nos da un esquema mental en como pensar el código para luego desarrollarlo. Usualmente eso hace del código resultante un mejor producto.
  • ¡Pero no sólo eso! Si comenzamos a jugar el TDD y nos mantenemos jugándolo durante una sesión de programación, seguramente nos daremos cuenta que entramos en un estado mental muy particular y especial que los programadores aprecian muchísimo: algunos le dicen simplemente La Zona (en inglés le dicen The Flow). Es un estado mental de concentración tan elevado que la sensación de control y conciencia misma de la acción de programar desaparece; uno simplemente fluye programando. Es un estado muy apreciado porque es ultra productivo. Pues bien, hacer TDD facilita muchísimo (o así atestiguan muchos) el entrar aquí, en La Zona.

Así que, ¿jugar o no jugar al TDD? Eso depende de cada quien (bueno, quizá hay lugares donde te orillan a hacer o no ciertas prácticas, ni qué hacerle, pero en este caso yo no lo vería como algo negativo). No siempre es necesario hacer TDD, y en algunos casos puede no ser tan benéfico (ponerse a experimentar programando, por ejemplo cuando se hace análisis de datos es una situación común de este escenario). Lo único que puedo decir es: inténtalo. Por un buen tiempo para que puedas disfrutar de sus beneficios. Conoce como hacerlo. Y después opta. ¡A jugar!

 

NOTAS:

  1. No se porque le llaman "Reto de Einstein". Seguramente como muchos mitos en la red, no fue elaborado por Einstein. Sin embargo así se le conoce.

P.D. puntos extra si resolviste el reto de Einstein en 20 minutos o menos ?

Etiquetas