domingo, 14 de diciembre de 2014

Código Java testeable

Introducción

Hace un tiempo, después de leer en casa sobre test unitarios y de haber hecho bastantes ejercicios, decidí escribir test unitarios en el trabajo.

La idea era escribir los test unitarios después de escribir el código de producción.
Nota: En varios libros y artículos comentan que la mejor forma de comenzar a escribir test unitarios en el trabajo es cuando surjan incidencias o problemas y creo que tienen razón. Si lo hubiera hecho así hubiera sido más fácil :-)

Tras varios intentos fallidos me encontraba realmente frustrado: ¿porqué me resultaba tan complicado escribir test unitarios si en mi casa no tenía ningún problema?

Entonces llegué a un artículo de Michael Feathers donde aparece la siguiente frase en el primer párrafo:

Code that wasn’t designed to be testable is not testable. Testability is not a quality that appears accidently. Or does it?

Código que no ha sido diseñado para ser testeable no es testeable. La testeabilidad no es cualidad que aparece accidentalmente. ¿O si?


Entonces, me dí cuenta que me resultaba tan complicado escribir test unitarios porque mi código no era testeable.
Este hallazgo fue a la vez una liberación y un palo porque a quién le gusta saber que su código no está diseñado de forma adecuada.

Código Java testeable

Si os habéis leído el artículo, poco más os puedo contar. Bueno, puedo contaros mi versión del artículo porque personalmente me resulta complicado el acordarme de todos los sitios en los no tengo que que estar pendiente donde pongo código TUF (Test Unfriendly Feature).

Así, para escribir código testeable hay que seguir los siguiente consejos:

  1. No escribas métodos estáticos o bloques de código estático.
  2. No escribas clases finales ni métodos finales
  3. Inyecta en tu código los colaboradores de la clase a testear (principalmente las que "hablan" con la base de datos, internet, sistema de ficheros o interfaz de usuario) y añádelas como atributos. Escribí un artículo sobre la inyección de dependencias en http://www.enrique-martin.com/2014/05/injeccion-de-dependencias-en-java-para.html
  4. Inyecta interfaces en lugar de clases. Es mejor depender de abstracciones que de implementaciones. Además creo que tiene sentido porque ¿para qué queremos inyectar una clase concreta si lo que queremos es que nuestro código sea más flexible?

Si practicas los dos primeros puntos tu código va a mejorar mucho en testeabilidad. En cuanto a los puntos 3 y 4 difieren a lo que aparece en el artículo.

Creo que si sigues los puntos 3 y 4 la mayoría de los problemas que se comentan en el artículos, como son en la clases privadas y en los constructores, se solucionan.

Porqué

Como pone en el artículo, todos los consejos están relacionados con la forma en que se escriben test unitarios.
Un test unitario debe ser rápido y repetible y suelen no cumplirse estas propiedades si, por ejemplo, se accede a base de datos en el código.
Así, lo que se hace es crear una subclase de la clase donde está el problema y se sobrescribe el método para que se comporte como queramos. Si no se puede sobreescribir el método resulta muy complicado el testearlo.

Por ejemplo, si queremos que un método devuelva siempre una lista vacía, y este método es estático. No podremos sobreescribirlo en la subclase, y por lo tanto no podemos hacer que se comporte como queremos.



En conclusión, si tu código no tiene test unitarios seguramente tú código no es testeable por lo que te va a resultar complicado escribir test unitarios.

domingo, 14 de septiembre de 2014

CodeRetreat en Bodegraven



Introducción

El otro día fui a un coderetreat en fort wierickerschans (no me preguntes como se pronuncia porque no tengo ni idea), en Bodegraven y la verdad es que me lo pasé fenomenal.
Como podéis ver en la foto de arriba, el sitio es precioso y toda la zona merece al menos un paseo para conocerla.

Qué es un coderetreat

Un coderetreat, como dicen en su página web, es un evento que dura todo el día y en el que desarrolladores se juntan para practicar sus habilidades.

El evento se divide en sesiones donde los desarrolladores se juntan en parejas para resolver un problema utilizando Test driven development* y en el lenguaje de programación que hallan decidido entre ambos.

Después de cada sesión hay una retrospectiva sobre cuales fueron los problemas que se han encontrado y como se han intentado solucionar.

El problema es siempre el mismo, el juego de la vida de Conway, pero en cada nueva sesión se van cambiando las restricciones, como por ejemplo, el no poder hablar con tu pareja o el hacer commits de menos de 2 minutos o el no poder retornar valores en los métodos (esta última tiene tela).

El creador y promotor de los coderetreat es Corey Haines y si no lo conocéis deberíais de hacerlo. Los facilitadores del evento nos comentaron al final que Corey quería poner su granito de arena en el evento y nos regaló su libro Understanding the Four Rules of Simple Design, que tiene muy buena pinta.

El evento

Este evento congregó a 45 desarrolladores, donde se encontraba gente de todos los niveles, desde gente veterana a jóvenes sin casi experiencia.

