¿Un QA puede ser también developer?

Assert QA == Developer


¿Es un QA un developer?
Me gusta hablar con la gente. Me gusta compartir opiniones. Me gusta debatir. Tras varias conversaciones con compañeros de trabajo, de los que he podido obtener de una forma u otra feedback de lo que creen que es el trabajo de un QA Engineer, me he propuesto a escribir un post que ayude a romper ciertas barreras mentales en el trabajo que creemos que hace un ingeniero de calidad y ver si en realidad es un developer.

Ingeniería de la calidad del software

La realidad es que poca gente conoce lo que es la ingeniería de la calidad. No es algo conocido, no es algo que llame la atención cuando decides estudiar informática, es la realidad.

Cuando un desarrollador habla de un QA, no piensa que desarrolle, no lo trata como un desarrollador. Es más, muchos piensan que los QAs son desarrolladores frustrados, y no es cierto.

¿Porque cuesta tanto ver la ingeniería QA como una rama de la ingeniería del software, del desarrollo?

Cuando se piensa únicamente desarrollamos pruebas se está muy equivocado. La calidad del software no solo se garantiza con teses.

Desarrollamos teses, ¡por supuesto que sí! Y en muchas ocasiones la lógica que implementamos en el test puede ser más compleja que el código o la funcionabilidad que probamos. Y si… sabemos lo que son los patrones… es más, los aplicamos.

Para garantizar que el software cumple con los requisitos de calidad exigidos los QAs deben diseñar y aplicar las estrategias de calidad necesarias. Y muy seguramente en esas estrategias se implementen diferentes proyectos, desde automatización de pruebas hasta proyectos más complejos, y adivinad, muchos de ellos habrá que desarrollarlos.

Automatización de pruebas

Automatizar pruebas funcionales no siempre significa automatizar el comportamiento de una funcionalidad mediante UI testing. En muchas ocasiones se requiere hacer pruebas funcionales a nivel de API, o probar funcionalidades cross-aplicación y cross-dispotivo.

Aquí os dejo los enlaces a la presentación y explicación de cómo Uber realiza pruebas cross-aplicación y cross-dispotivo para probar sus aplicaciones mediante Octopus.

POST:
https://eng.uber.com/rescued-by-octopus/
SLIDE:
https://docs.google.com/presentation/d/1vYXhkvgLKun72Ix91LQDDWZQdcY5VOBqKVvI1Y6riYo/pub?slide=id.gd8d657045_0_0

VIDEO:
https://www.youtube.com/watch?v=p6gsssppeT0

Para mi es importante entender que un QA no es una persona dedicada únicamente a automatizar pruebas o a realizar testing. Es un ingeniero capaz de desarrollar las herramientas necesarias que ayuden a garantizar la calidad de la aplicación.

Lo que significa que un QA es un desarrollador especializado en la calidad.

Sí, somos un equipo

Una de las cosas que me dijeron era que si el que desarrollaba la tarea hacia bien su trabajo no tenía por qué meter bugs, y ya que sabía lo que estaba desarrollando y donde afectaba él podría hacer las pruebas, por lo tanto, los QAs sobraban.

Bueno, en un mundo perfecto donde el desarrollador está encantado de probar todo lo que hace, y donde el tiempo de entrega no existe, en el que nunca se equivoca, puede ser…¡pues tampoco! Que te diga coca cola o Samsung que no hacen control de calidad de sus productos… igual sus móviles explotarían.

Es necesario desarrollar estrategias y proyectos que garanticen la calidad de nuestras aplicaciones, equipar al equipo de desarrollo con las herramientas suficientes para hacer código de calidad, para agilizar su desarrollo.

Cada equipo somos piezas del desarrollo. Desarrollo, DevOps, Producto, QA etc.

Conclusiones

Antes de ser QA fuí desarrollador, y hoy en día sigo desarrollando casi al mismo nivel que antes, salvo que antes funcionalidades de una aplicación, y ahora herramientas que garantizan su calidad. ¿Qué diferencia hay?

Los QAs también somos desarrolladores, es la realidad, y primero nos lo tenemos que creer nosotros para que los demás se lo crean.

 

 

 

 

Estrategia Prevention & Reaction – Parte II

Introducción

En el capitulo anterior vimos en qué se basaba la estrategia de Prevention & Reaction y cómo la aplicábamos en tiempo de RC. En esta segunda parte vamos a ver qué es el tiempo de producción y qué herramientas de calidad utilizamos para poder aplicar la estrategia Prevention & Reaction.

Tiempo de Producción

production time

Denominamos tiempo de producción al estado en que la release ha llegado a desplegarse en los entornos de producción. El software ya se encuentra disponible para que los usuarios lo utilicen, por lo que los errores que hayamos dejado pasar en tiempo de RC serán detectables por los usuarios. Las herramientas de calidad que actúan en tiempo de producción nos ayudarán a prevenir esta situación.

Prevención en tiempo de Producción

Prevention in production time
Las herramientas de prevención en tiempo de producción tratan de obtener información del estado y de las acciones de los usuarios y así poder utilizarlas en tiempo de RC. La información que obtengamos del entorno de producción nos servirá para adelantarnos a problemas aún no descubiertos por los usuarios, así como servirnos de datos para nuestras pruebas previas.

