Approval Tests: Sí pero…

La mejor manera de formarse una opinión sobre algo es conocerlo y ahora tengo la excusa del blog para eso. Leo sobre algo que me llama la atención, hago alguna prueba con ello para poder escribir un post y eso me permite verlo desde una perspectiva diferente. Es lo que hice con los mixins en C#, con javascript y, en mi anterior post, con los test de aprobación.

Ahora que tengo una gran experiencia un conocimiento básico (pero de primera mano, eso sí) sobre los tests de aprobación, tengo más claras algunas cosas que me gustan y otras que no tanto.

Cosas que me gustan

Hay casos en que pueden funcionar muy bien, especialmente cuando la salida del test es directamente algo en formato texto: html, xml, csv… En esas situaciones me parece más cómoda la “aprobación humana” que andar parseando el texto o usando expresiones regulares para validar el test.

Al final acaba siendo tan complicada (y a veces tan frágil) la validación tradicional con asserts que no merece la pena porque es casi igual de fácil introducir errores en la validación que en el código testeado. Para eso es mejor aplicar el sistema de aprobación. Recientemente he tenido que implementar en mi trabajo del Mundo Real™ un generador de etiquetas en formato EPL y hubiera sido bastante práctico usar tests de aprobación, porque al final todo se reducía a validar que un fichero de texto era correcto.

Hay otros casos en que se acaban escribiendo los tests siguiendo un proceso similar: se escribe el código (o se toma una parte de código que ya existía), se ejecuta con varios casos de prueba y luego se añaden asserts con los resultados. Esto es especialmente útil cuando queremos caracterizar el comportamiento de código heredado antes de empezar a refactorizarlo. Este flujo de trabajo (tal alejado del Red, Green, Refactor de TDD) cuadra muy bien con los tests de aprobación.

También me parece interesante la posibilidad de testear cosas que son muy complicadas de testear de otra manera, como informes Rdlc o WebForms (alternativa para WebForms).

Cosas que no me gustan

En realidad, es muy posible que parte de estas cosas que no me gustan sean debidas a que no conozco en profundidad este tipo de tests y seguramente sean solventables.

Una de las cosas que me llamó la atención al principio fue la posibilidad de testear WinForms, aunque fuese mediante lo que podríamos considerar tests de humo, usando WinForms.Approvals.Approve, que realiza una captura de pantalla del Form para que sea aprobada o rechazada.

Sin embargo, aunque la idea de la captura de pantalla me parece original, al final resulta en un test demasiado frágil que depende de cosas tan básicas como la configuración de colores que tengas puesta en Windows. Si dos miembros del equipo de desarrollo tienen distinta configuración de colores, el test fallará en uno de los dos equipos porque el borde de la ventana es diferente, aunque el contenido sea el mismo.

Otro punto que no sé como resolver es que el sistema de reporters para comparar el resultado de los tests no se lleva bien con un servidor de integración continua. Por ejemplo, si tienes marcado el test para usar el DiffReporter que lanza el Tortoise Diff como hacíamos en el ejemplo del post anterior, es muy cómodo durante el desarrollo, pero no tiene mucho sentido en el servidor de integración y de hecho acabaríamos con el servidor lleno de instancias de Tortoise Diff en ejecución.

No veo una forma fácil de configurar el reporter a utilizar en función del tipo de compilación que estemos haciendo (desarrollo vs integración) y eso hace que sea incómodo trabajar con ellos.

En resumen

Aunque tengan sus pegas, creo que los tests de aprobación pueden ser útiles en ciertos casos y, de todas formas, siempre es bueno conocer más herramientas que pueden ser de utilidad en algún momento determinado y ahora conozco otra: los tests de aprobación.

No descarto aplicarlos en algún proyecto y, seguramente, al hacerlo, encuentre la forma de solucionar algunos de los problemas que he visto y, por supuesto, también descubra nuevos problemas. Vamos, lo de siempre.