Mostrando entradas con la etiqueta testing. Mostrar todas las entradas
Mostrando entradas con la etiqueta testing. Mostrar todas las entradas

martes, septiembre 20, 2011

Gerrit, un sistema de revisión de código muy jugoso

martes, septiembre 20, 2011 por Martín

Hace unos días charlaba placidamente en una terraza de Santiago de Compostela con @pepellou y @carlisgg sobre lo interesante que era Gerrit y como resultaba curioso que un sistema basado en un repositorio de Git era la solución más natural a uno de los problemas más tradicionales de las organizaciones con muchos desarrolladores, que era el mantener la build intacta.

Tenía pendiente escribir sobre esto, pero además es que justo hoy @psluaces referencia en un comentario en el post sobre las desventajas de las ramas de desarrollo un artículo suyo, también interesante, donde se explican algunos de los problemas que alivia Gerrit. Así que, ¡qué gran excusa para ponerse a hacer los deberes y escribir este post que tenía pendiente!

lunes, enero 31, 2011

Niveles de felicidad en el testing

lunes, enero 31, 2011 por Martín

En la lista de Agile Spain se está comentando un artículo muy interesante de UncleBob sobre sobre Scrum y TDD y donde Leo Antoli pregunta si se están dejando de lado las capacidades de TDD como técnica para dirigir el diseño de un sistema.

Mi opinión al respecto está en el hilo y no quería entrar demasiado en ella en este artículo. Básicamente es que veo dos líneas en TDD. Una es la centrada puramente en testing, donde gira todo en torno a JUnit y tener barras verdes, y que personalmente creo que no es aplicable a diseños complejos y serios (ojo que no digo que no se haga TDD, sino sólo que en ese contexto no me parece una técnica aplicable a a dirigir nuestros diseños) ya que tiende a la sobre-simplificación de los sistemas y a un microdiseño o microtesting.

sábado, marzo 20, 2010

La horda de testers

sábado, marzo 20, 2010 por Martín

El término Mongolian Horde proviene de las hordas mongolas de Genghis Khan y sus hijos que conquistaron gran parte de Asia y Europa durante los siglos 13 y 14. La estrategia que seguían en sus combates era lanzar miles y miles de soldados contra sus enemigos sobrepasándolos en número y consiguiendo victorias sencillas.



Mongolian Horde es un término que se utiliza en la actualidad en el mundo de los negocios al tratar de resolver un problema a base de asignar más y más personas a la resolución del mismo, pensando (muchas veces inocentemente) que el disponer de más personas asignadas a una tarea hará que ésta llegue satisfactoriamente a su fin. En el mundo del software este término toma relevancia especial por lo habitual que han llegado a ser este tipo de situaciones. George Stepanek lo explica muy bien en su libro "Why software projects fail":

A naive project manager who saw developers as equivalent to each other would be tempted to use the so-called "Mongolian Horde" approach, which uses a large number of cheap and inexperienced developers. Just as with the original Horde, the end result is chaos. Even allowing for their limited design and programming skills, the developers just don't have the experience to organize and deliver a system of this scale.

Some developers can even bring negative productivity to a team. They may not understand the sophistication of the team's code, and will introduce bugs that require lots of rework. They may demand so much help that their own work fails to compensate for the lost productivity of the other team members...


En uno de los últimos proyectos en los que he trabajado me encontré con algo muy similar, pero en un campo en el que nunca lo había experimentado, que es el del testing de programas. Tener testers no es algo demasiado habitual en España, salvo en grandes empresas, mientras que en Irlanda era el pan nuestro de cada día. En todos los proyectos en los que participé había un departamento separado de pruebas. No sólo eso, los testers no tenían idea de programación, ni siquiera eran informáticos. La idea es en este caso tener personas con experiencia en el negocio que aunque no esan informáticos sepan realmente como debe funcionar la aplicación, y no tenga ideas preconcebidas sobre desarrollo de software sino que se comporten como meros usuarios. No es mala idea, pero eso es otro tema.

El caso es que en uno de estos proyectos estaban unos ocho testers. Pero había un problema, nuestro software, que básicamente era una conversión entre formatos de ficheros para entornos bancarios, tenía miles y miles de posibles entradas y salidas. El equipo de testers era muy tradicional, y su lider se negaba a recibir cualquier tipo de ayuda de automatización. Esto hacía que cada vez que lanzábamos una release, que era tras tres semanas porque en desarrollo seguíamos el dictamen Agile, tenían que probar todas esas combinaciones manualmente. Algo totalmente imposible. Nunca llegaban al 20% de pruebas, así que poco a poco el producto iba ganando más y más bugs lo que nos afectaba a desarrollo.

La solución ideada por los managers fue crear una Horda de testers. Contrataron más personas e incluso una agencia externa de testing. Llegó a haber un equipo de 38 testers!!! ¿Os lo podéis imaginar en una empresa que no llega a los 100 empleados? Ni que decir tiene que la iniciativa fue un fracaso. Ellos mismos se dieron cuenta de que tener más testers no significa probar más y mejor la aplicación. De hecho el número de errores aumentó y el número de pruebas realizada disminuyó. Era simplemente demasiado complejo el controlar y formar a tanta gente en tan poco tiempo como necesitaban.

¿Cuál fue la solución? En este caso el marrón me tocó a mi, pero desde desarrollo conseguimos convencerlos de que la única opción es que nos dejasen proporcionarles herramientas para automatizar su trabajo. Lo que hicimos fue separar un grupo de swats (desarrolladores kamikaze jejeje) que creamos un sistema para que ellos pudiesen diseñar tests automatizables. Muy simple y en lenguaje natural. De modo que ellos definian los tests y por detrás nosotros lanzábamos sin que se diesen cuenta acciones de HTMLUnit que iban probrando las páginas webs. Imaginaros, un test podría ser:

- upload /tmp/Test1.xml
- Login:username=martin,password=martin
- click "Results"
- assertExists "Upload Test1.xml successful"
- Validate /results/Test1.xml

Esto es algo totalmente inventado, el lenguaje era incluso más sencillo que esto. Pero os da una idea. Además, los testers podían reutilizar los tests, para crear sus propias cadenas de tests más complejos. En un principio recibieron la herramienta con escepticismo. Ya sabeis, "Aquí vienen estos con más trabajo con lo ocupados que estamos". Pero en cuanto vieron que ahora podían repetir los tests cuando quisieran, que no tenían que andar continuamente haciendo el mismo setup manual, y que un test que les llevaba media hora hacerlo pasaba a llevarles un minuto, la historia cambio. En unas pocas semanas tenían automatizado el 30% del trabajo, mucho más de lo que habían conseguido nunca. Y lo más importante para nosotros, los desarrolladores, al incluir los tests en la build, teníamos garantía de que todo funcionaba.

No sé si alguno de vosotros habéis vivido una experiencia similar, pero os animo a compartirla. Espero que os haya interesado mi historieta.

viernes, diciembre 11, 2009

Podcast sobre test de aplicaciones

viernes, diciembre 11, 2009 por Martín

En javaHispano han publicado un podcast hace unos días donde participan Alfredo Casado, Julio César Pérez y Jose Luis Bugarín y que se lo recomendaría a todo el mundo ya que explica muy bien el por qué es tan importante hacer testing, sus beneficios y todo lo que no perdemos al no hacerlo. Al igual que comentaba yo mismo en mi charla en Alicante, de la que todavía tengo pendiente el escribir varios posts, estamos en un momento donde una persona que no haga tests no se puede considerar un buen profesional. Señores, quitémonos el chip de monos picateclas porque el desarrollo de software es mucho más, y el testing es sólo una de las habilidades que un desarrollador ha de tener. Muy buen podcast.



El podcast lo podéis escuchar aquí mismo o descargaros el MP3 original desde la página de javaHispano.

lunes, noviembre 09, 2009

Tus builds de Hudson en Campfire

lunes, noviembre 09, 2009 por Martín

Ojeando los plugins de Hudson he descubierto de casualidad que desde hace un par de semanas está disponible un plugin para Campfire. Lo que quiere decir es que puedes configurar tus build para que publiquen sus resultados en Campfire. Para los que se nos olvida chequear el email y se nos pasa que hemos roto la build.

La página del plugin es esta y su instalación es trivial. Ojo que es necesario tener la última versión de Hudson para que funcione. Aquí tenéis el anuncio por parte de los autores. Una captura con la configuración:



Y su consiguiente resultado en Campfire:

sábado, octubre 31, 2009

¡Hay que respetar la build!

sábado, octubre 31, 2009 por Martín

En una de mis últimas empresas, allá por Irlanda (como pasa el tiempo, oiga) teníamos unos 30 desarrolladores. De entre todos estos, unos 10 estaban en Polonia, los demás estábamos en Irlanda. A parte de todo esto teníamos una consultora en el Reino Unido con unas 10 personas que se dedicaban a mantenimiento. Todas estas personas podían tocar la build.

El principal, con mayúsculas, problema con el que nos encontrábamos era la cantidad de commits que se hacían. El proyecto estaba en una fase fuerte de crecimiento así que había montones de funcionalidades que subir. Esto hacía que los commits fuesen constantes, y difíciles de controlar. Y como en toda época de rush, como no, las revisiones de código destacaban por su ausencia.

Total, que con tal cantidad de commits simultáneos, por muchos tests que hiciésemos (que se hacían) era muy habitual el romper la build. Pero ese no era el problema. El problema de verdad es que la gente seguía haciendo commits cuando la build estaba rota, lo cual presenta varios problemas:

  1. No sabes que tu código va a funcionar. Por mucho que esté funcionando en tu build local, al estar la build rota, no tienes la certeza de los cambios que ha subido otra gente, así que nunca sabes si esos cambios te pueden afectar.
  2. Si no se protege la build, os cambios se acumulan. Todos esos cambios, son cambios no probados en un entorno de integración. Cuanto más tiempo pase, más grande es el problema. Cuantos más commits se acepten con una build rota, más problemas potenciales están entrando en el código. El número de errores crece. El código se vuelve más inestable.
  3. A mayor número de cambios, más difícil es el recuperar la build. Si los cambios se van acumulando y acumulando, nos encontraremos que al corregir el primer error aparecen más errores. La única solución que queda es ir corrigiendo error tras error hasta que la build vuelva a funcionar. Cuanto más código incontrolado permitamos, más tiempo nos llevará arreglar la build.
  4. En el peor de los casos, no hay otra solución que volver atrás. En el peor de los casos nos encontraremos con que el código que se ha subido se cruza y no queda más remedio que revertir los cambios, con la consiguiente perdida de tiempo. Los equipos tendrán que pararse y ver por qué sus funcionalidades se han solapado.


Todo esto se ilustra en la captura de pantalla siguiente:



Entre 1 y 2 hay un montón de commits. Llega un momento en el que alguien se da cuenta de que se ha roto la build, y comienza el proceso de arreglar la build. En 2 se arregla algo, pero no es suficiente. En 3 algo más, pero sigue sin ser suficiente. En 4 finalmente se arregla, pero han sido necesarios 10 arreglillos para conseguirlo. Cuando si la build se hubiese arreglado en el momento de detectar el error no se hubiese perdido tanto tiempo.