La información principal que obtendremos de producción es la siguiente:

  1. Trazas de errores: Lo que nos permitirá detectar bugs antes de que los usuarios sean conscientes, o proveernos de información para solucionar los fallos.
  2. Acciones de usuario: Hay ocasiones en las que los usuarios realizan acciones que no son contempladas por el equipo QA; con esta información podremos obtener mapas de calor de acciones y ajustar y mejorar nuestros casos de prueba.
  3. Datos de entrada: Obtener datos de entrada reales para nuestras pruebas puede ayudarnos a aumentar de alguna forma nuestra cobertura.

 

Como se puede observar, las herramientas que se plantean intentan obtener información para ayudar a las fases anteriores de la estrategia y así minimizar el riesgo de inserción de bugs en RCs futuras.

Reacción en tiempo de Producción

reaction in production
Cuando el software se encuentra en producción es probable que el usuario reporte bugs o, en el peor de los casos, que sea necesario tratar un fallo bloqueante que requiera de un hotfix. Las estrategias en tiempo de producción intentan manejar estas situaciones.

Bien es cierto que el tratamiento de bugs y el protocolo de actuación frente a la necesidad de realizar un hotfix es muy personal a la empresa, pero  lo que aquí intento mostrar es una estrategia básica del tratamiento de un caso de hotfix.

Aparte de las dos etapas clave de desarrollo de la solución y posterior fase de pruebas por parte del equipo de QA, es muy importante recabar la información necesaria para alimentar la heurística del sistema de predicción de bugs del que hablamos en el capítulo anterior, así como para hacer análisis y retrospectivas.

Conclusiones y adelanto

El capítulo aporta puntos bastante importantes en cuanto a las estrategias que seguimos en el tiempo de producción. Cuando la aplicación se encuentra en producción, los usuarios se toparán con los errores a no ser que podamos prevenirlos mediante la información que vamos obteniendo a lo largo del proceso.

Debemos disponer de un protocolo para tratar los errores bloqueantes: el protocolo debe ser lo suficientemente eficaz para que el impacto, tanto para el usuario como para el negocio, sea mínimo. Esto se traduce en un protocolo que nos aporte garantías en cuanto a la validez de la solución, así como rapidez en el desarrollo de la misma. Estos errores nos deben ser de ayuda para prevenir errores futuros.

La mayor fuerza estratégica de Prevention & Reaction la encontramos en tiempo de RC, ya que un error en producción es una muestra de que la estrategia no se está aplicando correctamente. No obstante, no debemos darle menos importancia al tiempo en producción ya que nos aporta una gran información con la que podremos mejorar nuestras pruebas.

En el próximo y último capitulo veremos como aplicar la estrategia mediante grupos de trabajo.

Estrategia Prevention & Reaction – Parte I

Introducción

Con las metodologías ágiles, el software se encuentra en un desarrollo continuo, de una forma iterativa e incremental, de forma que la mayoría de empresas despliegan diariamente una o más versiones de su aplicación.

Este hecho provoca que las estrategias de aseguramiento de la calidad (de ahora en adelante QA) deban adaptarse, dado que únicamente cubrían las necesidades de las metodologías tradicionales.

Actualmente existen empresas que implementan metodologías ágiles sin la necesidad de perfiles de calidad, siendo los desarrolladores quienes la aplican, mediante el desarrollo de pruebas unitarias y de integración. Esto es debido a que los equipos de calidad pueden demorar o ser un bloqueo en dichas iteraciones de desarrollo.

Tras en análisis anterior se me ocurrió como trabajo personal desarrollar una estrategia que aplicara esa idea. La estrategia “prevención y reacción” pretende adaptarse a las metodologías y equipos ágiles garantizando la calidad del software, tanto en fases de desarrollo como en fases posteriores y puesta en producción.

Contextos de prevención y reacción

El término de prevención se refiere a evitar la inserción de bugs en el desarrollo; por el contrario, el término de reacción se refiere a la actuación de localizar los fallos y al tratamiento en caso de hacerlo.

Diferenciamos dos contextos o tiempos diferentes en los que operan las estrategias tanto de prevención como las de reacción: Tiempo de la release candidata (en ahora en adelante RC) y tiempo de producción.

Tiempo de RC

rc_time_contexts

Llamamos tiempo de RC al estado en la que la release no ha sido desplegada en producción. Comienza en la toma de requisitos del desarrollo hasta la fase de pruebas de la RC.

Prevención en tiempo de RC

strategies
Las estrategias de prevención en tiempo de RC tratan de evitar la inserción de bugs o errores en la RC, de tal forma que la RC llegue a la fase de pruebas lo menos impactada posible.

Las estrategias operan fundamentalmente en tres fases del desarrollo de la RC:

  • Fase de diseño: En la fase de diseño, el equipo de calidad debe obtener información de los criterios de aceptación por parte del equipo de producto. Se podría obtener en fase de requerimientos pero es probable que en la fase de diseño estén más definidos, por lo que aquella (la fase de requerimientos) sigue siendo una etapa temprana.
  • Fase de desarrollo: Implementación de un sistema de predicción de bugs. Nos garantizará una información objetiva de los riesgos de los desarrollos realizados en la RC, puntos conflictivos y propensos a fallo. Mediante un sistema de predicción se pueden focalizar las pruebas con mayor precisión y así reducir el tiempo de ejecución de las mismas.
  • Fase de pruebas: Antes de generar la RC (la cual se enviará a pruebas finales) es necesario que pase  pruebas de análisis estático, unitarias, integración y funcionales. El equipo de desarrollo será el encargado de desarrollarlas. La petición finalizará  una vez esté el desarrollo junto con las pruebas. Se realizarán pruebas bajo demanda por parte del equipo de calidad. Todos los resultados se analizarán y se utilizarán para el sistema de prevención y futuras retrospectivas.

