Publicidad:
La Coctelera

Sugerencia de presentación

He nacido para vago

30 Abril 2009

¿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 ;-)

servido por porras 10 comentarios compártelo

10 comentarios · Escribe aquí tu comentario

Raúl Murciano

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

Xavier Noria

Xavier Noria dijo

Peasso de post :).

Yo aprendi el valor del testing en la comunidad Perl que por lo general es hasta mas comprometida con el testing que la comunidad Ruby. Corre la idea de que Ruby y Rails han traido el testing al mundo como aquel que dice, se lo he oido hasta a Obie, pero es un mito.

En Perl hace años que es etiqueta que un modulo de CPAN tenga una test suite del copon, que ademas *corre en local* como parte del proceso de instalacion estandard. Y tambien hace tiempo que existen los CPAN Testers, que son voluntarios que corren las test suites en distintas maquinas. Vease el impagable valor que tiene para mi saber que este modulo que ademas es medio C funciona en todas estas versiones y arquitecturas:

http://testers.cpan.org/show/Algorithm-Combinatorics.html

jamas podria tener esa tranquilidad por mi mismo. Y lo mas util es cuando hay rojos, porque la test suite pasaba en tu maquina!

Bueno, que estoy divagando. Queria decir que lo veo igual que tu. Hay que hacer testing, pero el momento de hacerlo en mi opinion depende. Ya aviso que a mi el TDD no me va, me va el testing, pero el TDD no va conmigo. Es algo personal, de como funciono, por supuesto entiendo que otra gente se sienta como pez en el agua en ese workflow.

Por ejemplo, en un proyecto muy iterativo con requisitos cambiantes y agilidad para implementarlos bajo mi punto de vista mantener una test suite es una perdida de tiempo, a la semana tienes que reescribirla por completo, y a la otra. En un proyecto asi yo prefiero esperar a que la aplicacion converja, y cuando la cosa esta mas o menos calmada entonces me meto con la test suite.

Hay gente que cree que esa test suite no sale buena. No se si esa duda es fundada, pero al menos las que yo hago tienen tanto coverage y van tan a putear y a buscar casos frontera como las de cualquiera.

Un proyecto mas ordenado (supuesto que tal cosa exista :) puede crecer con su test suite en paralelo. Un proyecto en mantenimiento o tiene una test suite de puta madre o es un infierno.

En definitiva, creo que para decidir cuando escribir la test suite hay que aplicar sentido comun al proyecto en el que estas, y tener el pulso de la productividad (entendida no en terminos managerianos, sino como ese feeling que tiene uno de que saca faena razonablemente y que en general nos ha hecho andar por los lenguajes dinamicos :).

30 Abril 2009 | 02:36 AM

Mari Carmen Gutierrez de la Ossa

Mari Carmen Gutierrez de la Ossa dijo

Siempre aprendo cuando leo tu blog, no sólo por tus posts sino por el feedback que despiertas :-). Celebro que hayas vuelto a derramar tus conclusiones por aquí, hasta tal punto que a estas horas de la mañana me haya leído de cabo a rabo y atentamente toda tu exposición te debería dar qué pensar. Eres grande Porras!! :-D

30 Abril 2009 | 06:01 AM

estrelase

estrelase dijo

Cada día estás peor.

30 Abril 2009 | 07:57 AM

Raúl Murciano

Raúl Murciano dijo

Cuanto más conozco de la comunidad Perl más me arrepiento de haberla ignorado durante todo este tiempo :P

Coincido también con la segunda parte del comentario de Xavi: muchas veces el cliente prefiere empezar el desarrollo sin tener claras las funcionalidades y en ese caso realmente estás prototipando y testear en esa fase me parece tiempo perdido (en la confe rails comenté que con domestika.org llegué justo a esta misma conclusión).

Sobre el TDD: lo aplico cuando tengo clara una funcionalidad y como herramienta de diseño, cuando no tengo claro cómo definir algo en mi código. Cuando no es así suelo aplicar tests a posteriori para confirmar que el código trabaja bien en casos límite o para detectar que un bug no se vuelve a producir.

