lunes, 1 de mayo de 2017

Cápsulas de Testing - Qué son y Próximas fechas

Próximas cápsulas

Webinar (¡Inscríbete!):
  • Viernes 12 de mayo - 13:15 a 14:00 hs GMT-3 - Arquitectura de la prueba automática
  • Viernes 19 de mayo - 13:15 a 14:00 hs GMT-3 - Page Object

En TestingUy: Lunes 15 de mayo - 11:30 - 13:30 hs

(bajate el draft del libro en pdf)


jueves, 20 de abril de 2017

Cápsulas de Testing - Estrategias de Datos v2


En los equipos que desarrollan ágilmente se busca que todos los miembros del equipo tenga un conocimiento mínimo de las actividades de testing. También que los testers profundicen su conocimiento.

¿Cómo podemos distribuir ese conocimiento?
Las cápsulas de información de testing son una manera incremental de incorporar conceptos a partir de ejemplos del equipo o externos. Pueden servir como guía para realizar círculos de aprendizaje en el equipo de desarrollo o para profundizar conocimientos en comunidades de práctica.
Algunas cápsulas de conocimiento: Arquitectura de la prueba Automática, Modelo del Oráculo y Pruebas Diagnósticas.

En este caso, nos encontraremos 45 min el 21 de abril de 2017 (¡mañana!) para hablar sobre las estrategias de preparación de datos para pruebas automatizadas, de 13:15 a 14:00hs Bs As.

Agenda

  • Presentar el concepto (10 min).
  • Trabajar en grupos para analizar el ejemplo, o un caso particular (20 min).
  • Presentar los resultados (10 min).
  • Cierre (5 min).
Anotate

(Próximo encuentro, viernes 28 de abril, votá los temas)



Cápsula de Pruebas - Datos de Prueba

¿Cómo generar los datos de prueba?
¿Cómo lograr que los datos estén en disponibles en el momento de la prueba?


¿Cómo lo he hecho?

Para ejecutar las pruebas automáticas, necesitamos que la aplicación o SUT (System Under Test) esté en un estado conocido. Ese estado incluye los datos necesarios para la prueba.


Toma una prueba que estés realizando en este momento o que realizaste hace poco, piensa y anota:
  • ¿Cómo obtuviste o generaste los datos de prueba?
  • ¿Cómo lograste que esos casos de prueba estén cargados o disponibles para el SUT?


Generación de datos

Por Diseño: Se inventan datos que ejercitan la funcionalidad a desarrollar. Los ejemplos pueden estar basados en la experiencia en el negocio o en las hipótesis de uso futuro. Por ejemplo, generar datos que corresponden a situaciones límites y de error, hayan ocurrido o no.


Datos Reales: Tomar un conjunto de datos de la aplicación actual o del problema a resolver. Por ejemplo, tomar los conceptos facturados  en el último mes, o los clientes y movimientos de una sucursal durante el año pasado.


Simulados: Utilizar un algoritmo para generar datos. Por ejemplo, todas las combinaciones posibles de los variables de entrada, o valores aleatorios.


Object Mother: Cada entidad de la aplicación tiene un mecanismo para generar objetos de prueba. Normalmente con datos default y las entidades adicionales las genera recursivamente. Por ejemplo, una prueba que necesita un cliente, la prueba le pide a la entidad Cliente una instancia de prueba. Cliente genera un cliente que tiene un nombre y apellido default (Juan Perez). Para completar el país de nacimiento,  Cliente le pide a la entidad Pais una instancia de prueba.


Estado conocido

Cargar cada vez: Cargar los datos para cada prueba. Esto puede hacerse a diferentes niveles: desde el repositorio de los datos (base de datos, archivos), desde una capa de servicios o componentes, a través de la funcionalidad disponible para el usuario final. Puede cargarse a partir de un estado inicial vacío, o como incremento. Puede ser necesario modificar datos (fechas, números de referencias cruzadas).