¿Soluciones?

  • Involucración del equipo. La build debe de ser colectiva y todo el mundo tiene parte de responsabilidad en controlar que esté siempre sana. Muy a menudo la responsabilidad recae sobre el jefe de equipo, y si este falta se hace la vista gorda. Esto al final perjudica a todos. Si alguien ve que la build está rota, debe alertar de ello e investigar a ver qué está pasando.
  • No hacer commits si la build está rota. Tan simple como esto. Si la build se rompe, lo mejor es no hacer commits. No importa que el código sea muy urgente. Como desarrolladores, si hacemos commits, puede ser mucho peor para nosotros. Es mucho más efectivo el esperar a que la build esté estable y subir el código con la seguridad de que no vamos a romper nada. Además, así nadie nos meterá en el lio de arreglar la build después ;)
  • La técnica de la botella. Si las dos primeras no funcionan, la técnica de la botella es super-efectiva. Ya había escrito sobre eso aquí. Se compra una botella, que sea grande que hará falta. Cada vez que alguien rompe la build, se ponen 50 céntimos, un euro o algo así. Que no sean 10 céntimos porque entonces no duele demasiado :) Esto es mano de santo. En cuanto alguien ve que se va dejando un par de euros al día, pasa a ser mucho más cuidadoso con los cambios que hace. Además tras unos meses se puede hacer una cena a la salud de la build. La desventaja de este sistema es que no funciona demasiado bien con equipos deslocalizados :)
  • No permitir commits. Podríamos bloquear el repositorio de código fuente si la build se rompe. Esta es una solución bastante drástica que normalmente es perjudicial. Puede funcionar bien sólo cuando el equipo es pequeño. Si el equipo es grande y hay mucho código, esta medida tendrá el efecto de cuello de botella.
  • Revertir automáticamente el código que ha causado el error. Esta fue la medida que se aplicó en la empresa que os comentaba antes. La situación era tan complicada que no quedó más remedio que revertir de inmediato cualquier código que rompiese la build. Es un poco drástico pero dada la magnitud del problema, fue necesario. La gente comenzó a ser mucho más cuidadosa cuando veía que sus cambios se rechazaban una y otra vez.
  • Build en dos fases. En sistemas y equipos complejos. Otra alternativa es mantener dos builds. Una más inestable, en la que los desarrolladores van haciendo sus commits, y otra estable que nunca fallará. La primera sería una build permisiva, pero que como siempre, habría que respetar. La segunda aceptaría sólo código que ha pasado la primera build, y siempre estaría completamente estable. La idea es que si alguien necesita el código más reciente en cualquier momento, no tenga que esperar a que se arregle la build. Esto yo lo veo como un modelo complejo sólo apto para empresas grandes que tengan necesidades muy específicas.


En fin este tema daría para mucho hablar. Seguro que muchos estais familiarizados con el mismo y lo vivis en el día a día. Me encantaría leer vuestros comentarios y saber si tenéis este tipo de problemas y que hacéis vosotros para solucionarlos.

viernes, junio 05, 2009

Alegrarse al encontrar errores

viernes, junio 05, 2009 por Martín


No sé vosotros pero yo casi siempre me alegro de los errores que voy encontrando. Bueno, venga, estoy mintiendo. No es algo tan sencillo como, uy mira un error, que alegría. Al menos en mi interior sucede lo siguiente:

  • Primero: Cabreo. Lo reconozco, yo soy testarudo, y no me gusta equivocarme. Tampoco me gusta que se equivoque la gente con la que trabajo. Soy bastante exigente en eso. Así que mi primera reacción es cabreo, conmigo o con los demás.
  • Segundo: Alivio. Alivio por haber encontrado ese error. Si no encuentras errores, no es posible solucionarlos. Cuantos más errores encuentres, mejor será tu producto. Había alguien, no recuerdo el nombre que decía algo así como: "¿Quieres triunfar? Entonces, dobla tu tasa de fallos".
  • Por último alegría. Alegría por haber encontrado el error y haber hecho una solución. Alegría por haber creado una prueba que reproduzca el error, y haber sido capaz de reproducirlo y solucinarlo. Alegría porque ese error no volverá a suceder.


Por cierto, recupero este post en pingdom con 10 bugs que tuvieron consecuencias graves. Seguramente los autores de los programas se habrían alegrado bastante de haber encontrado los errores a tiempo.

Todo esto me vino a la cabeza a raiz de un artículo que leí hace poco, donde comentaban lo siguiente:

At a major software corporation, the CEO regularly holds parties to give out a valued award, shaped as a full-size life preserver, to individuals who have created "learning opportunities" by introducing a problem into the design. Of course, the CEO acknowledges that the problem wasn't introduced intentionally. But, because it made it into the design, the organization learned important lessons they can use going forward. Receiving the life preserver award from the CEO has become a high honor within the company.


Hombre, tampoco se trata de hacer fiestas, claro. Eso solo pueden permitírselo las major corporations. Pero bueno, quizás si sería para celebrarlo si de pronto tu servicio se cae, y descubres que no es demasiado escalable, pero todo se debe a que la gente está accediendo y comprando como loca porque tu campaña de marketing ha sido muy exitosa como comenta el artículo. Descubres el error, pero por una buena razón.

Mi aproximación ante un error siempre es la misma. Analizar el error, tratar de crear un test ya sea unitario, de integración o funcional que lo reproduzca. Solucionar el error. Muy al estilo de TDD pero para bugs.

Pero bueno, cotilleando un poco, ¿Vosotros como reaccionáis a los errores?

martes, mayo 26, 2009

Test funcionales para todos: Canoo WebTest + Grails.

martes, mayo 26, 2009 por Martín

Hace ya unos meses comentaba que Grails tenía sus cosas buenas y también sus cosas malas.

Pues bueno, el plugin de tests funcionales pasa a engrosar la lista de cosas que me gustan. Se trata de un plugin que integra Canoo WebTest, una fenomenal herramienta de testeo de la capa web.

Lo más importante que quiero destacar del artículo que estoy escribiendo es que no se limita a Grail. Este plugin simplemente se encarga de simular el acceso a páginas web y ejecutar un número de aserciones sobre las páginas. Los tests se escriben en Groovy y se necesita Grails para ejecutar, pero eso es todo. Es decir, podemos utilizar este sistema para testear cualquier aplicación web, ya esté hecha en Grails, en Java o en .NET. Y ya veréis que por lo sencillo que es, vale la pena.

