Recursos de Testing 3.0

Ayer estuve participando en el ciclo de Tech Talks facilitado por Arcadio Abad. Estuve hablando sobre un conjunto de prácticas que he dado en llamar Testing 3.0.

La charla fue efectivamente una charla de ida y vuelta con Arcadio quien a su vez transmitía las preguntas de la audiencia. Me sentí muy cómodo con el formato y creo que pude dar respuesta a todas las preguntas que Arcadio me transmitió(aunque creo que por el chat pasaron algunas otras que pueden haber quedado sin respuesta por cuestiones de tiempo).

Durante la charla hablé de varias cuestiones pero la gran mayoría relacionadas a la idea de usar los tests como especificación de requerimientos y guía del desarrollo (lo que usualmente se conoce como BDD). Comparto aquí algunos recursos al respecto:

  • Los libros de BDD de Rose y Nagy son simplemente excelentes.
  • El libro «Specification by Example» de Goyco también es excelente, es bastante más extenso porque cubre muchas cuestiones.
  • Unos videos que muestran la técnica de BDD/TDD en acción: parte 1 y parte 2
  • Varios artículos de mi blog sobre esta técnica

Y si quieren aprender más de BDD y no tienen un perfil muy técnico, los invito a que se sumen a mi Taller de Prácticas Técnicas para Scrum Masters (al margen del nombre, vemos cuestiones que son relevantes incluso para gente que no es Scrum Master)

Tech Talk: Testing 3.0+

Este jueves 9 de marzo estaré participando del ciclo de charlas técnicas organizado por la gente de Abstracta. En dicho espacio hablaré sobre mi visión actual del testing en general y del rol de tester en particular. La charla está pensada como una continuidad/profundización de la charla que dí en la QualitySense Conf en diciembre 2022 (video disponible aquí) y resume lo que actualmente enseño en la universidad.

Algunos puntos centrales de la charla:

  • Parte del testing lo deben hacer los desarrolladores.
  • Los testers deben trabajar muy cerca de la gente de negocio.
  • Los casos de pruebas deben generarse temprano en la iteración, incluso algunos casos de prueba deberían estar claros al finalizar la reunión de planificación de la iteración.
  • La gran mayoría del testing debe estar automatizado.
  • La ejecución de la mayoría de los test debe poder ejecutarse sin necesidad de utilizar un ambiente particular.
  • Testear algunas cuestiones en producción es válido, pero ello requiere planificación de cara a poder contemplarlo a nivel de desarrollo e infraestructura.

Varios de los puntos anteriores impactan directamente en las tareas y habilidades del tester y sé también que algunos pueden resultar polémicos. Esto es una buena excusa para sumarse la charla, es gratuita pero require registración.

WOPR, QSConf y Testing 3.0

Del 5 al 10 de diciembre voy a estar en Montevideo para participar de estos dos eventos.

El Workshop on Performance and Reliability (WOPR) es una evento cerrado que se accede por postulación/invitación y que tiene ~25 cupos por edición. Hay un grupo de organizadores que asegura la continuidad del evento (esta será la edición 29), luego hay una empresa del rubro (performance & reliability) que «hostea» el evento y se encarga de las cuestiones logísticas. Los interesados en participar envían una propuesta, la misma es evaluada por los organizadores y en base a eso se envían las invitaciones. En esta edición la empresa host es Abstracta, pueden encontrar más información al respecto del WORP en este post de Federico Toledo.

A continuación del WORP y organizado también por Abstracta, tendrá lugar el viernes 9 de diciembre en la torre Antel, la Quality Sense Conf. Esta conferencia será gratuita y en formato híbrido. En este contexto voy a estar dando una charla que he titulado «Testing 3.0» :

Las estrategias de testing y el rol de tester ha ido cambiando a lo largo del tiempo influenciado, entre otras cuestiones, por los avances tecnológicos y metodológicos. Desde los procesos «cascadosos» y las aplicaciones mainframes, pasando por los métodos ágiles, las aplicaciones de escritorio, a las aplicaciones web, mobile y el auge de DevOps. Los desafíos que enfrenta la industria del software en la actualidad han generado importantes desafíos y oportunidades para quienes trabajan en cuestiones de testing y calidad en general. En esta charla veremos algunas de esas oportunidades y cómo prepararnos para sacarle el mayor provecho. 

