archivo

Archivo de la etiqueta: casos de prueba

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.

Los casos de prueba que permitirían demostrar que funcionalmente un sistema tiene un comportamiento adecuado (otros tipo de casos de prueba son aquellos relacionados con pruebas no funcionales y que deberían verificar el adecuado comportamiento del sistema en situaciones de stress, desde el punto de vista de la seguridad, etc…) dependen de la complejidad y tamaño del sistema.

Es muy costoso plantear un juego de pruebas que reduzca a cero (o mejor dicho que haga que tienda a cero) la probabilidad de error, solo hay que ver la cantidad de casuísticas que se pueden presentar en la utilización de un sistema y darnos cuenta de que cualquiera de ellas podría dar lugar a error si hay algún aspecto en el proceso de programación que se nos ha escapado.

Como no suele haber una práctica del testing en los equipos de desarrollo, ni se suele tener una formación específica, la selección de los casos de prueba en muchas ocasiones no es óptima en el sentido de que el número de errores de tipo funcional que pueden detectar los mismos no es proporcional al esfuerzo que se ha necesitado para diseñar dichos casos de prueba y al que se requiere para ejecutarlos.

Teniendo en cuenta que lo ideal es que cada tipo de sistema tenga su propio itinerario de testing, resulta fundamental que el caso de pruebas elegido esté a la altura de los umbrales definidos en ese itinerario con el menor coste posible.

Teniendo en cuenta que alcanzar ese equilibrio es complicado, por lo menos hay que tender a él e intentar que los casos de prueba elegidos cubran la posibilidad de encontrar el mayor número de errores posible, ya que los errores permanecerán ocultos hasta que se ejecute la porción de código que los provoca y para que dicha porción se ejecute es necesario que el usuario (o el mecanismo automático de testing utilizado) realice las acciones necesarias para provocarlo.

En el entorno de personas con las que trabajo existen serias dudas de que la metodología de desarrollo guiado por las pruebas o Test-Driven Development, sea ágil, en el sentido de que entienden que si se aplica de manera ortodoxa o si bien las pruebas unitarias se desarrollan después, se pierde capacidad de trabajo efectivo por parte del equipo de proyecto.

Nunca he participado en un proyecto que siga esta metodología y en los desarrollos en los que he trabajado la importancia que se le da a las pruebas unitarias es muy escasa, por lo que no puedo aportar mi experiencia para opinar sobre las bondades o no de esta metodología, de manera que me tendré que centrar en lo que he leído sobre ella.

No obstante, hay que tener en cuenta una cosa. Agilidad no es lo mismo que desarrollar más rápido o por lo menos no es su objetivo principal, ya que si bien es cierto que la aplicación de metodologías ágiles, eliminan muchos aspectos que son prescindibles en un proyecto de desarrollo de software y por lo tanto pueden optimizar tiempos de desarrollo, el objetivo último de las mismas es conseguir productos software de calidad, que proporcionen satisfacción al cliente, dentro de unos plazos y presupuestos definidos (siempre y cuando, ambos sean realistas y acordes a la naturaleza del proyecto y al nivel de calidad que se espera del producto software), es decir, que no se produzcan los factores que derivan en la crisis del software.

El desarrollo guiado por las pruebas, fue introducido (o reintroducido) por Kent Beck, creador de la metodología de programación extrema y en cierto modo la segunda es una consecuencia natural de la primera, si bien ambas pueden utilizarse sin problemas por separado.

La metodología TDD a grandes rasgos es fácil de exponer:

– Se construyen las pruebas unitarias (o se puede extender si se desea el concepto a otros tipos de pruebas de más alto nivel, siempre y cuando sea automatizable su ejecución).

Como estos casos de prueba están construidos antes desarrollarse el componente software sobre el que se va a trabajar, van a fallar a la primera. De hecho se considera necesario verificar que fallan porque si no es así, querría decir que el test está más construido (¿por qué no?) o que el componente software ya está desarrollado (en proyectos donde se trabaja con sistemas de mediana o gran envergadura y con un número de desarrolladores alto, puede pasar que el componente o módulo ya se haya implementado previamente, bien porque le ha hecho falta a un compañero para otra funcionalidad o bien porque no se ha verificado que efectivamente ese componente ya estaba desarrollado).