Lo primero de todo es seguir las instrucciones del wiki, e instalar el plugin. Asumiendo que tenemos instalado Grails, tendríamos que:
  • Crear el proyecto: grails create-app tests
  • Instalar el plugin: grails install-plugin webtest
  • Crear la carpeta de tests: grails create-webtest

Una vez hecho esto tendremos una estructura de directorios con la configuración de los tests, los reports y una carpeta "tests" donde se irán colocando los tests funcionales. Crear un tests es insultántemente sencillo, y treméndamente intuitivo. Tan sólo es cuestión de saber como trasladar el conjunto de tareas de WebTest a Groovy. Pero entre los ejemplos, y lo sencillo que es, pues no debería haber ningún problema.

Fijaros en el siguiente ejemplo de un test funcional que tenemos en Jobsket para comprobar que los perfiles de Linkedin se importan correctamente:
def testLinkedinUpload() {

invoke      '/login'
verifyText  'Entra en Jobsket'
setInputField(name:'login',value:"${user}")
setInputField(name:'password',value:"${password}")
clickButton 'Entra'

invoke '/upload/linkedin'

setInputField(name:'profile',value:'http://www.linkedin.com/in/mpermar')
setCheckbox(name:'legalAccepted')
clickButton '!Sube tu CV desde Linkedin!'

verifyText 'Tu CV'
}


¿Es necesario que explique algo del test? Nada de código Java, nada de XML, nada de scripting raro. No os exagero, hacer tests funcionales con Grails y WebTest es una gozada. El código es muy sencillo de leer, y además al ser Groovy sigues teniendo la potencia que te ofrece un lenguaje orientado a objetos y puedes agrupar funcionalidad común a los tests en otras clases. Pues por ejemplo agrupar la parte de login de ahí arriba en un método login que pondríamos en una clase padre. Es un ejemplo.

Quedaría simplemente ejecutar el test:
  • grails run-webtest MiTest

Una vez se ejecutan los tests, los informes se pueden ver desde la web:



Y nada más. Simplemente resaltar lo comentado. Si estás haciendo un proyecto web, y buscas una herramienta para ejecutar tests funcionales, entonces Grails + Canoo WebTest es una opción muy recomendable. Además se integra muy bien con Hudson, pero eso lo dejo ya para otra entrada :)

viernes, noviembre 07, 2008

Configurando Hudson para proyectos Grails

viernes, noviembre 07, 2008 por Martín

Como parte del desarrollo de Jobsket, una de las cosas que hemos hecho es el preparar un servidor de integración continua para intentar mantener nuestras builds lo más estable que sea posible.

Grails, no tiene ningún plug-in ni soporte específico para ningún sistema de integración continua así que decidimos descargarnos e instalar Hudson. La principal razón para instalar este sistema de integración continua es que es muy sencillo de instalar y administrar, ya que toda la configuración se realiza desde el UI de la propia aplicación, con sus bonitos componentes AJAX, sin necesidad de andar tocando ficheros de configuración.

Hudson está por defecto preparado para trabajar con Java, pero configurarlo con otros lenguajes o frameworks no debería dar ningún problema. Aquí no os voy a aburrir con los pasos para instalar y configurar Hudson, sino que comento simplemente los cambios necesarios para integrar un proyecto de Grails son tan sólo dos y son realmente muy simples:

Primeramente configuramos nuestra build para ejecutar un shell script. Este script contendría los pasos necesarios para la ejecutar nuestros tests o la build o lo que queráis. En nuestro caso el script es realmente sencillo ya que simplemente estamos interesados en ejecutar los tests, pero si tenéis otros requisitos podéis ejecutar directamente cualquier script de Ant o Gant, lanzar Maven, o lo que sea.



Lo segundo es simplemente hacer que Hudson lea nuestros informes de test. Por defecto Grails los coloca en el directorio test/reports, así que simplemente le decimos a Hudson que los busque ahí:



Una última cosa importante que no he comentado es que no os debéis olvidar de ajustar todos los settings necesarios para ejecutar grails, como por ejemplo:

export PATH=$PATH:/opt/grails-1.0.1/bin
export JAVA_HOME=/opt/java/jdk1.6.0_03
export GRAILS_HOME=/opt/grails-1.0.1


Hudson te permite configurar desde el UI la JAVA_HOME pero el resto lo tendréis (creo) que añadir vosotros en alguna otra parte. Yo por ejemplo tengo todo esto en el script que se arranca al loggearse el usuario, pero vosotros lo podéis poner donde queráis, como por ejemplo en el script que vimos antes que ejecuta los tests.

Pues eso es todo, no debería llevar más de 10 minutillos. Rápido y sencillo.

jueves, abril 17, 2008

Aer Lingus automatiza el testeo de su web con Selenium

jueves, abril 17, 2008 por Martín

En SiliconRepublic, que es la publicación tecnológica online irlandesa por excelencia, hablan de como Aer Lingus ha automatizado el testeo de su web con Selenium. Me he animado a comentar esta noticia en el blog porque considero que muestra varios aspectos muy interesantes.

Lo primero es como una herramienta como Selenium le ha ganado la partida en un cliente grande a otros productos de pago como puedan ser Mercury, por poner un ejemplo. El responsable de e-commerce de Aer Lingus lo explica muy claro:

“Where the commercial product failed, Selenium is proving to be successful – we anticipate that our test cycles will be greatly reduced and our test resources will be able to concentrate on advancing the functionality of the site,” said Ronan Fitzpatrick, head of e-commerce at Aer Lingus.


