Dimensiones entre pruebas aisladas e integradas. Tiempo de test.

INTRODUCCIÓN

Seguimos con la serie de “Dimensiones entre pruebas aisladas e integradas”!. En el post anterior hablábamos sobre el grado de confianza de las pruebas y cómo el tener un mayor área de impacto ayudaba a tener un mayor grado de confianza.

Para diseñar o definir nuestra estrategia de pruebas no nos podemos basar solo en el grado de confianza, es necesario tener en cuenta otras dimensiones. En este post hablaremos sobre el tiempo de test e iteración de cada tipo de pruebas, al igual que en el post anterior pondré el gráfico de dimensiones comparativo de cada tipo de pruebas.

TIEMPO DE TEST E ITERACIÓN DE LAS PRUEBAS

Antes de ver el gráfico de dimensiones, lo primero que tenemos que entender es cómo medimos el tiempo de test.

Tiempo de test

El tiempo de test es el tiempo que tarda la prueba desde que se lanza hasta que obtenemos los resultados, sencillo, ¿no?. Normalmente lo podemos medir por:

Test time = Build time + Deployment time + Test setup time + Execution time + Test clean time +  Report time.

Resumido en:

TT = BT + DT + ST + ET + CT + RT

No todos los tipos de prueba suman estos tiempos, por ejemplo las pruebas unitarias no tienen tiempo de despliegue, por lo que, DT = 0. 

Otro ejemplo son las pruebas funcionales aisladas, que al tiempo de test hay que añadir el tiempo que tardamos en levantar (EUT – Environment up time) y tumbar (EDT – Environment down time) el entorno aislado. Podríamos poner las siguientes formulas por tipo de prueba:

  • Unit test: TT = BT + ST + ET + CT + RT
  • Contract test: TT = BT + ST + ET + CT + RT.

    El ST ya contempla el tiempo que tarda en descargarse la nueva versión del contrato en caso de que haya.
  • Integrated integration test: TT = BT + ST + ET + CT + RT
  • Isolated integration test: TT = BT + EUT + ST + ET + CT + EDT + RT
  • Integrated functional test: TT = BT + DT + ST + ET + CT + RT
  • Isolated functional test: TT = BT + EUT + ST + ET + CT + EDT + RT

    En las pruebas aisladas lo normal es no desplegar la aplicación, si no levantarla como parte del entorno, por eso el tiempo de despliegue se incluye en EUT.
  • Support functional test: TT = BT + DT + ST + ET + CT + RT
  • Exploratory test: TT = BT + DT + ST + ET + CT + RT
  • Production functional test: TT = ST + ET + CT + RT

En sí estas fórmulas no nos dicen mucho, pero nos pueden servir para conocer donde se van los tiempos de nuestras pruebas. Algo curioso es que por el hecho de tener más variables en la fórmula no significa que el tipo de prueba sea más lento que otra que tenga menos variables.

Los tiempos de las pruebas aisladas contemplan EUT y EDT, que no están contempladas en las pruebas integradas, pero estas últimas son mucho más lentas. Esto es debido a que en las integradas en el tiempo de ejecución (ET) hay que contar que se pueden comunicar con una BD real y con otros colaboradores como servicios etc, llevándose la mayor parte del tiempo.

En la imagen vemos como las pruebas aisladas al conectarse en local contra un snapshot de BD y contra los stubs de los servicios, el tiempo de comunicación se reduce bastante.

La BD únicamente tendrá los datos necesarios de la prueba, y el stub del servicio simplemente nos devolverá la respuesta que esperamos, es decir, no tenemos que esperar a que se ejecute nada en los servicios externos.

Comparando el tiempo de test entre tipos de prueba

Ahora que ya entendemos en qué nos basamos para valorar el tiempo de test vamos a medirlo junto a otras dos dimensiones:

  • Tiempo de test, representado por círculos con más o menos radio, en base al tiempo total.
  • Ámbito (scope) de las pruebas, en el eje X. Se trata de comprobar una parte del código, una funcionalidad concreta o un E2E.
  • Iteraciones (iteration) de las pruebas, en el eje Y. Cada cuanto ejecutamos las pruebas, cada cambio, antes de cada commit, en el CI, en el entorno de testing, pre-producción o planificadas o disparadas por algún evento en concreto.