Aplicación estrategias

La imagen muestra una forma de aplicar las estrategias de prevención en tiempo de RC.

  1. Se desarrolla la petición junto con las pruebas por parte del equipo de desarrollo. El sistema de predicción obtiene los datos de los cambios realizados.
  2. Se ejecutan las pruebas desarrolladas unitarias y de integración. Los resultados se almacenan para un posterior análisis. Esos datos servirán para alimentar la heurística del sistema de predicción de bugs.
  3. Se despliega la petición en un nuevo entorno.
  4. Se ejecutan las pruebas funcionales. Los resultados se almacenan tanto para el análisis como para el sistema de predicción.

Reacción en tiempo de RC

Reaction in RC time

Las estrategias de reacción en tiempo de RC tratan principalmente de localizar los errores que se nos han “pasado” en la fase de prevención. Dado que la RC ya ha sido generada, los errores ya se encuentran ella, por lo que es tiempo de reaccionar y localizarlos.

Es bien cierto que en esta fase se implementan estrategias o acciones que garantizan la calidad de la aplicación que en la fase anterior no se podrían aplicar.

Como se puede ver, la intención no es solo asegurar la calidad desde un aspecto funcional, si no que intentamos realizar pruebas que garanticen el rendimiento y la seguridad de la aplicación.

reacción rc

La imagen muestra una forma de aplicar las estrategias de reacción en tiempo de RC.

  1. Se despliega la RC en un entorno de pruebas.
  2. Se ejecutan las pruebas de calidad. (Funcionales, UAT, security, performance…) Los resultados se almacenan para un análisis posterior y como heurística del sistema de predicción de bug.
  3. Se acepta o rechaza la RC.

La fase de reacción en tiempo de RC es la última antes del despliegue en producción, lo que significa que localizar un bug en producción que se ha insertado en la RC es un caso de fracaso.

Conclusiones y adelanto

Hemos visto cómo aplicar la calidad del software en tiempo de RC en dos contextos diferentes: Preventivo y reactivo.

Entender los dos contextos nos ayudará a conocer las diferentes estrategias que aplicamos y saber el porqué. Garantizaremos la calidad del software desde etapas tempranas y focalizaremos la mayoría de nuestros esfuerzos a generar RCs validas. De esta forma ahorraremos tiempos en el testing, dado que centralizamos las pruebas y en el desarrollo, dado que minimizamos la aparición de bugs.

En esta fase es muy importante la obtención de los datos. Los resultados de las pruebas sirven para realizar retrospectivas que ayuden a valorar el éxito de la aplicación de nuestra estrategia de calidad, debido a que si en la fase de pruebas no encontramos fallos que posteriormente se encuentran en producción deberemos tomar medidas. En el caso de los datos de predicción, nos ayudarán a focalizar nuestras pruebas, por lo que tendremos más opciones de encontrar posibles fallos y reduciremos nuestro tiempo de testing.

En el próximo post de la serie analizaremos los contextos de prevención y reacción en tiempo de producción. Veremos cómo los datos de producción nos pueden ser de gran ayuda para adelantarnos a fallos y cómo nos servirán para objetivizar nuestras pruebas.

Testing de microservicios – Estrategias

Introducción

Cada vez va cogiendo más fuerza el desarrollo usando arquitectura de microservicios por lo que el mundo de la calidad de software ha necesitado de nuevas estrategias. En este post hablaremos diferentes estrategias que se utilizan para garantizar la calidad de los microservicios.

Breve introducción a los microservicios

La arquitectura en microservicios busca desarrollar una aplicación dividiéndola en pequeños servicios (cada uno con su lógica de negocio) que corren de forma autónoma y que se comunican entre sí. Pero, ¿Que beneficios e inconvenientes nos aporta frente a la arquitectura monolítica?

microservicios

Como se puede apreciar en la imagen, una arquitectura monolítica es divida en varios servicios creando así una arquitectura de microservicios, donde cada servicio se comunica entre sí aportando la funcionalidad que ofrecía en su arquitectura monolítica.

 

BENEFICIOS

  • Cada microservicio es independiente por lo que su despliegue y desarrollo también, un cambio en uno no afecta en los demás.
  • La comunicación se  realiza mediante su interfaz pública (API) por lo que el lenguaje de desarrollo de los microservicios es independiente.
  • Mayor gestión de la escalabilidad, podemos escalar solo los microservicios que reciban más carga.

INCONVENIENTES

No todo son beneficios y es que la arquitectura en microservicios también nos aporta ciertos inconvenientes y retos, muchos de ellos debido a la introducción del concepto de sistemas distribuidos.

  • En el caso que una aplicación se componga de muchos microservicios es necesaria una mayor coordinación en los despliegues.
  • Será necesario una buena monitorización debido a que nos basamos en una arquitectura con un flujo muy dependiente de la comunicación. Un error en un punto del flujo tiene que ser rápidamente reconocible.
  • Garantizar la consistencia de los datos es un punto a tener en cuenta.
  • La saturación de la red puede afectar gravemente en el rendimiento de nuestra aplicación.
  • Las estrategias de calidad son mucho más complejas que en sistemas monolíticos debido a que no solo tendremos que testear los microservicios de forma independiente si no la funcionalidad en el flujo de los datos.