El segundo punto interesante, y que a todos os suena, es lo complicado que resulta el introducir una política de testing de aplicaciones en una empresa. Estamos en un momento en el que, desde mi humilde opinión, nunca ha sido tan fácil testear aplicaciones. Al menos, hace cinco años no había ni la décima parte de las herramientas que tenemos ahora mismo, y las funcionalidades no se acercaban ni de lejos. Y sin embargo, a todos nos suena eso de "-¿Cómo has probado la aplicación? -Nada, unos cuantos clicks por aquí y por allá".

Según el artículo, y estamos en el 2008, en la web de Aer Lingus todo el testeo era p puramente manual hasta la implantación de Selenium. Una de las cosas que más me chocan es lo contentos que se ponen los responsables de los departamentos de QA, y diferentes jefes al ver como se van automatizando todos los tests. Sin embargo, el automatizar un proyecto es algo que tienes que pelear constantemente convenciendo a todo el mundo. Esto es como al niño que no le gustan los pimientos, y que no le gustan, y que no le gustan. Y resulta que pasados cinco años los prueba y de pronto descubre lo que se ha perdido.

El último punto importante que puedo ver es que a medida que las empresas descubren que la automatización del testeo de las aplicaciones es algo cada vez más y más importante, irán apareciendo más y más oportunidades para empresas tecnológicas que se dediquen al aseguramiento de la calidad, pruebas, automatización, y todos estos temas.

La automatización y la gestión de la calidad del software son tareas muy importantes y para las que a las empresa les cuesta mucho encontrar la sufiente expertise en el mercado. Es complicado encontrar expertos en estos temas, ya que por una parte hay poca gente que se dedique a ello, por otra parte los roles de tester están bastante menospreciados, y por último ya que mucha de la gente que se dedica a estas tareas no tiene siquiera conocimientos de software, desarrollo de aplicaciones, etc.

Estoy un poco fuera del mercado en España ahora mismo, pero me pregunto si existen empresas dedicadas exclusivamente a la consultoría de pruebas, haciendo lo mismo que Enovation ha hecho con Aer Lingus aquí en Irlanda.

martes, septiembre 25, 2007

Bug Driven Development

martes, septiembre 25, 2007 por Martín

Ayer leyendo el blog de Phil Haack me ha gustado mucho la respuesta imaginaria que le hace en su blog a un hipotético escéptico de toda metodología de testing y en la que se inventa el concepto de BDD:

I’m sorry, but I’m not a fan of Bug Driven Development. I think Test Driven Development is not without its challenges, but it’s a better alternative. Either you’re with us, or against us. Are you a bug lover? Bug Driven Development gives comfort to the bugs.

Yo no sería tan radical para decir que si no prácticas el Test Driven Development caerás en un proceso continuo de corrección de errores, pero lo que no cabe duda es que si no existe ningún proceso de calidad, si no existen unit tests, integration tests o una automatización mínima de los tests, se llega a un punto en el que el equipo de desarrollo entra en modo corrección de errores.

Quizás una de las peores consecuencias de esta BDD es que muchos de esos bugs, que no fueron testeados en su momento, ocasionarán cambios en el diseño y en la arquitectura del sistema, cambios que pueden requerir desde horas de código hasta muchos días. Y todo por no seguir un proceso de mínima prevención en un primer momento.

Al final esto de TDD y BDD no deja de recordarme en cierto modo a la medicina preventiva (TDD) y la medicina curativa (BDD).

jueves, septiembre 20, 2007

El rol de build engineer

jueves, septiembre 20, 2007 por Martín

Una de las posiciones que más hemos intentado presionar donde trabajo para que se contratase es la de release/build engineer.

No cabe duda que hoy en día construir software es más complejo (no necesariamente más difícil) que hace años. La cantidad de diferentes sistemas que intervienen en el funcionamiento de una aplicación hace que crear una release sea mucho más complicado que hace años donde casi sólo había que preocuparse por crear un fichero ejecutable para su correspondiente plataforma.

Hoy por hoy nos encontramos que cualquier mínimo software involucrará aplicaciones de escritorio, applets o RIAs, contenedores web, servidores de aplicaciones, sistemas de mensajería, interfaces o servidores de terceros, etc. Asimismo, la integración continua (incluso aunque nos ponga en evidencia) se ha convertido en una práctica fundamental a la hora de lanzar software a tiempo. Sin embargo, está claro que a medida que el software se hace cada vez más y más complejo el mantener este proceso de integración continua se hace más complicado. Y es que hay que tener en cuenta que el proceso de integración continua no se limita únicamente a compilar el código fuente y asegurarse de que no se ha roto la build , si no que es necesario construir un sistema "vivo" que nuestro departamento de QA pueda utilizar para asegurarse de que realmente no se ha roto nada.

Para intentar solucionar este problema se introduce el rol de build/release engineer. Hoy por hoy si se busca en los portales de empleo se encuentran ofertas de empresas que buscan cubrir este tipo de vacante, aunque es cierto que tampoco son demasiadas. Por ejemplo hoy he estado buscando en las ofertas de Irlanda y sólo he encontrado tres o cuatro en el portal que suelo seguir.

La verdad es que por experiencia propia puedo decir que aunque el rol está justificado lo cierto es que es complicado encontrar a alguien que se quiera dedicar exclusivamente a mantener la salud del sistema de automatización de una empresa, por mucho que este rol te permita aprender como funcionan internamente muchos sistemas. Al fin y al cabo, quién quiere pasarse meses pelando con scripts y ficheros XML, ¿no?

