archivo

Archivo de la etiqueta: testing exploratorio

En su día escribí un artículo sobre esta práctica de testing. Hace poco leí una cita de Bob Martin que resume perfectamente los objetivos que se persiguen con el testing exploratorio (traducción libre): “El testing exploratorio es un esfuerzo creativo en el que los testers exploran el comportamiento del sistema en un intento de caracterizar sus comportamientos; tanto documentados como no documentados”.

El testing unitario (y en extensión otras prácticas de testing automatizadas) no es suficiente como tampoco lo es el que se basa en planes de pruebas porque ambos dejan o pueden dejar espacios del sistema sin cubrir y que pueden ser importantes.

Sistemas altamente acoplados, con clases y métodos kilométricos, con código que resulta complicado de entender son ejemplos en donde realmente se programa con miedo una vez que se comprueba que tocarlo supone implicaciones hasta en las partes más insospechadas de la aplicación.

Si el sistema además es crítico el miedo pasa a convertirse en pánico.

Tal vez las palabras miedo o pánico sean demasiado exageradas (y no es nada positivo trabajar de esa manera) pero por lo menos el programador debe sentir respeto y estar alerta cuando realiza modificaciones en un sistema de este tipo. El exceso de confianza no es bueno y más en un caso como este.

Hay que evaluar si el cambio que se va a hacer en el sistema es algo puntual o si se sabe que van a existir una serie de cambios a corto y medio plazo, así como la magnitud de los mismos y la magnitud del sistema. El esfuerzo que supone realizar estos cambios (mucho mayor que en un sistema con una deuda técnica ajustada a sus características), el esfuerzo en testing y el riesgo que tiene liberar nuevas versiones de estos sistemas debe ser analizado antes de afrontar la mejor estrategia para el cambio.

En condiciones como esta, cambios que sean fruto de un capricho no deben ser contemplados y cambios muy relevantes que supongan una modificación sustancial del sistema podrían dar lugar a que se tome la decisión de desarrollar una nueva aplicación.

El programador por su parte puede tomar sus precauciones: testing unitario, automatización de determinado testing de mayor nivel, etc…

Por otro lado, el paso a producción de nuevas versiones de sistemas de estas características no debe tratarse a la ligera y esperar cruzando los dedos a que no pase nada.

El testing debe ser realizado en profundidad y desde el punto de vista funcional debería ser la combinación de casos de prueba y testing exploratorio.

¿Qué es la certificación de aplicaciones?, ¿asegurarte de que la versión entregada no tiene defectos y hace lo que el usuario espera?, ¿debe tener también en cuenta aspectos técnicos relacionados con la mantenibilidad del sistema?.

Es posible que sea la suma de esos y más factores, pero, ¿quién posee el conocimiento suficiente para certificar?, ¿el equipo de proyecto?, ¿los usuarios?, ¿ambos?. En cualquier caso deben ser personas que han participado en el proyecto y que saben todo lo que ha pasado en él, porque es la única forma de conocer cuáles son las expectativas reales de los usuarios y de conocer por qué y dónde está la diferencia entre una solución teórica perfecta y la que se ha logrado conseguir.

Puedo entender que equipos externos den soporte a ciertos aspectos como el testing del sistema, no solo en la ejecución sino también en el asesoramiento de los mismos, también que garanticen que lo que se entrega es lo que efectivamente se encuentra en nuestro sistema de gestión de versiones y en nuestro repositorio de artefactos, pero no puedo entender, porque no es algo real, que se pueda certificar un producto basado en un plan de pruebas que ha realizado quién lo ha construido y que todos sabemos que presenta imperfecciones porque desgraciamente no se le suele prestar mucho cariño a invertir tiempo en eso, por mucho testing exploratorio adicional que se haga.

Por todo esto, considero que es necesario ser muy prudente cuando se dice que este o tal equipo van a certificar los desarrollos que se realizan para una organización porque probablemente de lugar a expectativas que se encuentren lejos de convertirse en realidad.

Hay que ir más allá de los casos de prueba o de las fuentes que se tengan para poder realizar este tipo de testing: casos de uso, requisitos, historias de usuario, etc… porque resulta muy complicado que la documentación disponible cubra todas las casuísticas que se han desarrollado (aún cubriéndolas, que hayan descendido al nivel de detalle necesario en todos los casos) y porque una cosa son las especificaciones y otra los componentes software que se han desarrollado y su engranaje.

Lo ideal es la combinación de ambos tipos de testing (basado en casos de prueba y exploratorio) porque el testing exploratorio salvo que se tenga colaboración del equipo de proyecto o lo recursos del proyecto permitan conocer bien el negocio, no podrá corroborar de manera adecuada el funcionamiento del sistema.

El testing exploratorio básicamente consiste en realizar el testing con los recursos disponibles y en donde la habilidad, conocimientos y experiencia del tester o del equipo de testing resultan fundamentales para hacer un trabajo de calidad. Desde este punto de vista también cabría dentro de este testing la aplicación de los casos de prueba basado en documentación existente en el proyecto: “esta es la documentación que hay, tu te lo guisas y tu te lo comes”, si bien me gusta hacer una diferenciación entre un caso y otro ya que en uno hay una intención de hacer una documentación que pueda ser de utilidad para las pruebas (aunque no sea ese su propósito principal) y en el caso del testing exploratorio se basaría más en ir recopilando piezas (documentales, prototipos, consultas al equipo de desarrollo, etc…) y en el trabajo en profundidad con el producto.

