¿El emperador está en pelotas?
Sinceramente espero que no, pero a veces la fe me flaquea ;-)

Os contaré una pequeña historia, y saldré un poco del armario en el proceso: antes de trabajar en serio con Rails y Ruby, nunca jamás había desarrollado con tests, y ni siquiera tenía muy claro cuáles podían ser las ventajas de hacerlo, ni cómo funcionaba el asunto. Fue la exposición a la (nunca suficientemente alabada) comunidad rubista y railera la que me hizo llegar a donde estoy hoy y llevo ya algún tiempo: a pensar que el testing es La Manera Correcta De Hacer Las Cosas™ (con toda la cautela e ironía que siempre lleva esa frase saliendo de mi boca). Quiero decir que todo lo que sé y opino acerca de testing, TDD, BDD, etc., es lo que he aprendido en estos casi cuatro años; no es poco, pero tampoco puede decirse que sea una visión muy general ni universal. Vaya eso por delante.
Durante este tiempo, mi arsenal de herramientas y técnicas ha ido creciendo y cambiando: Test::Unit, Shoulda, mocking, RSpec, integración contínua, tests de integración y aceptación, Cucumber, Selenium. El patrón de adopción era siempre similar: algo que te hacía perder un poco de productividad y velocidad de desarrollo, a cambio de mejorar la calidad de tu código, su mantenibilidad y en general su capacidad para no darte problemas en el futuro. De alguna forma, era el proceso contrario a la contracción de deuda técnica: comprabas productividad a medio y largo plazo pagándola con productividad a corto plazo. Suponiendo que el mundo no se acabe mañana, parece una buena idea, funcionaba y todo el mundo era feliz. Expresabas tus fuertes opiniones a los cuatro vientos, eras respetado por tu compromiso con el código de calidad, te ofrecían trabajar en proyectos la hostia de chulos, dabas conferencias, y ponías la palabra TESTING así en mayúsculas y a todo lo que da en pantallas de 4 metros.
Mientras tanto, en otro rincón de la galaxia (que sin embargo era básicamente el mismo), un grupo de entusiastas rubistas de Madrid andaba montando periódicamente Monsters of Ruby (también conocido en una de sus encarnaciones como Rails Hackathon). En el más reciente (semana pasada), la idea era poner a varios equipos a contruir en paralelo la misma aplicación, en Rails, al objeto de compartir conocimiento, contrastar enfoques, y ya de paso echarnos unas risas compitiendo. Dado que la mayoría de los participantes están acostumbrados a usar tests, se nos ocurrió que una buena manera de especificar a los equipos cuál era su cometido era entregar un conjunto de tests que la aplicación tenía que acabar pasando. Aceptación en estado puro. Con el entusiasmo del que cree en lo que hace, montamos un conjunto de pruebas para entregar a los equipos, con lo más chipén, state-of-the-art, lo que hay que hacer ahora para impresionar a las nenas y en definitiva lo que podéis escuchar en cualquier conversación en cualquier bar del país: RSpec, Cucumber, Webrat y Selenium. Como dice Dani, lo único que importa es molar.
EPIC FAIL

Ni uno sólo de los equipos completó, digamos, el 25% de la aplicación. ¿En qué momento de la historia que acabo de contar se torció todo? Parecía buena idea, éramos jóvenes y entusiastas y volveríamos a hacerlo. Todos y cada uno de los cambios de herramientas de los que he hablado fueron meditados, valorados en términos de trade-off y aceptados porque compensaban. El problema es que todos esos cambios eran paulatinos y apenas perceptibles en términos de productividad. Y tres años después, allí estábamos 3 desarrolladores competentes 3, necesitando una tarde entera para fabricar un formulario, un dolor de cabeza, unas ganas de llorar y un apetitoso perolo de sopa de rana. Ancas de batracio deconstruídas en salsa de desarrollador.