Por lo tanto, en el caso de reconocer el valor de build engineer y no poder contratar a uno, ¿qué se puede hacer? Básicamente se me ocurren dos soluciones:


  • Promocionar a alguien de QA: Normalmente (al menos aquí) los testers suelen ser graduates o personas con conocimientos informáticos pero que nunca se han dedicado a programar o que ni siquiera han estudiado realmente informática. Muchas de estas personas son realmente buenos en lo que hacen y llegan a tener un conocimiento global del funcionamiento del sistema mucho mejor que muchos desarrolladores.

    Algunos de estos testers con el tiempo van ganando experiencia y conocimientos que les permitirían pasar a ejercer un rol de build engineer, que a fin de cuentas está directamente relacionado con todo el proceso de QA, así que podría verse como un tipo de promoción natural.

  • Asignar el rol de build engineer a todo el equipo: Para mi es importante resaltar aquí lo de "todo el equipo". Ya que todos sabemos lo que va a pasar si un desarrollador se dedica a configurar la build el sólo, es decir, que se convertirá de manera no-oficial en el build engineer, y que siempre que pase algo acudiremos a él a ver si lo puede solucionar.

    Rotando el rol de build-engineer entre los diferentes miembros del equipo, por ejemplo haciendo que cada semana uno ejerza ese papel, se consigue que todo el mundo acabe por tener un conocimiento de la build y que se mejore también el conocimiento global de como funciona el sistema. Al principio puede hacerse tedioso y engorroso, por eso de que todos tenemos muchas cosas que hacer para andar aprendiendo todos lo mismo, pero con el tiempo y cuando los errores aparezcan todo el grupo habrá adquirido el conocimiento para solucionar los problemas de automatización y no se dependerá del release engineer que vuelve dentro de un mes y se ha ido de vacaciones.


Por cierto, que si os lo estáis preguntando, pues nosotros por ahora nos hemos quedado en un termino medio. Cuando llegué no había nada de nada, pasados unos meses conseguimos un build engineer, pero con el tiempo lo perdimos, y ahora, pues bueno, como al final nuestra automatización ha llegado a niveles bastante avanzados y es bastante compleja pues requiere mucha dedicación, así que hay un equipo digamos de "gestión de procesos" que se dedica a controlarla, siendo algunos de los miembros de este equipo también desarrolladores. Es decir, que en lugar de involucrar a todos los desarrolladores lo que puede ser un poco utópico pues se escogen a tres o cuatro y se les asigna la responsabilidad de estar pendientes de eso como parte de su tiempo.

viernes, septiembre 14, 2007

Eclipse y su infraestructura de testing

viernes, septiembre 14, 2007 por Martín

Hace tiempo hablaba del Eclipse Way y de como me fascina el proceso de desarrollo que siguen.

Repasando un ppoco las charlas de este año de la EclipseCon 2007 (ya ha llovido) me he encontrado con una bastante interesante de Sonia Dimitrov y Kim Moir donde hablaron sobre todo el proceso de QA que se sigue en Eclipse.



Se extraen varias cosas interesantes:

  • Tienen el rol de build engineer para proteger a los desarrolladores del proceso de build (este rol merece un post en si mismo).
  • 176.000 tests en 33.000 JUnit tests ejecutándose en cinco build machines con máquinas virtuales 1.4, 1.5 y 1.6.
  • 469 tests de rendimiento con 2345 tests que se ejecutan en cinco máquinas diferentes. Se ejecutan sólo unos cuantos días debido a que lleva unas 10 horas ejecutar los tests y procesar los resultados.
  • Para asegurarse la validez de los tests de rendimiento utilizan imágenes ghost que instalan justo antes de lanzar los tests.
  • Tienen un conjunto de tests de limpieza. Chequean que todo esté correcto: javadocs, licencias, políticas de código, etc.
  • Los desarrolladores escriben test unitarios, pero el código de los tests se mantiene separado en un CVS propio.
  • Los resultados de los tests de rendimiento se almacenan en una base de datos dedicada.
  • Para detectar fallos tienen un parser que analiza la salida de los tests y en caso de errores genera reportes y los envia a una lista de correo.
  • La mayor parte de los errores que obtienen no se deben en realidad a errores en el código sino a problemas con las máquinas, poco espacio en disco, actualizaciones de software, antivirus, etc.


No sé que os parece, pero a mi me ha sorprendido especialmente toda la infraestructura dedicada al testing, incluido el dedicar un CVS específicamente para el almacenar el código de los tests. Está claro que toda esta infraestructura y este proceso tan elaborado debe tener algo que ver con la capacidad para estar lanzando versiones sin retraso durante cinco años.

martes, mayo 08, 2007

Graded Browser Support

martes, mayo 08, 2007 por Martín

Como hoy hemos definido nuestro soporte oficial de navegadores en la empresa, pues se me ha ocurrido el dedicarle unos parrafos a esto en el blog. A ver que os parece.

Graded Browser Support es un enfoque creado por Yahoo para tratar de mantener controlado el soporte de diferentes navegadores web en un producto.

Con el paso de los años y al hacerse cada vez más y más comúnes nuevos navegadores y sistemas operativos, las empresas de software se encuentran con que es cada vez más y más difícil el garantizar que un producto funciona bien en una plataforma determinada ya que el número de combinaciones es cada vez mayor.

Como mínimo, una aplicación web tendrá que afrontar al menos la combinación Sistema Operativo + Navegador Web (10.000 posibles combinaciones según Yahoo), y eso en caso de que sea una aplicación web para el usuario final. En caso de ser una aplicación orientada a la empresa, tendrá que tenerse en cuenta también el servidor web en el que se desplegará. Por último, en caso de ser un applet, el plugin Java aparece como una vuelta de tuerca más a la combinatoria.

La aproximación de Graded Browser Support resuelve este problema presentando diferentes grados de soporte. Esta aproximación presenta una serie de grados que van de mayor a menor soporte.

En el grado de mayor soporte, Grado A por ejemplo, el usuario tiene garantizado que la aplicación ha sido completamente probada y que todas las funcionalidades se encuentran disponibles. Normalmente los equipos de tests ejecutarían todas las pruebas posibles sobre este tipo de configuraciones. Un ejemplo podría ser: Java Plugin 1.5.0_11 + Firefox 1.5 + Windows XP SP 2.