Testing automatizado en React-Native

Luego de 6 meses trabajando a diario con React-Native he logrado hacerme una idea bastante clara sobre esta temática que me parece no está suficientemente bien documentada.

En primer lugar tengamos presente que con React-Native vamos a generar aplicaciones móviles para Android y/o iPhone con lo cual un tipo de prueba automatizada que podremos realizar es directamente sobre el binario nativo que se instala en el dispositivo, serían las denominadas pruebas end-to-end que muchas veces se hacen en forma manual. Su ejecución requiere por un lado del uso de un emulador (o incluso se puede usar un dispositivo físico) y por otro, el uso de algún driver/conector que nos permita interactuar con la aplicación desde la perspectiva del usuario. Como estas pruebas van directamente contra el binario/ejecutable, tenemos independencia para codearlas en un lenguaje distinto al que utilizamos para codear la aplicación. La pieza central en este tipo de pruebas es el driver/componente que nos va a permitir manipular la aplicación emulando la interacción del usuario. En este sentido una de las herramientas más populares es Appium y otra es Detox.

Sacando las pruebas end2end, tenemos distintos tipos de pruebas de índole más técnico, de componentes/unitarios. Estas pruebas sí las estaremos codeando con la misma tecnología que codeamos la aplicación. En el caso de estar trabajando con React Native estas pruebas las vamos a codear con JavaScript. Aquí también entran en juego distintas herramientas. La primera de ellas es el framework de testing que utilizaremos para escribir los casos de prueba y agruparlos en suites. Aquí tenemos varias alternativas (como suele ocurrir habitualmente en JavaScript) pero al trabajar con React se suele utilizar Jest que es la herramienta recomendada en la documentación oficial de React. Jest nos va a permitir escribir casos de prueba sobre objetos/funciones JavaScript, sean estos componentes React o simples objetos planos «vanilla JavaScript». Una «bondad» que tiene Jest es que trae nativamente funcionalidades de mocking/stubbing con lo cual nos ahorramos de tener que incluir en nuestro proyecto otro framework/herramienta para mocking.

Si en nuestras pruebas queremos testear componentes React-Native, en particular el rendering, en primera instancia podemos utilizar el Test Renderer que es parte del core de React. También como parte del core de React tenemos las Test Utils que ofrecen un conjunto muy útil de funciones utilitarias.

También tenemos la posibilidad de utilizar React-Native Testing Library que debemos instalar por separado (yarn add –dev @testing-library/react-native). Esta librería construída sobre la base del Test Renderer y agrega un conjunto de funciones utilitarias de gran utilidad.

Situaciones de Diseño #1

Hace tiempo venia con la idea de publicar una serie de videos sobre diversas técnicas/patrones/recomendaciones para lidiar con situaciones de diseño habituales. Finalmente ayer decidí poner manos a la obra y publiqué el primer video de esta serie.

La situación que aborda este primer video es cómo lidiar con lógica que depende de fechas de una forma testeable. Muchas veces cuando tenemos lógica que depende de la fecha actual, estamos tentados de utilizar directamente una llamada al componente nativo de fecha. El problema con este camino es que no resulta testeable. La clave está en encapsular el acceso a la fecha del sistema de manera tal de poner utilizar un doble de prueba (mock) en el momento de hacer nuestra pruebas automatizadas.

Les dejo aquí el video y los invito a que me dejen en los comentarios alguna otra situación que les gustaría que aborde en próximos videos.

Conferencia Testing UY 2021

Este año participé por primera vez como orador en esta conferencia. Más allá de mi experiencia como orador me gustó la organización de la conferencia debido a varias cuestiones que me resultaron innovadoras sobre todo considerando que es un conferencia gratuita organizada por voluntarios.