No cambiar: Se llega al estado conocido y se lo proteje. Por ejemplo backup y restore de bases de datos, se utilizan transacciones de base de datos, se realizan operaciones que no modifiquen datos o se realizan operaciones que revierten la operación realizada en la prueba.


Existentes: Asumiendo que tenemos un volumen alto y variado de datos, realizamos una búsqueda que nos traiga un dato con las características que necesitamos.


Mock (o dobles): Reemplazamos un componente del sistema, que no nos interesa probar, por un mecanismo que devuelva datos conocidos. Pueden ser siempre los mismos datos o puede ser más inteligente.


Actividades

Analiza el siguiente ejemplo y proponer la estrategia para los datos de prueba:


Tenemos una aplicación monolítica que resuelve una parte central del negocio de nuestra organización. Siguiendo las buenas prácticas actuales, se busca migrar hacia una arquitectura de microservicios. La migración será incremental, y en cada micro servicio se va a realizar en dos fases: duplicar funcionalidad mínima de la aplicación actual, y luego agregar funcionalidad nueva, valiosa para el negocio.
La aplicación actual tiene algunas pruebas automatizadas a través de la UI.
Queremos que puedan trabajar en paralelo los equipos que modifican el sistema monolítico remanente y los que desarrollan cada nuevo micro servicio.
¿Qué alternativas tenemos para generar los datos de prueba?
¿Cuáles son los pros y contras de cada una de las alternativas?

jueves, 30 de marzo de 2017

Capsulas de Testing - Estrategias de Datos


En los equipos que desarrollan ágilmente se busca que todos los miembros del equipo tenga un conocimiento mínimo de las actividades de testing. También que los testers profundicen su conocimiento.

¿Cómo podemos distribuir ese conocimiento?
Las cápsulas de información de testing son una manera incremental de incorporar conceptos a partir de ejemplos del equipo o externos. Pueden servir como guía para realizar círculos de aprendizaje en el equipo de desarrollo o para profundizar conocimientos en comunidades de práctica.
Algunas cápsulas de conocimiento: Arquitectura de la prueba Automática, Modelo del Oráculo y Pruebas Diagnósticas.

En este caso, nos encontraremos 30 min el 31 de marzo de 2017 (¡mañana!) para hablar sobre las estrategias de preparación de datos para pruebas automatizadas.

Anotate



jueves, 26 de enero de 2017

TestComplete y Git

En un grupo están trabajando con TestComplete, una herramienta que permite automatizar aplicaciones de escritorio (y muchas más cosas).
Estaban manteniendo las pruebas con versionado por directorios y decidimos moverlos a git.

La solución es sencilla, ya que TestComplete tiene integración con git.

Agregar en la raíz un archivo .gitignore con contenido
Log/

Luego se pueden seguir los pasos normales para subir un proyecto existente a un repo. Por ejemplo en GitHub.


¿Y que pasa si te olvidás del paso del .gitignore?

En ese caso, la subida de los logs puede tardar mucho tiempo, incluso dar timeout. En nuestro caso, contenido completo de la carpeta del proyecto con sus logs pesaba 500Mb!

¿Cómo borrar completamente algo de Git?

Quitar de la versión

En este caso, para borrar todos los directorios Log


find . -name Log -print
Tomar de la salida todos los directorios resultantes y armar lineas como la que está a continuación, que quitan los directorios del repo local, pero lo dejan fisicamente.
git rm -r --cached <directorio>/Log

Luego podés validar que estén borrados en Git.
Ahora si, agregá el .gitignore (como está indicado arriba).
Y comitear y subir al repo. 
git status
git commit -m ‘borrar logs’
git push

Validar que en repo remoto no esten los Logs.


Quitar de toda la historia

No es común querer modificar la historia de Git. Y la forma estandard brindada por git es lenta.
Usamos una herramienta llamada BFG.

git clone --mirror https://github.com/<user>/<repo> <repo>_mirror
cp -a <repo>_mirror/ <repo>_backup/
cd <repo>_mirror
java -jar ~/Downloads/bfg-1.12.14.jar --delete-folders Log
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push