Estrategias de testing 

Como hemos dicho en la introducción, el mundo de la calidad del software ha tenido que aplicar nuevas estrategias de calidad para el reto que supone garantizar la calidad de las aplicaciones con arquitectura de microservicios.

En mi opinión el reto no se encuentra en el testing individual de cada microservicio, si no, en la integración y en la garantía de la consistencia de los datos. En comparación con los sistemas monolíticos, en una arquitectura por microservicios o distribuida el QA/Tester va a necesitar de un mayor conocimiento de la arquitectura y del flujo existente, debido a que es necesario controlar y verificar la información en todos los puntos de comunicación así como la funcionalidad de todos los microservicios.

La estrategia principal o las pruebas que se realizan son las siguientes (teniendo en cuenta que la estrategia es muy dependiente del proyecto que nos encontremos):

  • Tests unitarios: Como en todo proyecto ya sea monolítico o no, son necesarias pruebas unitarias. Mediante las pruebas unitarias comprobaremos la funcionalidad de los métodos o módulos de código que creamos necesarios.
  • Tests de integración: Los teses unitarios prueban los componentes de forma aislada por lo que también necesitamos probar el comportamiento entre los métodos. Debemos tener en cuenta que solo probaremos el comportamiento de los métodos de cada aplicación de forma aislada (de cada microservicio), por lo que las llamadas entre microservicios las mockearemos.
  • Tests de contratos o de API: La arquitectura de los microservicios depende de la comunicación entre los diferentes servicios. Cada microservicio presenta una API que consumen los demás microservicios, cuando la diseñamos estamos definiendo un “contrato”. Debemos realizar los diferentes tests a las APIs de los microservicios para garantizar que se mantiene el “contrato”.
  • Tests E2E: E2E (end-to-end) o teses funcionales tratan de garantizar la calidad de nuestra aplicación sin la necesidad de mockear  ningún método o llamada. Un test recorrerá la funcionalidad entre todos los microservicios que requiera. Debemos tener en cuenta que son susceptibles a fallar por motivos agenos a la funcionalidad (problemas de red, perdida de datos etc.). En el caso de los microservicios se recomiendan seguir unas reglas que nos ayudarán a reducir el esfuerzo de nuestros teses:
    • Dado que las pruebas E2E son difíciles de mantener, debemos intentar centrarnos en probar solo las funcionalidades más importantes, probando las demás en teses unitarios o de integración.
    • El uso de WebDrivers como selenium para probar las funcionalidades de usuario tiene un coste grande en cuanto a mantenimiento por lo que la mayoría de las acciones del usuario podemos hacerlas simulando las llamadas a la API.
    • Debemos intentar mantener un entorno limpio para cada ejecución dado que las pruebas son muy dependientes de los datos y pruebas anteriores pueden desestimar el resultado de los teses.

Referencias

  1.  http://testdetective.com/microservices-testing/
  2. http://www.sczyh30.com/vertx-blueprint-microservice/index.html

Explorando el “Exploratory Testing”

Introducción

 

Después de leer en varios blogs entradas sobre “exploratory testing” y como ha evolucionado desde 1.0, 1.5, 2.0 y 3.0 me he propuesto hacer un pequeño artículo para ayudar a valorar su importancia más allá de la teoría y ver su practicidad.
No voy a entrar a hablar sobre la evolución del testing exploratorio dado que James Bach ya lo explica de forma bastante detallada en en su artículo.

Exploratory testing

 

El ET (exploratory testing) sigue siendo una parte importante en la garantía de la calidad de nuestro software, a la que en menor o mayor medida no damos tanta importancia. La mayor importancia en los test exploratorios y clave para su éxito son sus bases o sus características:

  • Aprendizaje de la aplicación
  • Diseño de tests
  • Ejecución de tests

Resultado de imagen de exploratory testingEl QA deberá garantizarlas de forma simultanea a medida que va probando la aplicación, es decir, va diseñando las pruebas y ejecutándolas al tiempo que va adquiriendo conocimientos de la aplicación.

Esto puede generar disparidad de opiniones dado que al tester se le puede exigir un conocimiento del funcionamiento de la aplicación para poder validar las diferentes funcionalidades que la componen. Pero debemos ir un paso más adelante.  No estamos hablando de basar la calidad de la aplicación en este tipo de teses, si no de hacer uso de ellos para potenciar las habilidades de los testers y la búsqueda de bugs.

Algunos podréis estar de acuerdo conmigo, en el hecho de que cuando realizamos pruebas sobre una nueva funcionalidad o una nueva aplicación nuestra atención es mayor (menos comodidad, menos monotonía, desconocimiento de la funcionalidad etc), esto suele generar mejores resultados en cuanto a encontrar bugs.

Y como hemos podido observar la herramienta más importante para este tipo de test son las skills o las capacidades del tester en cuestión. Es importante disponer de la capacidad de pensar o diseñar los casos de prueba a medida que se avanza en las pruebas, discernir lo que es importante probar durante la sesión de pruebas, localizar los criterios de aceptación, en resumen, disponer de cierta experiencia e imaginación para el testing.