Además de las tradicionales charlas como la que di yo (de una 1 hora de duración), había también una oferta de talleres (en general de carácter muy práctico y con cupo limitado) y charlas relámpago.

La conferencia se desarrolló durante toda la semana. Los talleres se dictaban durante la mañana/mediodia y primera hora de la tarde. Las charlas tenían lugar por las tardes en horario «after office».

Más allá de las actividades de contenido, había sorteos y un desafió de testing en equipos. La transmisión de las charlas se hizo por Zoom y todas ellas (las charlas, no los talleres) serán publicadas en el canal de YouTube de la organización.

Como ya es costumbre en tiempos de pandemia, había también un discord a modo de «espacio social».

Un detalle que me resultó muy interesante es que a pesar de ser un evento «latino» hubó varias presentaciones de otros lugares del mundo, varias de ellas en inglés.

Tuve la oportunidad de participar de varias charlas entre las que se destacaron a mi gusto: la de Guillermo Skrilec sobre el testing de la aplicación de vacunación en Uruguay, la de José Luis Velázquez Jacobo sobre testing de sistemas de conducción asistida y la de Federico Toledo y Matias Fornara sobre calidad de pruebas automatizadas.

Las diapositivas de mi charla está disponibles aquí.

Mis felicitaciones y agradecimiento a los organizadores, creo que ha sido un gran evento, de los mejores de la región.

Curso gratuito de Unit Testing

Una de las dificultades que suelo encontrar al intentar enseñar Test-Driven Development a gente que ya tiene varios años de experiencia en desarrollo de software (con los principiantes es distinto), es que muchas veces no saben hacer pruebas unitarias automatizadas. Por eso, hace un par de semanas cuando decidí experimentar haciendo un curso 100% en video, no dudé en hacerlo sobre unit testing.

Ayer finalmente, luego de un par de semana de trabajo completé el curso, son 2 horas de video divididas en varios videos de no más de 10 minutos. Además de los videos, incluye varios recursos de lectura y ejecicios. Todo el código del curso está basado en C# (netCore) y NUnit, pero todo el contenido es fácilmente extrapolable a otros lenguajes/frameworks. Personalmente creo que tomar el curso completo (videos + lecturas + ejercicios) podría llevar unas 4 o 5 horas dependiendo de la experiencia de programación de la persona.

El curso está publicado con acceso gratuito en la plataforma Udemy

Definición de la estrategia de pruebas

Existen muchas clasificaciones de tests, casi tantas como autores. De caja blanca, de caja negra, unitarias, de integración, de aceptación, funcionales, de sistema, de carga, etc, etc.

Hay para todos los gustos y colores. Más aún, algunos tipos de tests tienen un significado distintos para distintas personas. Un caso usual de esto son los test end-2-end que típicamente:

  • para los desarrolladores implican tests de una funcionalidad que atraviesan todas las capas de la aplicación, desde la pantalla hasta la base de datos
  • para los testers implican tests que cubren un flujo de negocio que integra varias funcionalidades

Esta situación obliga a que todo equipo deba en primer lugar ponerse de acuerdo en la terminología a utilizar. A partir de esto hay que definir la estrategia de pruebas.

Definir la estrategia de pruebas implica definir:

> Tipos de tests que se realizarán
> Cuantos de esos tests se realizarán
> Quien los realizará
> Cuando los realizará
> Qué herramienta se utilizará
> Y cual será la arquitectura de prueba que dará soporte a todos los tests

La siguiente figura resume parcialmente la estrategia de pruebas de mi proyecto actual.

Lo que indica esta imagen se complementa con las siguientes decisiones:

  • El desarrollo se hace una forma test first, donde los tests guían el desarrollo. Todo empieza «tironeado» por una pruebas de aceptación (story tests) especificada en Gherkin a partir de una charla entre: usuario + tester + developer.
  • Los tests de aceptación no se automatizan al comenzar el desarrollo sino a posterior y al mismo tiempo no todos los escenarios son automatizados.
  • El resto de los tests se escriben a priori del código y de a uno por vez. Una vez implementados se ejecutan constantemente en el build server.
  • Salvo los tests de aceptación, todo el resto de los tests de la figura son escritos por los developers.
  • Para los tests de aceptación usamos Gherkin+Specflow.
  • Para los tests de frontend utilizamos Jasmine+Karma.
  • Para los tests de backend utilizamos NUnit.
  • Para mockear utilizamos Moq y Wiremock.