En el BDD no me meto: aún no le he hincado el diente porque no consigo integrarlo en mi forma de trabajar. Supongo que será fácil de aplicar en proyectos propios porque tú tienes la libertad de modificar el comportamiento mientras estás escribiendo los tests, pero cuando el comportamiento lo define el cliente no le termino de ver las ventajas sobre el testeo tradicional.

30 Abril 2009 | 08:58 AM

Luismi Cavallé

Luismi Cavallé dijo

Excelente post, sí señor. Me gustaría comentar acerca del corto plazo. A menudo hablamos acerca del testing y de los beneficios que aporta en el medio y largo plazo a costa del corto plazo. No estoy completamente de acuerdo con que inevitablemente solo haya un perjuicio en el corto plazo.

Corey Haines, uno de los tipos detrás del movimiento del Software Craftmanship, mantiene que el conjunto de prácticas y técnicas de uno es aquel que emplea cuando el tiempo aprieta y el proyecto necesita resultados rápidos. En este situación a menudo renunciamos a determinados "lujos" como el testing o el refactoring. Según Corey si esto es así, entonces es que el testing no es una de tus prácticas, pues no te sirve cuando más falta te hace.

Testear es solo una herramienta. También lo es emacs y quien realmente ha invertido tiempo y esfuerzo en aprender a usarlo eficientemente, no renunciará a emacs en favor del bloc de notas de windows cuando tenga prisa. Al contrario.

Entre los beneficios en cuanto a productividad que puede aportar el testing a corto plazo se me ocurren varios: proporcionan un criterio del "hecho" (saber cuando has acabado), tienden a evitar la sobreingeniería y perder tiempo resolviendo problemas que no tienes hoy, minimizan el tiempo antes de ponerte a escribir código al sustituir a la fase de diseño, etc. Todo ello, desde luego, utilizando las técnicas de testing adecuadas al tipo de proyecto y haciéndolo de manera efectiva. Uno no es eficiente con emacs el primer día que lo utiliza. Al contrario, es menos eficiente que con cualquier otra cosa.

En definitiva, pienso que la discusión correcta no es la de cuánto testing necesito (o si testeo o no) en determinado proyecto, sino la de **cómo** testeo, teniendo en cuenta tanto las características del proyecto y como las habilidades del equipo, para maximizar la productividad a medio, largo, pero también, a corto plazo.

30 Abril 2009 | 09:40 AM

Francisco Javier Guzmán Rivas

Francisco Javier Guzmán Rivas dijo

Muy buen post!! Seguro que podemos mostrar a ciertos "managerianos" las indudables ventajas del buen testing.

30 Abril 2009 | 09:52 AM

cientifico

cientifico dijo

Si MOR2 te ha hecho llegar a estas conclusiones... MOR2 se puede tachar de éxito rotundo.

30 Abril 2009 | 10:30 AM

Raimond Garcia

Raimond Garcia dijo