Los facilitadores del coderetreat fueron Stefan Hendriks y Bart Bakker. También creo que fueron los organizadores del mismo junto con Blue4IT.
Tuve que hacerles varias preguntas en las sesiones y me ayudaron mucho a encaminar las sesiones.
Stefan va a estar libre en Octubre a si que si necesitáis algún desarrollador Java o Ruby no dudéis en contactar con él.


La comida estuvo a cargo de Blue4IT y fue muy completa. Nada de pizzas para todos, sino que había todo tipo de comidas: hamburguesas, ensaladas, gambas, todo tipo de salsas y un largo etcetera.




También recibimos un regalo de ellos: un paraguas que aguanta fuertes vientos. Porque no debemos olvidemos que estamos en Holanda :-)

En cuanto a mí, en todas las sesiones programé en Java y en todas y en cada una de las sesiones me divertí y aprendí cosas nuevas.

Ideas

Algunas ideas que me surgieron a partir del evento:
  • Todos en el evento hablaban en Holandés excepto yo. "Gracias" a mi el evento fue en inglés en vez de en holandés. Naturalmente, a nadie le molestó ni tuve ningún problema al respecto pero creo que a la larga es importante que aprenda holandés para estar mas metido en la comunidad.
  • Me extrañó que con la cantidad de gente que había ninguno quería programar en Javascript conmigo. La mayoría eran desarrolladores principalmente en Java. Parece que si te gusta Java no te puede gustar Javascript.
  • Unos cuantos me comentaron lo que mola Scala y la verdad es que entraron ganas de probarlo.
  • No solo se aprende programando, sino que aprendí mucho en las conversaciones con la gente. Creo que la gente está más predispuesta a hablar de forma sincera en este tipo de eventos.


Retrospectiva

Al final hicimos un retrospectiva intentando responder a tres preguntas relativas al coderetreat, y estas fueron mis respuestas:

  • ¿Qué es lo que me ha sorprendido?
Lo que más me ha sorprendido es lo divertido que es programar en pareja cuando tienes experiencia con TDD. La primera vez que fui a un coderetreat no la tenía y no fue ni la mitad de divertido.
  • ¿Qué es lo que he aprendido?
He aprendido muchas cosas, pero creo que la más importante es lo importante que es que el test unitario sea fácil de entender.
Me dí cuenta de esto cuando estábamos en la sesión en la que no podíamos hablar con nuestra pareja.
  • ¿Qué es lo que voy a hacer diferente el lunes?
Hacer commits más pequeños.


Algunas fotos del evento aquí y para finalizar una foto (gracias a Derk Dukker) en la que aparezco :-)






(*) No es necesario practicar o tener cierta experiencia con TDD para disfrutar del evento.

La primera foto es de Projectenbank Cultuurhistorie y las demás son de Michel van Dongen, el director de Blue4IT.

jueves, 4 de septiembre de 2014

Por qué escribir test unitarios

El otro día leí un artículo de Gil Zilberfeld sobre la economía de los test unitarios.
En la siguiente dirección podéis encontrar un enlace a su blog:

http://www.gilzilberfeld.com/2014/09/the-economics-of-unit-testing.html

Básicamente lo que quiere decir el artículo es que:

Escribir test unitarios te permite ganar dinero

Así de simple.

¿Y cómo lo hacen? De la siguiente manera:
  • Escribir test unitarios hace que el tiempo en liberar cada versión se reduzca
  • Si el tiempo en cada versión se reduce, puedes vender tu producto y las nuevas funcionalidades antes. 
  • Además el números de errores (bugs) se reduce por lo que podemos dedicar más tiempo a nuevas funcionalidades.
Pero, ¿cómo puede reducir el tiempo en liberar cada versión? Muy fácil, porque aunque el tiempo dedicado al desarrollo aumenta, el tiempo dedicado a pruebas (testing) se reduce drasticamente.

Tengo que decir que, en mi experiencia, escribiendo test unitario he reducido mucho el tiempo dedico a probar a pruebas. Además, también he comprado que el número de errores se han reduce considerablemente. Por lo que ambas afirmaciones son ciertas.

Claro que hay que dedicar tiempo al principio a aprender como escribir test unitario pero en cuanto el equipo aprende vamos a conseguir los beneficios que he comentado anteriormente.

En resumen y como dice el autor del blog:

Unit testing shortens the current and future release cycles at the expense of initial extra development work.
Los test unitarios reducen el actual y futuros ciclos de liberación de versiones, a costa de un trabajo extra inicial de desarrollo.

El por qué de este artículo

Como te debes haber dado cuenta, me he dedicado hasta aquí a resumir el artículo de Gil Zilberfeld, pero la idea de este artículo es otra.
Creo que si queremos "vender" a nuestros compañeros, jefes o amigos el por qué debemos utilizar test unitarios esta es la mejor forma de hacerlo.
Primero, porque estamos utilizando un lenguaje que todo el mundo entiendo. 
Y segundo, porque al fin y al cabo nosotros estamos trabajando por dinero y el dinero es un lenguaje que todo el mundo entiende.

Por otro lado, si sólo quieres empezar a escribir test unitarios no necesitas pedir permiso a nadie. Puedes empezar hoy mismo a hacerlo. A la larga verás como fue una buena decisión.

* Modificado 12-09-09: Corregidos algunos errores gramaticales