Adicionalmente a los tests de la figura hacemos pruebas de performance (jmeter) cuando tenemos cambios relevantes en la arquitectura y pruebas exploratorias de ejecución manual antes de cada salida a producción. Tenemos pendiente agregar algunas pruebas de seguridad.

Finalmente respecto de cuántos tests de cada tipo hacer idealmente apuntamos a tener un triángulo con pocos tests de aceptación end-2-end para los flujos centrales en la punta y muchos tests unitarios en la base para lograr cobertura de flujos alternativos. En el medio de la pirámide quedan los tests de componentes/integración.

Automatizando pruebas de IBM BPM

Una vez más un amigo que me tiene mucha confianza me invitó a proyecto desafiante: automatizar pruebas de una aplicación generada con una tecnología propietaria «IBM Business Automation Workflow» (IBM BPM).

Muy a grandes rasgos esta herramienta permite automatizar procesos de negocio utilizando una herramienta case que permite integrar (entre otras cosas) servicios (soap & rest) y componentes Java. Una vez que se ha generado el flujo, se genera un paquete (.ear) que se despliega en un servidor de aplicaciones Webphere y listo, está disponible para los usuarios. Hay que mencionar que la propia herramienta de desarrollo de IBM provee ciertas funcionalidades para realizar pruebas, pero en el contexto de esta iniciativa hemos decido ir por un enfoque basado en herramientas de uso general, aunque no descartamos hacer algunos experimentos con estas funcionalidades de prueba.

Luego de un par de sesiones de trabajo hemos identificado 3 tipos de pruebas:

  1. Pruebas end-to-end usando Selenium Web-Driver, esto eso: las prueba es un script que utilizando un nagevador emula el comportamiento del usuario
  2. Pruebas de servicio, realizadas con SoapUI y que consumen los servios SOAP que están por detrás de las pantallas
  3. Pruebas unitarias de los componentes Java codeadas con JUnit.

Decidimos empezar por (2) porque parecía ser un win rápido y efectivamente lo fue. No encontramos mayores complicaciones en hacer estas pruebas.

A continuación empezamos a trabajar en (3) y como sospechamos la cuestión se tornó más difícil porque el código de los componentes Java que se invoca desde la herramienta case (un eclipse customizado) tiene dependencias a bibliotecas de IBM que no están disponibles en repositorios públicos. Para hacer estas pruebas también debimos «mavenizar» los proyectos de cara a poder correr las pruebas en el servidor de itegración continua.

Finalmente, nos queda pendiente probar la estrategia (1) personalmente no me inquieta mucho pues al fin y al cabo las pruebas de UI son algo en lo que no suelo confiar mucho por su costo de mantenimiento y su fragilidad. En dos semanas les cuento que tal nos fue con esto último.

Nuevo proyecto: Arquitectura de Prueba

Una vez más me meto es cuestiones de automatización de pruebas y una vez más en un contexto bancario. Esta vez junto a mis estimados colegas de Grupo Esfera. Ayer hicimos el kickoff del proyecto y a continuación tuve una de las mejores sesiones de trabajo del año junto a mi amigo Diego Fontdevila. Estuvimos unas 2 horas revisando código, hablando de diseño, trade-offs y herramientas 😉

En términos genéricos el objetivo del proyecto es armar una arquitectura de prueba para facilitar/guiar a los equipos de desarrollo de la organización que trabajan en aplicaciones de canales y que deben integrarse con los sistemas core.

El stack de tecnologías con el que voy a estar trabajando incluye: Cucumber, Selenium, Pact, Java y AS400 entre otros.