Conforme se va descendiendo a través de la pirámide de grados, el nivel de soporte va disminuyendo. Así por ejemplo Grado B podría ser Java Plugin 1.6.0_01 + FireFox 1.5 + Ubuntu 7.04. Grado C, Java Plugin 1.5.0_04 + IE 7.0 + Windows Vista, etc. etc. Conforme se va bajando en los grados, el nivel de seguridad en las funcionalidades del producto disminuye. El equipo de test ejecutará sólo un subconjunto de las pruebas para las funcionalidades más básicas, es decir, medida que se desciende en la pirámide, el número de pruebas es menor. Eso no quiere decir que el resto de funcionalidades no vayan a funcionar correctamente. Simplemente quiere decir que el producto está menos probado en esas plataformas.

Ya acabando, un Grado X representaría todas las combinaciones extrañas en las que el producto no ha sido probado. Esto no significa que no funcione, sino simplemente que el equipo de test no ha ejecutado ningún tipo de prueba. Pues por ejemplo: Java Plugin 1.5.0_04 + Safari 1.2 + Mac OS X, por poner algo.

Y por último podríamos añadir el grado "No soportado" que simplemente representaría configuraciones que no se soportarán de ninguna de las maneras. No quiere decir que no se sepa si va a funcionar o no, sino que se está completamente seguro de que no se puede ejecutar el programa con esa plataforma. Pues por ejemplo en cualquier navegador que tenga instalado el Java Plugin 1.3.1

Bueno, aquí quizás os he mentido un poquito porque Graded Browser Support sólo define realmente tres niveles, que son los que he puesto en negrita, es decir el A, el C y el X. Pero bueno, en mi opinión cada uno puede adaptar esta idea y añadir los niveles que crea conveniente. Lo importante es el concepto y facilitar el trabajo de los desarrolladores, de los equipos de test, a la vez que se ofrece al usuario una serie de garantías bajo una serie de plataformas, todo documentado y bien clarito.

domingo, febrero 04, 2007

Como hacer rápidamente pruebas unitarias y de integración con Jackrabbit

domingo, febrero 04, 2007 por Martín

Bueno, uno de mis propósitos de año nuevo, o más bien de Enero, es volver a darle un empujón a mi blog en inglés. Así que iré poniendo aquí las entradas que pongo en el otro. Si alguién realmente necesita alguna traducción sólo tiene que pedirla.

Y es que yo tengo serios problemas con lo de bloggear en inglés o en español. Cuando estaba en España, era como si tuviese la necesidad de bloggear en inglés, y ahora me pasa exactamente lo contrario. Pero lo cierto es que me encuentro con que bloggear también en inglés es muy importante en estos momentos porque de algún modo te sirve como carta de presentación para hacer contactos, entrar en comunidades, etc. Pero por otra parte, no puedo escribir nada sobre mi trabajo, ya que sería problemático. Bueno, en fin, un lio.

Aquí queda la susodicha entrada sobre Jackrabbit e unit testing:
Como hacer rápidamente pruebas unitarias y de integración con Jackrabbit

sábado, febrero 03, 2007

Tests en el water

sábado, febrero 03, 2007 por Martín

En el trabajo en el que estoy en este momento te das realmente cuenta de lo difícil que es inculcar una cultura de tests dentro de proyectos grandes. Estás constantemente explicando que hacer tests es bueno, preparas herramientas para hacer tests de integración de componentes y de integración global de manera sencilla, rellenas wikis, confluences, y herramientas diversas con información, fuerzas que los tests rompan la build, o instals herramientas de cobertura. No importa. Siempre hay gente que no hace código y partes de los programas que fallan a última hora y que descubres que no tienen tests.

Y es que acostumbrarse a la cultura de pruebas es complicado. De hecho yo soy el primero en haberme hecho el vago en el pasado :) Y parece que las compañías grandes como Google no se libran de los problemas, por mucho que sus acciones suban en bolsa. Hoy he descubierto que han hecho publico algo llamado Test on the Toilet, que consiste en una serie de hojas con consejos sobre la importancia de realizar tess, como afrontarlos, como conseguir una buena covertura, etc. Las hojas se colocan en el water de modo que todo el mundo las pueda leer en lugar de tener que llevarse el periódico para leer los deportes. Aquí una prueba.

Una idea simpática y revolucionaria. No sé por qué pero me da la impresión de que puede ser muy efectiva.

jueves, enero 11, 2007

Integración continua y avergonzamiento público

jueves, enero 11, 2007 por Martín

Una de las medidas que Mike Clark promovía en el libro de cabecera Pragmatic Project Automation es la de mostrar el resultado de las diferentes build de la manera más visible que se pueda. El objetivo está claro, saber lo más pronto posible cuando y por qué se ha producido un evento que ha roto el proceso de build de la aplicación.

En mi compañía se ha ido un poco más allá, y como aliciente adicional se ha creado una lista de "Top Build Breakers". Además el manager de producto recibe un bonito email semanal con estadísticas tan jugosas como cuantas veces se ha roto el proceso de build, quienes son los que más lo rompe, cuanto se tarda en solucionar un problema, y cosillas así.

Aunque los desarrolladores noveles son los que más han protestado con la medida, por considerarla intimidatoria y como un punto importante de presión, lo cierto es que medidas así aseguran a mantener alto el estado de salud del código, al menos en cuanto a compilación y pruebas unitarias. Pasados ya más de tres meses desde la aplicación de la medida, la productividad ha aumentado enormemente, y sobre todo el tiempo que la base de código permanece en un estado inconsistente ha decrementado radicalmente. Hace meses el código podía estar días en estado inconsistente (valga como defensa que hablo de varios cientos de proyectos), y ahora mismo pasa no más de unos cuantos minutos. La gente es mucho más cuidadosa con el código que se sube al repositorio y con los tests unitarios que se crean.

Por lo tanto, que nadie se asuste por aplicar o por sufrir estas medidas, ya que la experiencia dice que al final es un beneficio para todos. Por cierto. Sí, he roto alguna vez la build. Pero que conste que no salgo en la lista de ganadores :-)