Muy interesantes porras siento que fuera un pequeño infierno usar cucumber en el MOR2 :(

Como sabes cada día estoy mas metido en el tema de cucumber/tests y lo voy a intentar seguir defendiendo...

Las ventajas a medio y largo plazo creo que están bastante aceptadas entre todos, la discusión es a corto plazo.

En mi opinión, aunque sea un proyecto pequeño y sin estar bien definido, excepto en casos como un programa por puro disfrute, por jugar con una herramienta nuevo u otros casos excepcionales, hacer tests es esencial, si son antes de la implementación mejor, si son después pues muy bien también, pero como recalca Lusimi, lo importante es *como* hacemos esos tests. Si la implementación va a estar cambiando cada día, no conviene usar muchos mocks, si son los requerimientos que van cambiando cada día
pues inevitablemente aunque se hayan hechos los tests desde un enfoque clasicista habrá que cambiarlos.

Esto es un drawback porque tienes que cambiar los tests, pero creo que compensa no tener que probar la funcionalidad manualmente de todo lo demás que has desarrollado en el proyecto. Creo que aquí viene la definición de un proyecto no solo productivo sino de calidad.

Si definimos la calidad como la visión que tiene nuestro cliente de nosotros y la calidad de nuestra vida como desarrolladores, el hecho de no tener que manualmente confirmar que nuestra aplicación sigue funcionando al introducir un cambio, ni que el cliente nos mande un email diciendo que ha dejado de funcionar una parte de la aplicación, incrementa la calidad percibida por el cliente y la que nosotros entendemos de nuestro propio trabajo.

También, me doy cuenta, de que una simple conversación con el cliente deja muchos cosas sin definir, ahora bien, cuando empiezas a escribir los tests es cuando te das cuenta de todas esta preguntas que tendrías que haber hecho o que el cliente te *tendría* que haber comentado, pero ni uno ni otro pensamos en ello o bien porque asumimos que entendíamos los requerimientos o bien porque el cliente asumía que entendíamos el modelo de negocio con la misma profundidad que el.

Dicho esto, también es cierto que en un proyecto de un día o dos en un proyecto personal, no comercial y por puro disfrute de programar, no compensa pasarse la mitad del tiempo escribiendo tests. Pero este problema en vez de achacarlo a escribir tests o no, creo que lo que hace es abrir la puerta y la imaginación, a como escribimos los tests y las herramientas que utilizamos para escribirlos.

En el caso hipotético (espero real dentro de poco) de que los tests estén ya escritos y definidos en el lenguaje de programación escogido, ruby, java, php, .NET, y que lo único que haya que hacer sea escribir la implementación que los hagan pasar, no hay razón para no utilizar tests, ya que es igual de rápido usarlos que no usarlos.

Un ejemplo son los tests relacionados con los emails. Si ya tienes todos los steps definidos de como testear las funcionalidad de emails, es tan fácil como escribir en texto plano usando un autocomplete de steps, las 20-30 lineas que lo testen.

Si el desarrollo en estas colecciones de steps no están bien definidas en casos como selenium, es un problema de todos, es necesario crear las gemas, plugins o simples repositorios donde estarían estos steps definidos para su uso de inmediato por cualquier desarrollador (póngase el ejemplo, muy dicil de testear hoy, como es el autocomplete en un formulario de una manera exhaustiva). Siempre habrán tests que no se puedan reusar pero también habrá mucho sitio para tests que si se puedan reusar en múltiples aplicaciones.

Ahora bien, siempre hay que pensar en el aspecto pragmático, y en un proyecto muy corto y no comercial igual no compensa pasarse 8 horas escribiendo una seria de steps reusables en cualquier otro proyecto. Si después lo va a usar la gente, pues apreciarían un test suite para extenderlo con tranquilidad, si no lo va a usar nadie, ni el propio creador, pues mira me parece bien no escribir ni un solo test y dedicarme a otras cosas.

Todo depende del contexto, por supuesto, pero el uso de tests hoy en la mayoría de proyectos tiene ventajas imposibles de cuantificar en tiempo pero sin duda muy grandes para el mañana.

Viva Cucumber y Vivan los TESTS.

11 Mayo 2009 | 03:17 PM

Escribe tu comentario


Sobre mí

Avatar de porras

Sugerencia de presentación

ver perfil »
contacto »

Me llamo Sergio Gil Pérez de la Manga, y mi madre se cabrea si escribo mi nombre con un sólo apellido. Vivo, trabajo y hago casi todo lo demás en Madrid.

Trabajo como programador porque es lo más parecido que he encontrado a no trabajar. Sobre todo si lo haces bien. Y en eso estoy, en hacerlo cada vez mejor para trabajar cada vez menos. Alguno lo llamaría vagancia, y yo ahí no me meto.

Algunas de las herramientas que en este momento me llevan al Nirvana de no dar un palo al agua son Ruby, Ruby on Rails, Textmate, cualquier sabor de Unix (en este momento principalmente MacOSX pero también Ubuntu Linux) y sus herramientas, o Rake. En ocasiones hablo de ellas aquí, pienso que a alguien le pueden servir y que no puedo ser el único al que no le gusta trabajar.

Y como no sólo de tecnología vive el hombre (bueno, el hombre no sé, pero desde luego yo no), por aquí aparece de vez en cuando la punta del iceberg de mis pequeños pensamientos; al menos la parte de ellos que no cabe en Twitter.

Bienvenidos todos.

Y ahora: ¿Y tú?

Fotos

porras todavía no ha subido ninguna foto.

¡Anímale a hacerlo!

Buscar

suscríbete

Selecciona el agregador que utilices para suscribirte a este blog (también puedes obtener la URL de los feeds):

¿Qué es esto?

Crea tu blog gratis en La Coctelera