¿La conclusión? Parece ser que hemos estado viviendo una alucinación colectiva, nos hemos engañado los unos a los otros, nos hemos metido en una espiral de pérdida de productividad tan gradual como imparable, igual que la pobre rana que acaba cociéndose sin siquiera darse cuenta. El emperador está desnudo, y ha bastado un proyecto suficientemente simple e inocente (como un niño) para gritarlo a los cuatro vientos. No tiene sentido testear exhaustivamente una aplicación, sólo sirve para perder el tiempo.
Que levanten la mano los inocentones que piensen que el post acaba aquí =;-)
Esa conclusión puede ser una verdad clara y confortable, como las que necesitas en momentos de desasosiego, pero tiene mucho de equivocada. Ha habido en mi discurso unos cuantos argumentos algo mentirosos:
- He hablado mucho de productividad, y con razón: es lo que debe guiar en todo momento nuestras decisiones. Lo que construímos en relación a los recursos (principalmente el tiempo) que empleamos para ello es lo único que da valor a nuestro trabajo. Si escribimos el código más elegante del mundo pero no somos productivos, no somos buenos programadores. El problema es cómo medirlo, y no voy a explayarme mucho porque hay ríos de tinta sobre ello. Un resumen rápido: simplemente, no se puede
- También he hablado de trade-off entre productividad a corto plazo y productividad a medio/largo plazo. Aún en el caso de que pudiéramos medirla, ¿cuál es el tipo de interés de la productividad? No parece muy razonable invertir 1 hora hoy a cambio de 1 hora dentro de un mes. Pero, ¿y de 2, y de 3? ¿Dónde está el límite, cuánto tengo que obtener, para convertir una pérdida de tiempo en una buena idea? Tampoco lo sabemos
- Resulta que en el proyecto que nos ocupaba no existía el largo plazo. Era un juego que duraba una tarde. En ese contexto (en el que el mundo se acaba mañana), no tiene sentido invertir
- Hay otros factores que influyen en la rentabilidad de esa inversión: el tamaño y la complejidad del proyecto. Son variables también difíciles de medir, pero cuanto mayor y más complejo, más rentable será cualquier inversión en mantenibilidad (que es lo que hacemos al testear). En proyectos pequeños y simples, es menos interesante invertir
- La relación entre tamaño y complejidad (aun cuando no es fácil medirlos) no es lineal. Un proyecto el doble de grande que otro (signifique eso lo que signifique), es más que el doble de complejo. Esto multiplica el efecto del punto anterior
Teniendo esto en cuenta, la conclusión no es tan clara y confortable, y además no es nada novedosa, y es que no hay herramientas ni técnicas correctas, sino herramientas y técnicas apropiadas para una tarea concreta. ¿Necesitábamos alforjas para este viaje? Probablemente no, pero puede servirnos para recalcar más aún la importancia de evaluar cómo vamos a enfocar cada proyecto, y no dejarnos llevar por la inercia. Aplicar un enfoque de testing tan exhaustivo a un proyecto simple y tan limitado en el tiempo pudo ser un EPIC FAIL (lo fue), pero eso no significa que en otro proyecto lo sea. Y de hecho, creo que en algunos (por ejemplo el nuestro actual) el EPIC FAIL sería el enfoque contrario.
El emperador está bien vestido y abrigado, lo que pasa es que el sábado fue a la playa y pasó un calor de cojones el pobre ;-)






Raúl Murciano dijo
Lo has clavado uanmortaim :D Mucha gente queda impresionada por el aumento de productividad que notan cuando pasan de tecnologías más pesadas a Rails. Claro, a lo bueno se acostumbra uno rápido ;) y cuando llega alguien intentando que prueben a desarrollar con tests les entra la flojera: les parece más lento y farragoso y tienen miedo de estar dando un paso atrás. Les entiendo, yo pensaba lo mismo.
Ahora creo que escribir código es, dentro del proceso de desarrollo, el recurso más barato. Mantenerlo es más caro, y este coste con el tamaño del proyecto (hay que comprobar que cada cambio introducido no ha roto nada) y con el paso del tiempo (hay que recordar qué hacía cada parte del código, cómo interacciona con las demás...). Si entra más gente en el proyecto, el coste es mayor aún.
Los tests, entre otras cosas, ayudan a comprobar que los cambios no rompen nada y a documentar cómo funciona una aplicación, y creo que sólo por esto ya merece la pena hacerlos... siempre y cuando el proyecto vaya a estar activo algo más que unas horas XD
30 Abril 2009 | 02:12 AM