Continuous Delivery, aplicaciones legacy, TestNG y SeleniumIDE

Una cuestión clave en todo contexto de continuous delivery son las pruebas automatizadas. De poco sirve pasar «rápido» entre ambientes, si no podemos garantizar cierta calidad de lo que estamos poniendo en cada ambiente.

Cuando uno construye aplicaciones desde cero, es relativamente fácil generar pruebas automatizadas. El uso de técnicas como BDD y TDD junto con algunos patrones de diseño permiten generar aplicaciones testeables y con alto nivel de cobertura.

Pero no siempre trabajamos sobre aplicaciones nuevas. En ocasiones nos toca trabajar con aplicaciones ya existentes, que muchas veces no cuentan con pruebas y que han sido desarrolladas sin tener en cuenta la testeabilidad. En los contextos ágiles a este tipo de aplicaciones se les suele llamar aplicaciones legacy.

Por suerte son pocos los proyectos, en los que trabajando como programador, he tenido aplicaciones legacy. Sin embargo, trabajando como consultor, me he cruzado bastante a menudo con clientes llenos de este tipo.

Mi estrategia para trabajar con aplicaciones legacy es comenzar haciendo algunas pruebas funcionales que cubran los principales flujos de la aplicación. Y luego a gradualmente comenzar a modificar la aplicación haciendola testeable y agregando distintos tipos de tests según sea posible.

Una combinación de herramientas que me ha resultado interesante para hacer pruebas funcionales es SeleniumIDE + TestNG.

Selenium IDE es una herramienta de automatización de pruebas del tipo Record & Play que funciona integrada con el explorador FireFox y permite que uno vaya recorriendo la aplicación y poniendo aserciones en determinados puntos. Luego la misma herramienta permite reproducir la prueba grabada. Si bien a primera vista la estrategia puede parecer muy interesante, la realidad es que no es tan simple. De hecho este tipo de herramientas de automatización de pruebas ha tenido varias críticas (algunas de las cuales comparto), por diversos motivos que han sido tratados, entre otros, por George Meszaros.

Por su parte TestNG, es una herramienta al estilo JUnit, pero a diferencia de esta, tiene un foco más amplio que la prueba unitaria y por ello provee algunas funcionalidades muy útiles para hacer pruebas funcionales.

A partir de estas dos herramientas, mi estrategia es:

  1. Diseñar la prueba y crear la «cáscara» de la prueba con TestNG
  2. Grabar la prueba con Selenium IDE
  3. Exportar el script resultante a Java
  4. Tomar el código del script Java generado y usarlo para completar la cáscara creada con TestNG
  5. Ajustar la configuración del driver de test (pues si bien por default viene FireFox, uno podría querer/necesitar probar con otro browser)
  6. Ajustando el código de prueba en TestNG tomando en cuenta la particularidades de la prueba
  7. Ejecutar las pruebas con TestNG

Dos cuestiones importantes a considerar para utilizar este enfoque y que son las que abarca el punto 5 son:

  1. Es posible que para ejecutar las pruebas sea necesario contar con un estado particular de la aplicación que puede no ser trivial de generar
  2. Es muy común que los datos de tests requieran cierto grado de «dinamismo». Aquí puede resultar muy útil la funcionalidad de TestNG que permite definir sets de datos de prueba.

Bien, esto es todo por el momento.

Como siempre, si tienen alguna consulta/inquietud, no duden en escribirme.

Agiles 2013: Programa disponible

Esta semana se publicó el programa de la conferencia y junto con ello notificaron la aceptación de las sesiones. Mi sesión Estrategias para la adopción de Continuous Delivery fue una de las eligidas ;-).

Según cuenta el progama, además de las clásicas sesiones tipo presentación, también habrá sesiones tipo workshop, una clínica de coaches y un open space.

Faltando menos de 2 meses y con la sesión confirmada, es hora de que me ponga a ver las cuestiones logísticas.

¡Nos vemos!

Notas para instalar Jenkins en Ubuntu

Una de las cosas más me gusta de las distribuciones basadas en Debian es la facilidad para instalar software utilizando apt-get.

Jenkins puede instalarse utilizando apt-get, pero antes de ejecutar apt-get install jenkins,  uno debería actualizar la configuración de su repositorio de paquetes para así asegurarse de instalar la última versión. Esta página describe el proceso completo de instalación.

Enjoy it!

Impresiones del Agile Open Buenos Aires Educación 2013

Hace dos semanas participé de este evento comunitario y me llevé un montón de cuestiones para profundizar y experimentar.

Una de las particularidades del evento fue la presencia de una importante cantidad de gente no relacionada al desarrollo de software, lo cual resultó muy enriquecedor.

Yo propuse dos sesiones: una para compartir experiencias de Aula Extendida y otra para debatir sobre los trabajos finales de las carreras de sistemas. Sólo la primera tuvo apoyo y se realizó, pero de todas formas hablé sobre el segundo tema en los pasillos, con algunos asistentes que estaban interesados. En la sesión de Aula Extendida, comenté mi experiencia en las materias que dicto en UBA y UNQ. Uno de los participantes planteó si es mejor utilizar las herramientas provistas por redes sociales que los sistemas típicos de los ambientes académicos (listas, foros, Moodle. etc).

Una de las sesiones que más me gustó fue la propuesta por la gente de EDEA, una organización que trabaja en cuestiones de diseño sustentable. Nos contaron sobre su organización, la forma en que trabajan e hicimos un par de dinámicas corporales muy interesantes.

También participé de una sesión facilitada por Alan Cyment, en la que compartió algunas técnicas «from the back» que suele utilizar en sus cursos.