No obstante la experiencia se gana a medida que se hacen pruebas, por lo que es una muy buena herramienta para que los testers ganen y mejoren sus habilidades.

Experiencia y opinión

 

En el tiempo que llevo como QA lo cierto es que tengo más experiencia en la automatización de pruebas funcionales o manuales que exploratorias por lo que he dispuesto de un test plan (ya sea heredado o diseñado por mi) para desarrollar o ejecutar las pruebas.

Ahora cumpliré casi 10 meses en la empresa actual y realizamos  tanto automatización como pruebas manuales. Durante mi proceso de aprendizaje de la aplicación enfoque una gran parte del tiempo y del esfuerzo para realizar pruebas exploratorias lo que me ha llevado a tener un amplio conocimiento de la aplicación y a encontrar bugs que se salían del circuito “básico” de de pruebas. Hoy en día a pesar de que tenga interiorizado ese conocimiento y realice pruebas basadas en un test plan (que intento actualizar) suelo buscar un hueco para realizar pruebas exploratorias y sorprendentemente siempre suelo encontrar algún bug.

Siempre hay que tener en cuenta la situación o la estrategia del aseguramiento de la calidad de la empresa, pero como opinión personal creo que es importante implementar en la estrategia de calidad unas horas por recurso para que se realicen pruebas exploratorias. Esto va a ayudar a encontrar más fallos en la aplicación y sobre todo a mejorar las habilidades del tester.

Bibliografía

  1. http://www.satisfice.com/blog/archives/1509

 

Predicción de bugs, mito o realidad!

Introducción

Desde hace tiempo me produce bastante curiosidad el hecho de que puedan existir sistemas o algoritmos que nos puedan ayudar a “predecir” la existencia de bugs en nuestro software. Así leído puede parecer idílico e incluso algo difícil de creer dado que de base ya podemos pensar que hay muchos factores que pueden afectar a la inserción de un bug en nuestro código.

Para la predicción de bugs necesitaríamos una cantidad de datos importantes respecto al código, cambios realizados en la release, histórico de bugs. Y con todo ese caldo de datos…pum… magia?

Para que veáis que no solo puede afectar la parte técnica como curiosidad os dejo este enlace a un post que sobre todo es curioso.

Así que me he puesto a investigar un poco y ver la realidad y sobre todo los beneficios que nos puede aportar.

Algoritmo de predicción de bugs – FixCache

Existen varios algoritmos en lo que a la predicción de bugs respecta pero en este artículo me gustaría centrarme en el algoritmo FixCache y realizar una comparativa en artículos posteriores.

Actualmente existen dos tipos de estrategias para la predicción de bugs:

  1. Basados en las métricas de calidad como lineas de código (LOC) y la complejidad ciclomática.
  2. Basados en el control de cambios e histórico del repositorio.
fixcache_ratevstime
Imagen 1: Hit rate vs time for projects

FixCache entraría en el segundo grupo, dado que se sirve del repositorio de código para analizar los cambios y así predecir los posibles bugs.

En la imagen 1 vemos un ejemplo de la tasa de éxito del algoritmo FixCache sobre cuatro aplicaciones diferentes.

El algoritmo trabaja observando los cambios realizados en los ficheros o los métodos y utiliza tres heurísticas para añadir los ficheros a la “caché”:

 

 

 

  • Nuevos ficheros de código o modificados los cuales pueden contener bugs.
  • Ficheros que actualmente contienen bugs son propensos a contener más bugs (Aquí entra la teoría del “defect clustering”)
  • Ficheros que han sido modificados para solucionar algún bug son propensos a contener otros bugs.

Como hemos indicado para crear la “caché” de datos se sirve del repositorio de software, donde identificará los cambios realizados en los ficheros mediante los commits  al proyecto comparándolo con su propia base de datos o caché.

La gestión del caché es importante, normalmente cacheando un 10% de los ficheros del repositorio al finalizar el periodo de análisis. Es importante determinar si la caché está completa para remover los ficheros que no vayan a formar parte de posteriores análisis, para ello se pueden implementar varias políticas de reemplazo (parecido a las de la gestión de memoria caché de nuestro sistema):

  • El fichero menos utilizado recientemente (LRU).
  • El fichero que menos cambios ha tenido .
  • El fichero que menos bugs ha tenido históricamente.
  • El fichero que menos autores de cambios tenga.

Sería interesante ver que política de reemplazo da mejores resultados, lo cierto es que la más utilizada es LRU, me imagino que por su baja complejidad de gestión respecto a los demás.

Practicidad del sistema de predicción de bugs

Ya hemos visto un ejemplo de algoritmo que se basa en los cambios en los ficheros del repositorio pero,  ¿Que utilidad podemos darle al uso de un algoritmo de predicción de bugs?

En un sistema de CI (continuous integration) donde se aplique la metodología ágil, donde se realizan cambios a diario en el código y donde la intención es realizar despliegues a producción continuamente puede ser una muy buena opción para ayudar al equipo de QA en sus pruebas. Pongamos varios ejemplos:

  • Lanzar pruebas de regresión automáticas de aquellas funcionalidades o aquellos ficheros que el algoritmo detecte con riesgo de bugs en cada RC (release candidate).
  • Crear un “semaforo” que identifique las zonas de riesgo de la RC y así focalizar las pruebas o reforzarlas para prevenir bugs.
  • Mantener un histórico de ficheros conflictivos que puede ser utilizado a modo informativo por QA, desarrolladores etc.