CONCLUSIONES

Lo más interesante de ver a este nivel, es lo unido que está el tiempo de test con el número de iteraciones. 

Para que el testing ayude a mejorar la productividad del equipo, la idea es tratar de obtener de forma rápida el estado de la aplicación tras un cambio. Por este motivo las técnicas más rápidas se intentan ejecutar en las iteraciones más tempranas del desarrollo.

En este punto es donde las técnicas de testing aisladas nos van a aportan un mayor valor, ya que nos van a permitir ejecutar en iteraciones tempranas y de forma rápida aquellas pruebas que se deberían ejecutar en etapas posteriores, con un mayor coste temporal y por lo tanto, productivo. 

Si nos basamos en una estrategia de testing preventiva, lo que nos va a interesar es ejecutar la mayor parte de las técnicas de prueba en etapas tempranas. Vamos a intentar ejecutar las pruebas por cada cambio que hagamos o antes de cada commit o merge, lo que nos va a hacer apostar por técnicas con un tiempo de test rápido y con un grado de confianza medio alto.

POSTS DE LA SERIE

1/3 Dimensiones entre pruebas aisladas e integradas. Grado de confianza.

2/3 Dimensiones entre pruebas aisladas e integradas. Tiempo de test.

3/3 Dimensiones entre pruebas aisladas e integradas. Test flakiness.

Intelligent testing, ¿Llega una nueva era?

Introducción

A través de un tweet de Lisa Crispin, llegue a un artículo del blog de Mabl, en el que hablaban un poco sobre el concepto de “intelligent testing”.


En este artículo me gustaría repasar los cuatro principios que se tratan del Intelligent testing. Si bien es cierto que el video del blog habla sobre cómo lo aplican a través de Mabl, intentaré ser agnóstico al producto.

¿Qué intenta resolver “Intelligent testing”?

Para entender el concepto de intelligent testing, creo que es necesario conocer los “defectos” del testing convencional (vamos a llamarlo así).

En mi opinión el testing convencional estaba pensado y muy acoplado a las metodologías de desarrollo convencionales. Con la entrada de las metodologías ágiles, el testing ha sufrido ciertos cambios intentando adaptarse, pero no siempre con el éxito que debería.

Esto ha provocado que el testing llegue a ser el cuello de botella del sistema de CI/CD. Para evitarlo y poder implementar el testing dentro de las metodologías ágiles, en muchas ocasiones se ha tenido que crear estrategias de testing muy acopladas al sistema de CI/CD, lo que tampoco es del todo correcto.

Creo que la evolución del testing siempre ha estado por detrás del desarrollo, cuando debería ir de la mano. También creo que gran parte de la culpa la tenemos los testers y QA/QEs que nos hemos ido adaptando al código y a la tecnología, en vez de estar a la altura. Debemos ser más preventivos y menos reactivos. Todavía nos queda mucho por aprender.

Lo que intenta el “testing inteligente” es básicamente eso, dejar que el testing sea el cuello de botella de nuestro desarrollo, y para eso se basa en cuatro principios.

1.º principio: Adaptarse a los cambios

Uno de los grandes problemas de la automatización, son los falsos positivos. Cuando lanzamos la suite de pruebas podemos encontrarnos con una gran número de fallos que tendremos que analizar, ya que seguramente un porcentaje de los fallos sea debido a falsos positivos.

Algunos falsos positivos vienen dados por cambios en el código que hacen que nuestro test falle, sin que en realidad sea un fallo de la aplicación. Esto suele ocurrir mucho en el caso de las pruebas de UI.

En las pruebas UI, nuestro test está acoplado a los componentes con los que interactúa, lo que hace que el test sea altamente sensible. Cuando por alguna razón el xpath o el selector del componente cambia, nuestro test falla. No quiere decir que sea error de la aplicación, es un caso de falso positivo.

Tenemos que adaptar manualmente el test y volverlo a lanzar. Esto supone una inversión de tiempo alto, por lo que somos un cuello de botella.

Lo ideal sería que el framework de testing sea lo suficientemente inteligente como para identificar el problema (un cambio del selector, en el caso anterior), identificar el cambio, probarlo y hacer los cambios en el test, de las forma que las siguientes ejecuciones vayan correctamente.