Ya por la tarde participé de una sesión cuyo nombre no recuerdo, pero que trató sobre el impacto que tiene la tecnología en la educación. Bastante polémica e interesante. En cierto modo en la sesión de aula extendida hablamos principalmente sobre el efecto positivo, pero en este caso también tratamos algunos aspectos negativos y cómo lidiar con ellos.

En resumen, me resultó muy enriquecedor.

Workshop de Extreme Programming

Los últimos días he estado ausente porque estuve trabajando en la preparación y el dictado de un workshop de Extreme Programming junto a mi colega @carlospeix.

Como era la primera vez que lo dictábamos, hicimos una invitación cerrada a algunos conocidos y ex-alumnos que gentilmente aceptaron ser nuestros «conejillos de indias».

El workshop salió un poco distinto a como lo habíamos planeado, pero a pesar de eso quedamos muy contentos con el resultado y los alumnos también se manifestaron positivamente.

Estimamos volver a dictarlo hacia mediados/fines de septiembre, pero de forma abierta al público.

xpw

Sobre las pruebas de integración

Continuando con el tema pruebas, es hora de hablar de las pruebas no-unitarias.

Pruebas de integración de componentes

Estas pruebas buscan probar componentes en forma NO aislada. Pero no son necesariamente pruebas de usuario. Hay ciertos casos donde es muy costoso aislar un componente para su prueba o que incluso, puede que no tengas sentido ese aislamiento pues la parte crítica radica justamente en la integración.

Un caso donde estas pruebas tiene sentido es cuando tengo que testar la funcionalidad de búsqueda de mi capa de acceso a datos. Si bien puede que tenga un ORM, puntualmente para las cuestiones de búsqueda «avanza» puede que el ORM termine bastante acoplado a la base.
Estas pruebas también suelen usarse para testear la aplicación desde los controller hasta la base, pasando por alto las vistas (que suelen ser muy frágiles/cambiantes/difíciles de testear)
Estas pruebas suelen codearse usando una herramienta de prueba unitaria, aunque conceptualmente no son unitarias.

Pruebas de aceptación funcionales (o aceptación de stories)

Son las pruebas que definirán si hemos completado o no una story dada. Son naturalmente pruebas de integración, ya que no prueban un componente aislado sino también la interacción de varios componentes (son no-unitarias).

Estas pruebas  son de la incumbencia del usuario, por eso es que intentamos hacerlas con alguna herramienta que le resulte cómoda al usuario (que en general no es una persona técnica).

En nuestro caso usaremos Cucumber. Cuando hacemos BDD estamos haciendo este tipo de pruebas.

Nuestro foco con estas pruebas es asegurarnos que entendimos bien la story y que el código que escribimos hace lo que tiene que hacer. Como consecuencia de esto no debería ser relevante donde ejecuto las pruebas. O sea, no es necesario instalar la aplicación en un ambiente particular para ejecutar estas pruebas. Al mismo tiempo, podría en algunos casos escribir steps de cucumber que manipulen directamente los objetos de mi modelo.

Pruebas de aceptación del sistema

Estas pruebas son similares a la anteriores, pero adicionalmente también queremos asegurarnos que la aplicación fue correctamente configurada y que todo su ecosistema está perfectamente funcional. Esto implica que sí es relevante el lugar donde pruebo la aplicación. Debería ser un ambiente similar al de producción.

Aquí ya no estamos hablando de hacer BDD. Respecto de las herramientas, puedo usar un robot tipo Selenium o VSTest o incluso Rspec. Es más, mucha gente hace estas pruebas en forma manual.

También puedo utilizar cucumber, pero con algunas restricciones:

  • Seguramente me interese utilizar un driver de cucumber que levante el navegador
  • No podré manipular objetos del modelo en mis steps de cucumber.

Muchas veces estas pruebas se hacen en forma manual. El equipo termina el desarrollo, instala la app en un ambiente de test y un equipo de testers ejecutar pruebas a modo «caja» negra.

Continuará….

Clasificación de Pruebas

Existen distintas clasificaciones para las pruebas de software. Desde el punto de vista de cómo se ejecutan, podemos clasificar las pruebas en manuales o automatizadas.

 

Por otro lado, desde el punto de vista de qué es lo que prueban, yo suelo clasificarlas en primera instancia en unitarias o no-unitarias.

 

La prueba unitaria prueba un componente en concreto. Esto implica aislar al componente bajo prueba de sus dependencias. Pues si no lo aislamos y la prueba falla, no tendremos la certeza de si la falla se debió a un error en el componente bajo prueba o si se debió a un problema en una de sus dependencias. Es aquí, donde entran en juego los llamados Test Doubles que no ayudan a aislar el componente bajo prueba.

 

Por su parte, dentro de lo suelo llamar pruebas no-unitarias, entran todos los demás tipos de pruebas, las cuales implican probar la interacción entre distintos componentes. En este tipo de pruebas los componentes ya no están aislados y por ello algunas personas las llama pruebas de integración. En este grupo están tanto las pruebas de aceptación, como las de stress y cualquier otra prueba que implique la interacción en distintos componentes. Dado que hay mucho que decir sobre este tipo de pruebas, dedicaré otro post exclusivo.

Agile Open Buenos Aires Educación 2013

La cita es el próximo sábado 10 de Agosto en las instalaciones que tiene la UNTref en el Centro Cultural Borges (arriba de las Galerías Pacífico en la ciudad de Buenos Aires)

Es un evento totalmente gratuito que se realiza con formato Open Space, lo cual permite que todos seamos tanto oyentes como oradores ;-).

Para más información pueden ver aquí y aquí.

Si bien el evento es gratuito es requerida registración previa para estimar la cantidad de asistentes y así simplificar algunas cuestiones de logística, este el link para registrarse.

¡Nos vemos!