Conclusiones

Depende de nuestro sistema de CI y la finalidad puede que nos sea más o menos viable implantar un sistema de predicción de bugs, lo cierto es que no muchas empresas disponen de ello (que se sepa) y puede ser interesante únicamente en los casos que se realicen cambios en nuestro código continuamente.

Bibliografía

  1. https://users.soe.ucsc.edu/~ejw/dissertations/AdaptiveBugPrediction_SungKim_Thesis.pdf
  2. http://static.googleusercontent.com/media/research.google.com/es//pubs/archive/41145.pdf
  3. http://www.mysmu.edu/faculty/davidlo/papers/csmr13-reopened.pdf
  4. https://users.soe.ucsc.edu/~supertri/docs/msr2011-final.pdf
  5. http://www.softwaretestingclub.com/profiles/blogs/defect-clustering-pesticide-paradox
  6. http://www.malavida.com/es/noticias/control-biometrico-para-predecir-errores-de-codigo-en-programacion-006101

Y que me dices de “Agile Testing Quadrants” – Parte III

Introducción a “Agile Testing Quadrants”

En los anteriores post de la serie hemos dado una pequeña introducción de lo que son los cuadrantes del testing  y las pruebas que realizamos en el primer cuadrante en “Y que me dices de “Agile Testing Quadrants” – Parte I” .

La importancia del segundo cuadrante y sus pruebas las tratamos en el post Y que me dices de “Agile Testing Quadrants” – Parte II” .

En este artículo vamos a hablar sobre el tercer cuadrante de los !Agile Testing Quadrants.

Agile Testing Quadrants

Tercer cuadrante – Q3

Para el cliente no solo es importante que el software funcione, el cliente espera que la aplicación funcione como tiene que funcionar en todos sus aspectos, es decir, que se cumplan todas sus necesidades y las “features” que se ofertan.

El tercer cuadrante de los “Agile Testing Quadrants” se preocupa de probar que el producto es el deseado, que la aplicación dispone de las funcionalidades que se han definido y que estás son correctas. En ocasiones nos encontramos con que se desarrolla una nueva funcionalidad que no es lo que espera el cliente, esto puede ser debido a que no se ha entendido bien los requerimientos, no se ha realizado un buen análisis o faltan casos por contemplar.

La clave de las pruebas del tercer cuadrante es ponernos en la piel del cliente, ya que vamos a intentar garantizar que se cumplen sus necesidades y que las funcionalidades son correctas.

En este tipo de pruebas emularemos el comportamiento del usuario mediante pruebas manuales. Realizar pruebas manuales requiere de ciertas habilidades por parte del tester:

  • Organización: Antes de realizar las pruebas es necesario organizar correctamente tanto las rutas de test para garantizar una buena cobertura como disponer de los datos necesarios para realizarlo.
  • Curiosidad: Durante el transcurso de las pruebas no puede faltar la curiosidad dado que vamos a tener que probar funcionalidades que probablemente no hayamos probado anteriormente.
  • Intuición: En muchos casos se detectan fallos o errores debido a que anteriormente nos hemos peleado con un escenario similar en el que hemos encontrado algún fallo. Este conocimiento nos dará cierta intuición en las pruebas.
  • Empatía: En muchos casos tenemos que ponernos en la piel del usuario para realizar ciertas pruebas. El usuario no siempre hace uso de las funcionalidades correctamente o no las utilizan como o para lo que se hicieron.

Me gustaría centrarme un poco más en el “Exploratory testing” pilar del tercer cuadrante. Este tipo de pruebas requiere de cada una de las habilidades que hemos hablado anteriormente. Durante la sesión el tester diseñará y ejecutará las pruebas analizando los resultados. La clave de este tipo de pruebas es que nos ayudará a aprender y a obtener mayor conocimiento de la aplicación que se está probando y lo más importante, a encontrar la mayoría de los bugs.

Como en los posts anteriores os hablaré de mi experiencia. Donde trabajo actualmente las aplicaciones que tenemos tienen muchos casos de prueba, muchas funcionalidades que aportan una mayor complejidad y mayor reto a los QAs. Normalmente me dedico a probar las RCs, a desarrollar pruebas automáticas y  a comprobar los bugs que se publican, pero cuando saco un rato libre me dedico a realizar “Exploratory testing” donde encuentro la mayor parte de los bugs, cierto es que son bugs antiguos que no han entrado con las nuevas funcionalidades. El realizar este tipo de pruebas me ha hecho aprender de la aplicación y a plantear dudas que se han podido traducir en conocimiento, bugs o en casos que no se han contemplado para dicha funcionalidad.

Conclusiones

 

El tercer cuadrante de los “Agile Testing Quadrants” se centra en comprobar que se cumplen las necesidades del cliente y que las funcionalidades de la aplicación son correctas. Para ello el tester tendrá que ponerse en la piel del usuario y disponer de ciertas habilidades que apoyen y den valor a las pruebas.

Uno de los pilares del tercer cuadrante es el “Exploratory testing” donde el tester durante la sesión diseñará, probara y analizará los resultados de las pruebas que va ejecutando manualmente, siendo el conocimiento aprendido de la aplicación uno de los objetivos más importantes.

Enlaces a la serie de posts

Histórico de los resultados de Geb – Parte I