Claro, esto es relativamente “fácil” en las pruebas de UI. Pero qué ocurre si realizamos otro tipo de pruebas funcionales o de performance (porque recordemos que podemos integrar las pruebas de performance dentro de nuestro CI).

En estos casos no lo veo tan claro que sea tan fácil de adaptar el test. Supongamos que realizamos pruebas funcionales de API, lanzamos las pruebas y fallan debido a un cambio de contrato. Entiendo que si tenemos los contratos definidos y actualizados o hacemos uso de contract testing, podremos adaptar nuestros tests basados en esas fuentes de conocimiento.  

En el caso de las pruebas de rendimiento, debería depender de qué tipo de pruebas o sobre que se lancen (UI, API etc.), y adaptarse.

Otra opción que se me ocurre sería disponer de un sistema inteligente que “analice” los cambios y notifique o haga los cambios pertinentes en las suites de testing, sea del tipo que sea, funcionales, performance…

2.º principio: Testing desde el Cloud

 

Otra forma de reducir el tiempo de ejecución de las pruebas es la ejecución en paralelo. Las plataformas Cloud nos facilitan este hecho, ya que podremos disponer bajo demanda o escalar el número de ejecuciones y entornos sobre los que queremos lanzar las pruebas.

En el caso de las pruebas funcionales podremos reducir considerablemente el tiempo de ejecución, debido a que dividiremos las pruebas por el número de “ejecutores”.

En el caso de las pruebas de rendimiento podremos aumentar la carga o el número de usuarios virtuales sin penalizar el gestor de carga.Al lanzarlo sobre sistemas cloud podremos beneficiarnos de los servicios de estas plataformas, como sistemas de análisis (para analizar los resultados), heurísticos etc..

Cloud testing

 

3.º principio: El output debería ser más afirmativo y resolutivo

Como he comentado en el primer principio, tras terminar las pruebas, hay una fase de análisis de resultados. En muchas ocasiones (por no decir en la gran mayoría), cuando hay fallos, los resultados no son del todo claros y nos toca invertir tiempo en ver cual es el problema.

Esta inversión de tiempo, una vez más, nos lleva a ser un cuello de botella para los resultados, y en otras ocasiones a que se nos escapen bugs, debido a la falta de atención que ponemos en su resolución.

El que las pruebas den un output con la información necesaria (ni exceso, ni defecto) y esa información llegue a ser resolutiva, es tan importante como unos buenos teses. De nada sirve tener un test perfecto, si los resultados no son lo suficientemente informativos.

Hoy en día sacamos trazas (en ocasiones excesivas) y screenshots (en ocasiones confusos), pero no es suficiente para reducir el tiempo de análisis de los resultados.

Bajo mi punto de vista, tenemos que invertir muchos más esfuerzos en mejorar este punto. La parte buena es que los sistemas heurísticos y de machine learning cada vez están más avanzados, y creo que de alguna forma podremos integrarlo con el testing.

Creo que sería interesante disponer de un output inteligente, donde en base a los resultados obtenidos, comparándolo con una fuente de conocimientos de otros resultados anteriores y los cambios realizados, podamos dar unos resultados, no solo con buena información, si no, con el problema detectado y parte de su resolución.

4.º principio: Testing integrado en el CI

Este último principio creo que es el que está más integrado. Actualmente hay pocas empresas que no tengan el testing integrado en el sistema de CI/CD. Ya son muchos sistema de CI que disponen de plugins para muchos frameworks de testing.

El problema es que si no se cumplen los otros tres principios, el testing seguirá siendo el palo en la rueda del CI.

Conclusiones

El testing inteligente es un muy buen concepto que acerca cada vez más la posibilidad de estar a la altura de la evolución del desarrollo, creo que todavía queda por evolucionar varios aspectos, pero es factible, lo que es muy buena noticia.

Parte de esa responsabilidad recae en los testers y QA/QEs que creo que necesitamos una evolución como concepto y rol. No podemos seguir anclados en el probar el software, ni en la idea idílica de “garantizar la calidad”.

La tecnología de hoy en día, el cloud, la heurística, nos permite dar un paso más adelante y ayudarnos a anteponerse a los errores, más que encontrarlos.

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

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