Para la construcción de los casos de prueba, los desarrolladores deben basarse en las especificaciones indicadas en los casos de uso o en las historias de usuario. Ahí radica la importancia que tiene la construcción de las pruebas unitarias antes del desarrollo del componente, ya que implica un mayor enfoque en los requisitos, una mayor necesidad de comprender la funcionalidad y comportamiento deseado, es decir, implica comprender el problema, conocer los resultados esperados, antes de empezar a desarrollarlo.

La ventaja de desarrollar las pruebas antes de implementar los componentes es la indicada en el párrafo anterior, es decir, enfrentarse y comprender el problema antes de empezar a resolverlo.

Si las pruebas unitarias se construyen después, no estaríamos hablando de TDD, eso es importante, por lo que lo repito, si las pruebas unitarias se construyen después se trata de otra estrategia de desarrollo de software, no de desarrollo guiado por las pruebas.

Pese a que como he comentado, no se ha fomentado en los proyectos en los que he participado la construcción de pruebas unitarias, soy de la opinión de que es favorable tener una buena cobertura de código, por lo que la existencia de pruebas unitarias, antes o después de implementar los componentes, permite detectar de manera rápida la existencia de efectos colaterales o desarrollos erróneos de métodos o clases.

¿Por qué no lo hemos fomentado? Es una suma de varios factores, por un lado pese a que entendemos los beneficios que puede proporcionar, no tenemos del todo claro su retorno de la inversión, pese a que es objetivo que la deuda técnica se reduce en proporción a la cobertura, por otro lado, los proveedores con los que hemos trabajado tampoco utilizan esta práctica en sus desarrollos. Por tanto y en resumen, la falta de experiencia nuestra y de los proveedores hace que nos más dar el paso y prioricemos otros aspectos en el proceso de desarrollo y en la calidad del diseño y de la codificación.

– A continuación se construye el componente software que debe verificar las reglas de funcionamiento definidas en las pruebas.

Una vez desarrollado, se pasa el test y si funciona adecuadamente, se pasa de nuevo todo el juego de pruebas, si hay errores, se vuelve a revisar el componente, si todo ha ido bien, se pasa a la siguiente fase.

– Una vez que se tiene un software que verifica las pruebas implementadas, se procede a su refactorización.

El objetivo de la utilización de esta técnica es evidente, desarrollar software con el menor número de fallos posible, reduciendo además los errores debidos a efectos colaterales en el desarrollo, respetando también la calidad de diseño y de codificación para favorecer la comprensión y capacidad de mantenimiento del software.

Se sabe que cuanto más tarde se detecten los errores más esfuerzo se requiere para solucionarlo, esta técnica pretende disminuir el riesgo por la presencia de errores de ese tipo, además de facilitar un código donde sea mucho más fácil trabajar, tanto para corregir esas incidencias como para contruir nuevas funcionalidades o modificar, si fuera necesario (el software es de naturaleza adaptativa), las ya implementadas.

Espero poder probar más pronto que tarde esta metodología en alguno de los proyectos en los que participo y poder verificar personalmente las ventajas que tiene la utilización de esta estrategia de desarrollo.

El concepto de testing de caja gris es simple, se basa en la realización de testing de caja negra basado en casos de prueba realizados por personas que conocen el programa por dentro. Se entiende que de esta forma las pruebas realizadas son más efectivas porque se conocen las partes del código que pueden resultar más conflictivas: por su complejidad, por su acoplamiento con otras clases, etc…

Por regla general cuando nos encontramos que el equipo de desarrollo diseña casos de prueba se centra en aspectos funcionales sin tener en cuenta cómo se ha desarrollado la aplicación, algo que resulta curioso ya que se tiene conocimiento suficiente para poder diseñar este tipo de pruebas. ¿Por qué sucede esto? Pues porque no se le da la importancia que se merece al testing y luego pasa lo que pasa y se entregan los productos en el estado en que se entregan.

Parece que todo lo ajeno a la construcción es accesorio, prescindible o incluso una pérdida de tiempo. Yo no entiendo el desarrollo de software sin la realización de un testing acorde a las características del proyecto, como tampoco lo entiendo sin una documentación en función de lo que se necesite.

Ver también: Testing de caja blanca.