Introducción

Cuando se lanzan pruebas automáticas uno de los pasos posteriores a la ejecución suele ser el análisis de los resultados. Es importante comprobar que las pruebas se han lanzado correctamente y verificar la veracidad de los resultados tanto positivos como negativos detectando falsos positivos. Es por ello que mantener un histórico de los resultados puede llegar a ser muy interesante y nos ofrece grandes ventajas:

  • Comparativa frente a resultados anteriores
  • Detección de falsos positivos en base al histórico de los mismos
  • Ver la evolución de las pruebas
  • Ver el crecimiento de cobertura

Se pueden listar un mayor numero de ventajas que se nos puedan ocurrir, pero lo más importante es que mantener un histórico nos va a proporcionar una fuente de conocimiento de las ejecuciones que podremos consultar en un futuro.

Como he escrito en el título, vamos a extraer los datos de los resultados de Geb, que nos permite realizar pruebas funcionales integrándose en nuestro caso con Spock.

Vamos a ello.

Resultados de ejecución

Al ejecutar las pruebas los resultados de la ejecución por defecto se almacenan en el directorio:

[project]/target/test-reports/

Vamos a encontrarnos con los siguientes ficheros:

TESTS-TestSuites.xml: Fichero con los resultados de la ejecución del test suite por completo

TEST-functional-spock-[Spec].xml: Ficheros con los resultados de las ejecuciones de los Spec. Uno por cada spec que esté definido.

Html: Directorio donde se encuentran los resultados en formato html

En nuestro caso vamos a extraer los datos del fichero TESTS-TestSuites.xml.

Análisis para extracción del histórico de resultados

Hemos lanzado las pruebas del proyecto que vimos en el post https://qajungle.com/restful-api-functional-testing/ . El fichero de resultados, en este caso con resultados positivos:

De estos resultados se puede ir observando que disponemos de varios datos interesantes para extraer, vamos a categorizarlos como datos informativos y mediciones.

Datos test suites

Dentro del fichero de resultados se listan los test suites que han sido ejecutados, en este caso solo uno, veamos que datos interesantes nos aportan:

testsuite errors="0" failures="0" hostname="aritzaguila.local" id="0" name="PostsAPISpec" package="" tests="1" time="0.912" timestamp="2016-06-21T09:42:17"

Datos informativos
Los datos informativos nos van a servir para identificar correctamente la prueba que se ha ejecutado.

  • Hostname: Nombre del host donde que se ha ejecutado la prueba. Puede ser interesante siempre que ejecutemos las pruebas en diferentes máquinas o en caso de que las balanceemos.
  • Name: Nombre del Spec que se ha ejecutado.
  • Timestamp: Hora la que se ha ejecutado el Spec.

Datos medibles
Los datos medibles nos van a servir para ver, medir, comparar y evaluar los resultados de las pruebas.

  • Errors: Errores de ejecución de la prueba. Normalmente suelen ser debido a excepciones de ejecución.
  • Failures: Fallos de la prueba. Normalmente suelen ser fallos los incumplimientos de las pruebas.
  • Tests: Número de tests ejecutados correctamente.
  • Time: Tiempo de ejecución del Spec, en milisegundos.

Datos test cases

Cada test suite dispondrá de los casos de prueba que se han ejecutado, en nuestro caso uno.

testcase classname="PostsAPISpec" name="check that the API returns all posts data" time="0.909"

Datos informativos

  • Classname: Nombre de la clase donde se encuentra el test case.
  • Name: Nombre del test case.

Datos medibles

  • Time: TIempo de la ejecución del test case.
  • Name: Nombre del test case, en milisegundos.

Es muy importante recalcar que en caso de que haya habido un error o un failure en el caso de prueba se añadirá una nueva etiqueta con la información del error o el failure.

Ejemplo para error:

En el caso de un failure la etiqueta sería <failure>.

Enlaces a la serie de post

  1. Creando un histórico de los resultados de Geb – Parte II

Y que me dices de “Agile Testing Quadrants” – Parte II

Introducción a “Agile Testing Quadrants”

En el post “Y que me dices de “Agile Testing Quadrants” – Parte I”  hablamos de lo que eran los cuadrantes del “testing” y dimos una pequeña introducción a las pruebas que se realizaban en el ámbito del primer cuadrante.

En este capítulo de la serie vamos a hablar de la finalidad de las pruebas del segundo cuadrante.

 

Testing Quadrants

Segundo cuadrante – Q2

Las pruebas del segundo cuadrante dan soporte al equipo de desarrollo desde un nivel más alto. Mediante las pruebas manuales y automáticas verificaremos que se cumplen los requerimientos de negocio.

Lo importante de las pruebas del segundo cuadrante es que intentaremos automatizar la mayoría de las mismas, cierto es que posiblemente haya algunas pruebas que tengamos que hacerlas manualmente debido a la complejidad de la automatización o al interés mismo de la prueba bajo el coste de automatización.

A diferencia del primer cuadrante en el segundo se realizan mayor tipo de pruebas para verificar los requerimientos de negocio:

  • Pruebas funcionales para verificar la funcionalidad de la aplicación. El mayor ejemplo lo podemos ver en las pruebas a nivel GUI, que validan las funcionalidades de la aplicación desde la capa visual. Se desarrollan con frameworks que ayudan a automatizar las acciones en el navegador, como por ejemplo selenium.Pero las pruebas funcionales no solo se realizan a nivel GUI, también se realizan otro tipo de pruebas funcionales como por ejemplo de API.
  • Pruebas de historia, para verificar que se cumplen correctamente las historias definidas desde negocio.