En nuestro caso, pasamos de un repositorio de más de 1Gb a uno de 380Mb.

miércoles, 18 de enero de 2017

Desarrollo ágil de Software - stack Python

Soy uno de los facilitadores del curso Desarrollo Ágil de Software (DAS) de Kleer.
Lo solemos hacer con Ruby (alguna vez lo hemos dado en Java y C#).

Afortunadamente, hace poco lo hicimos en Telefonica I+D Chile y nos pidieron hacerlo con Python ¡Gracias!

Le comento mi experiencia y les dejo la referencia del ambiente https://github.com/jgabardini/csdpy, lo pueden reproducir en Linux (o la virtual de DAS con Mint)

Resumen de Stacks

En el ambiente Ruby, las herramientas son: bundle, rspec, cucumber, webrat/capybara, sinatra con erb.

En el ambiente Python: virtualenv y pip, behave, splinter, flask con jinja2. Además, usé un plugin de Jenkins: ShinningPanda.

Python

No hubo problemas porque la mayoría ya programaba en Python (había dos o tres personas sin conocimiento, pero que se sumaron rápido).
Algunos prefirieron usar sus ambientes, por los editores (sin usar la virtual). La virtual tiene Gedit, ellos usaban Visual Studio Code, vim, ....
Usé Python 3.4 (en vez de 2.7 que es el default en la virtual de DAS).
Para manejar versiones y ambientes use virtualenv y pip.

Unittests

Usé nosetests como test runner. Extrañé la sintaxis BDD (de rspec), pero ellos no 😉
Para el próximo (que por suerte es la semana que viene), daré instrucciones concretas sobre la estructura de directorios. Los desarrolladores Python NO tienen el mantra Convention over configuration, cada uno lo hace distinto si los dejas libres 🙌. Y explicaré las reglas de descubrimiento de pruebas de nosetests, eso hubiera ayudado (tests/xxx_test.py).

Flask

El código mínimo es un poco más largo que el de Sinatra y, como yo no tengo tanta práctica, no lo escribí de cero. Usé el código del repo csdpy desde el inicio.
Cuando falla el routing u otro error, no es tan amistoso como Sinatra, no muestra una página 500 con información de que falta.
Usar annotation para definir el routing, obliga a tener funciones por cada mapeo, y es natural que la misma función cubra varios métodos HTTP. Cometí muchos errores de nombre método duplicado, acostumbrado a los bloques de Ruby.
Los asistentes no tuvieron mucho problemas (o los resolvieron).
Nuevamente, Flask es menos prescriptivo que Sinatra. Yo propuse una estructura de directorios. 
El motor de templates, Jinja2, lo usé simplificado. Sin layout, bloques ni herencia. Es el motor usado en  Django.

Behave

Sigue bastante la idea de Cucumber, excepto que los pasos son distintos para cada palabra clave (Given/When/Then). En Cucumber, un paso está definido solo por el texto. En Behave los pasos se definen por la combinación palabra clave + texto. Tuve el mismo problemas con nombres de métodos repetidos que en routing de Flask.
No propone pasos con regex  "automáticas". Uno debe agregar los parámetros a mano.

Splinter

Usé Splinter que equivale a webrat/capybara. Pinta muy bien. Tiene una API muy parecida a WebDriver y puede usar los driver de WebDriver, o flask (me parece que inprocess, pero no lo encontré la documentación).


Configuración de Jenkins

Para correr tareas que requieren virtualenv, use un plugin ShinningPanda. Todas las tareas configuradas como shell.
Para que corra el behave tuve que agregar un package: behave-jenkins.

Conclusiones

Hacer la migración de Ruby a Python me llevó un día neto de trabajo. Bien sencillo.
Luego de 3 años de programar principalmente con Ruby, me sentí raro en Python. Me falta práctica. Por suerte, la semana que viene volvieron a pedirme, esta vez en Córdoba, que hagamos el curso en Python 😎