Como en todo, lo importante es dedicar al testing el tiempo que necesite la aplicación en función de su criticidad, complejidad, etc… y en función de cómo se ha desarrollado el proyecto. Lo difícil es precisar con exactitud cuánto es suficiente (y que exista disponibilidad real de tiempo y recursos para poder realizar esta actividad).

El problema es el de siempre, todo se deja para el final y el equipo de desarrollo no dedica tiempo suficiente al testing y además es más que posible que la calidad del código y de la arquitectura sea tal que la probabilidad de que existan errores de integración o por efectos colaterales es importante.

¿Qué quiero decir con todo esto? Pues que el tiempo es limitado y las condiciones para realizar el testing no serán en muchos casos las mejores (lo cual no quite que intentemos aproximarnos lo máximo posible a ese “tiempo que necesite” que comenté en el primer párrafo).

Esto nos lleva a que hay que priorizar. Si existen casos de prueba diseñados a medida o diseñables a partir de la documentación existente en el proyecto o de la combinación de la misma y conversaciones con los analistas, programadores, usuarios, etc… es necesario ejecutarlos, recordemos que donde más puede flaquear el equipo de testing si no ha participado en el proceso de definición y desarrollo del sistema es en la comprensión de la lógica del negocio.

Y después nos queda el testing exploratorio para intentar cubrir los huecos (muchas veces numerosos) que dejarán tras de sí los casos de prueba. ¿Hacia dónde lo enfocamos?, ¿donde invertir el esfuerzo? Yo lo respondo con otras preguntas: ¿qué partes del sistema son las críticas?, ¿qué aspectos no están cubiertos con casos de prueba?, ¿qué partes del sistema están integradas con otros (ya sea para recibir y/o enviar información)?, ¿qué aspectos no están cubiertos con casos de prueba?, ¿existe una matriz de compatibilidad con navegadores de la aplicación?, ¿se han dedicado pruebas a ello?.

Hacer un buen testing exploratorio no es sencillo, se requieren testers con experiencia y conocimientos para que a través de ello y de la información que dispongan y consigan saber dónde enfocar los esfuerzos. Ahora bien, no esperes un trabajo excelente si no se les proporciona ayuda y/o información y además el tiempo es muy limitado.

Si un sistema tiene una deuda técnica alta y en particular presenta un alto acoplamiento entre clases, la realización de testing exploratorio resulta crucial ya que en este caso, los efectos colaterales pueden aparecer hasta en el sitio más insospechado de la aplicación, en este caso hay que sacar el tiempo que sea necesario a realizar las pruebas oportunas ya que no podemos dejar que el comportamiento de la nueva versión del sistema en el entorno de producción sea como jugar a la ruleta rusa. En producción que, por favor, las sorpresas sean las mínimas posibles.

La siguiente reflexión de Brian Marick no deja indiferente: “Los documentos del proyecto son una ficción interesante: útiles, pero nunca suficientes”.

Este es un tema controvertido en el que como es lógico existirán opiniones para todos los gustos y probablemente casi todas tengan su parte de razón.

Siempre hay detalles que no recoge la documentación (el proyecto es algo vivo y está sujeto a cambios y a nuevos matices) y hacer que recoja todos los detalles puede requerir un esfuerzo importante tanto para el documento en sí como en futuras actualizaciones del mismo (tal vez y ya es mucho decir, se consiga cerrar una documentación completa y de calidad de una versión del producto, mantener esto resultará complicado y de la misma manera que el software, la documentación “se deteriorará” con el tiempo).

Soy de la opinión (estoy convencido) de que el programador no debe inventar nada cuando está desarrollando pero eso es una cosa y otra que los detalles que no aparecen en la documentación deban aparecer reflejados finalmente en la misma ya sea de manera formal o informal (habrá situaciones donde resulte interesante (o rentable) y en otras no).

El testing exploratorio se centra en el producto y, por tanto, va más allá de la documentación del proyecto y el uso que se hace de la misma es el de un instrumento para comprender mejor la aplicación y para obtener información que pueda ser de utilidad para el testing. Consultas al equipo de desarrollo, al área usuaria y la revisión de la propia aplicación e incluso del código proporcionarán un mayor nivel de conocimiento.

No rechazo la documentación, no quiero que se entienda así, rechazo el exceso de formalidad y el exceso de documentación. Es un instrumento, no lo olvidemos, cuando se convierte en un fin, creyendo que a través de ese fin se consiguen los objetivos, tenemos un problema.

Es un concepto sobre el que hay muchísima bibliografía y en cierto modo es algo curioso, ya que el negative testing es el proceso de buscar incidencias en el artefacto que se verifica o se valida, es decir, la diferencia con el testing ordinario es que este encuentra los errores mediante la comprobación de si un artefacto cumple las expectativas, si tomamos por ejemplo en el propio producto software, el testing ordinario se centraría en validar si se cumplen o no los requisitos funcionales y no funcionales y las incidencias se encontrarían mediante ese proceso.

El negative testing busca errores y no se centra (por lo menos no es su objetivo principal) en comprobar si el producto funciona.

¿Dónde podemos aplicar negative testing? En muchas áreas, por ejemplo, cuando se detecta una incidencia en una funcionalidad o módulo del sistema que sospechamos que se puede extender a otros, cuando hacemos testing exploratorio, etc…