Estas pruebas nos exigen tener un conocimiento amplio de las necesidades a cumplir por lo que nos exigirán tener una gran comunicación tanto con negocio como con desarrollo, así como disponer de ejemplos que nos ayuden a diseñar las pruebas.

Al igual que en post Y que me dices de “Agile Testing Quadrants” – Parte I”  voy a aportar un poco de experiencia personal.

En una empresa anterior en la que trabajé en uno de los proyectos nos encargábamos de la calidad de las aplicaciones del cliente. El cliente nos hacia llegar un documento enorme con las pruebas que hacían manualmente para que las fuéramos automatizando. Nosotros no conocíamos la aplicación, por lo que cada dos por tres teníamos que ir con el equipo funcional para preguntarles que querían automatizar y lo más importante , que querían verificar dado que la funcionalidad era tan compleja que hasta a ellos mismos a veces les costaba conocerlo. Aquí se ve la importancia de la comunicación en el proceso del diseño de las pruebas.

En la empresa que estoy actualmente es todo muy diferente, el seguir una metodología ágil lo simplifica todo. Los QA disponemos de un tablón el que vemos lo que se está desarrollando, tenemos comunicación directa con los desarrolladores y con producto por lo que las dudas las solventamos rápidamente. Esto se resume en que el diseño de las pruebas se pueden realizar antes de que la historia esté desarrollada por lo que la automatización posterior será mucho fácil.

Conclusiones

Mediante las pruebas que se realizan en el segundo cuadrante verificaremos los requerimientos de negocio de nuestra aplicación pero para poder diseñar las pruebas es muy importante la comunicación tanto con desarrollo como con negocio.

Es posible que en algunos libros o artículos se categoricen las pruebas del segundo cuadrante como pruebas de aceptación, pero en realidad las pruebas de aceptación abarcan mucho más dado que no solo compruebas los requerimientos de negocio, también los de sistema, usabilidad y rendimiento.

Enlaces a la serie de posts

Y que me dices de “Agile Testing Quadrants” – Parte I

Introducción a “Agile Testing Quadrants”

Si alguna vez habéis trabajado con metodologías de desarrollo ágil cabe la posibilidad que conozcáis u os suene el concepto de “Agile testing quadrants”. Básicamente categoriza las pruebas de “testing” que podemos realizar en base a los diferentes propósitos.

 

Agile testing quadrants

En el gráfico se divide en cuatro cuadrantes que a su vez comparten un propósito y cada cuadrante es responsable de un tipo de pruebas en concreto.

El concepto en si no pretende ser una metodología o un marco de trabajo que se tenga que seguir a rajatabla en cada fase. Únicamente es un concepto que nos ayuda a tener focalizado en qué fase o en qué contexto aplicamos un tipo de prueba u otro ayudándonos a entender su finalidad.

Explicado esto, la idea del post es aportar un poco la visión de cada punto y en algunos puntos hablaré sobre mi experiencia y mi opinión.

Primer cuadrante – Q1

Uno de los principales pilares de la calidad de la aplicación son las pruebas unitarias o de componente dado que desde fases tempranas del desarrollo, siempre que se aplique de una forma correcta, se van a estar probando las partes de código o los métodos del código más importantes que componen nuestra aplicación.

En el desarrollo ágil, la metodología TDD (test-driven development) sería el núcleo de este cuadrante debido a que primeramente se desarrolla la prueba unitaria y se va implementando el código de la lógica de la aplicación mediante la refactorización, lo que aporta mayor garantía de calidad.

En este punto creo que puedo aportar cierta experiencia. Cuando comencé a desarrollar en la primera empresa que trabajé no realizábamos pruebas unitarias y menos utilizamos metodologías ágiles, esto se debía en parte a falta de conocimiento y en parte a las dichosas fechas.

Esto suponía que un cambio en el código nos podía “romper” ciertas funcionalidad que en “teoría” funcionaban correctamente, por lo que invertíamos mayor esfuerzo en arreglar lo que rompíamos o en hacer pruebas.

Lo cierto es que el desconocimiento no me hacía ver gravedad que podía llegar a tener. Con el paso del tiempo empezamos a involucrarnos más en proyectos de QA, lo que me llevó a aprender mucho y a ver el resultado de que en un aplicación no se implementará una buena estrategia de aseguramiento de la calidad en fases tempranas (el 95% de los proyectos que vi no disponían de ningún tipo de prueba unitaria y ni lo tenían en mente).

Y ahora que trabajo en una empresa como QA y que seguimos una metodología ágil veo los beneficios de disponer de unas buenas pruebas unitarias y el uso de la metodología TDD, lo que verdaderamente nos da una mayor garantía a la hora de sacar el producto al público.

Conclusiones

Más que una conclusión, lo que me gustaría trasladar es la importancia de implementar la calidad de la aplicación desde la fase inicial de su desarrollo e incluso conceptualización.

A medida que vayamos avanzando con esta serie de posts veremos como los cuadrantes nos aportan una visión de que pruebas podemos aplicar en cada fase para garantizar la calidad de nuestra aplicación.

Enlaces a la serie de posts

Lectura recomendada