martes, diciembre 19, 2006

Juegos en la empresa

martes, diciembre 19, 2006 por Martín

Sin lugar a dudas, una de las formas más originales de probar un producto, y que he tenido la oportunidad de experimentar este año, es la de jugar con él. Sí, jugar, habéis leido bien. Intentaré explicar el concepto en los siguientes párrafos.

Cuando un producto está llegando a su fecha de lanzamiento empieza el periodo estresante de pruebas exhaustivas. Normalmente, el producto se cerrará en cuando a código fuente y a partir de ahí entrará en proceso de integración y pruebas por parte del equipo de tests. Una vez que termine este período, podremos lanzar nuestra tan esperada versión. Obviamente, nos interesa que cuando el producto llegue a manos del cliente, éste se encuentre impecable y totalmente libre del más mínimo error, problema de rendimiento, agujero de memoria, o cualquier otro efecto indeseable.

Si nuestro proceso de pruebas e integración es extraordinario, todo irá como la seda. Pero la realidad es que las cosas no suelen ser así. Aunque nuestro proceso de pruebas sea perfecto desde el punto de vista formal, la realidad es que siempre existe un factor importantísimo que no podemos controlar: el factor humano.

El factor humano es importantísimo a la hora de probar un producto, porque por muchos tests unitarios, de integración, de rendimiento o funcionales que tengamos, ¿saben realmente nuestros desarrolladores lo que están probando? Es más, ¿saben nuestros desarrolladores como funciona el producto?, ¿saben como es el interfaz de usuario?, ¿saben como se comunican los componentes?, ¿se han puesto alguna vez en la piel del usuario final? Probablemente la respuesta a todas estas preguntas sea afirmativa si estamos hablando de un producto pequeño, pero sin embargo, cuando hablamos de un equipo de cientos de desarrolladores, de productos con decenas de módulos diferentes, y de grupos de desarrollo diversos (incluso deslocalizados), entonces la respuesta será un conjunto de noes.

Una de las formas de afrontar este problema es jugar. Sí, jugar, como leéis. Dependiendo de la aplicación se podrán crear diferentes tipos de juegos. No todas las aplicaciones son "jugables". Unas lo son más que otras. Por ejemplo, si estamos creando un juego para un periódico nos será sencillo el crear un juego virtual dentro de la empresa; si estamos trabajando en un producto para invertir en el mercado bursatil, podremos crear un juego de inversión en bolsa; si estamos creando una tienda online podemos crear un juego en el que ganaría el que más compras realize, o el que más dinero gaste, o cosas así; si estamos creando una aplicación de gestión de un servicio médico, podemos premiar a los que más pacientes traten o examinen completamente, a los que más informes creen, etc. etc. En fin, hay muchísimos ejemplos, unos más sencillos, otros más complejos.

Una vez que tenemos definido el juego es importante crear el entorno de ejecución del mismo. Este entorno debería simular de algún modo el entorno de producción real. Como la carga de usuarios será menor, se debería escalar este sistema para alcanzar algún tipo de relación con la carga de usuarios esperada. En general el sistema será mucho más pequeño que el de producción, pero debería ser lo suficientemente significativo como para generar problemas que podrían aparecer en producción.

Una vez que tengamos definido todo esto, llega el momento de jugar. Pero bueno, a estas alturas estaréis pensando, pero éste realmente se piensa que la gente va a ponerse a jugar con todas las cosas que tienen que hacer. Tenéis toda la razón del mundo. Todo esto no es suficiente si no se toman algunas medidas muy importantes:


  • Premios en metálico.

  • El juego debe ser obligatorio.



Como apunto en la lista, el juego debe tener obligatoriamente premios, y si es posible debería haber premios en metálico para todo el mundo. Por ejemplo, en el ejemplo de la tienda, se podría ofrecer a los empleados el 5% del importe de todo lo que compren hasta un límite de 1000€; o en el juego de la bolsa, pues el 5% de las ganancias que consigan + 5€ por operación realizada hasta 1000€.

Tener premios sin duda estimulará a la gente a participar. Una opción interesante es contactar con el cliente para conseguir ese dinero en metálico. Este tipo de juegos suele atraer la atracción del cliente final, ya que muestra que existe una intención real de hacer una prueba extensiva del producto. De hecho, si el cliente final es una organización, probablemente les interese a ellos mismos realizar un juego interno posterior dentro de la propia compañía.

También es muy importante que el juego sea obligatorio. Este tipo de prácticas ofrecen una enorme oportunidad para simular el comportamiento real de la aplicación, con personas reales y en un entorno similar al entorno de producción. Por eso es tan importante que participe la mayor cantidad de personas como sea posible. Adicionalmente, este tipo de juegos sirve para que los desarrolladores se familiaricen con la aplicación, para que entiendan como funciona, para que se pongan en la piel del usuario final y se enfrenten al interfaz de usuario, para que se den cuenta ellos mismos de los diferentes problemas. En fin, son demasiado valiosas como para que no se realicen. Por ello debe obligarse a los desarrolladores (y a testers, y soporte técnico, y managers, y a todo el mundo) a participar en el juego.

La participación no tiene porque ser constante, ya que también queremos que las personas trabajen. Se pueden organizar periodos de participación durante el día, o quizás ofrecer herramientas que automatizen el juego para que no haya que estar todo el día mirando para la pantalla para ganar.

Este año, he tenido la oportunidad de participar en uno de este tipo de juegos y la verdad es que la experiencia fue increiblemente positiva, y todo el mundo coincidió en lo mismo. Son experiencias que no sólo te ayudan a aprender como funciona el producto, sino que ofrecen un enorme abanico de posibilidades a la hora de probar realmente las aplicaciones.

Me pregunto si alguien tiene expriencias que compartir sobre este tema que personalmente me parece muy interesante. Ahí queda la oferta.