Ilustrados comunidad mundial educativa
Inicio | Escribenos
User: Pass: Recordar ó (Registrate!)

| !Publicar Articulo¡

Estudio de frameworks para el desarrollo de pruebas de software. Pruebas de unidad

Resumen: La producción de software en nuestro país es una ciencia joven la cual se ha impulsado rápidamente gracias al desarrollo de las ciencias informáticas en las universidades de nuestro país y a entidades surgidas debido...
3,878 visitas
Rating: 0
Tell a Friend
Autor: Irina Elena Argota Vega y Alain Bedoya Reyes

RESUMEN
La producción de software en nuestro país es una ciencia joven la cual se ha impulsado rápidamente gracias al desarrollo de las ciencias informáticas en las universidades de nuestro país y a entidades surgidas debido al Ministerio de la Informática y de las Comunicaciones (MIC) con “el objetivo preciso de impulsar, facilitar y ordenar el uso masivo de servicios y productos de las Tecnologías de la Información, las Comunicaciones, la Electrónica y la Automatización para satisfacer las expectativas de todas las esferas de la sociedad”.

Este desarrollo en la producción de software se ha estimulado con la fundación de la Universidad de las Ciencias Informáticas (UCI), con lo cual se espera un progreso acelerado de las Tecnologías de la Información y las Comunicaciones (TIC).

El aseguramiento de la calidad se ha convertido en una necesidad de prioridad para las organizaciones que desarrollan software porque en la medida que avanza la tecnología, es más exigente la calidad del software requerida actualmente por las empresas encargadas de medir la calidad, y para satisfacer estos requerimientos de calidad uno de los métodos más utilizados por los desarrolladores es el proceso de desarrollo de Pruebas de Software.

Hoy en día, se podría decir que las pruebas de software han llegado a ser más fáciles y más difíciles al mismo tiempo. Las pruebas de software son más difíciles por la gran cantidad de lenguajes de programación, sistemas operativos y las plataformas de hardware en las que se encuentran envueltas. Las pruebas de software son más fáciles, en algunos casos, por que los sistemas operativos y software, son mucho más sofisticados y proveen intrínsicamente buenas rutinas de pruebas, que pueden ser incorporadas en las aplicaciones, sin la necesidad que el programador las desarrolle desde cero.(MYERS 2004)

Entre las Pruebas de Software que se le pueden realizar a un sistema determinado están las Pruebas de Unidad. Sobre los frameworks que se pueden utilizar para el desarrollo de las mismas, dentro del mundo del software libre, se centrará la presente investigación.

Palabras claves: Pruebas de Software, Framework, Pruebas de unidad, calidad de software.

INTRODUCCIÓN
Actualmente la prueba de software se utiliza en todos los desarrollos de la industria, siendo inconcebible que un cliente reciba un sistema software que no haya sido probado. Pese a su enorme impacto en el coste de desarrollo, es una de las líneas de trabajo que muchos programadores aún consideran clasificable como un arte y, por tanto, como difícil de conceptualizar.

En el mundo existen múltiples metodologías para el desarrollo de software, pero sin duda alguna todas tienen implícito el proceso de desarrollo de pruebas, el cual está centrado en el objetivo de encontrar defectos a un software; puede ser por razones de depuración o de aceptación del mismo.
El objetivo general que se desea alcanzar para darle cumplimiento al presente trabajo es: realizar un estudio de frameworks para el desarrollo de pruebas de software.

De ahí que para el cumplimiento de este objetivo general se deriven los siguientes objetivos específicos:
· Definición de conceptos involucrados con el tema de Pruebas de Software.
· Investigar sobre los pasos para la realización de pruebas de unidad.
· Investigar sobre los frameworks existentes que utilicen el lenguaje de programación C++.
· Llegar a conclusiones del framwork escogido a partir de la experiencia adquirida.

1. Conceptos generales.

1.1 Prueba de Software
La Prueba o Testeo de Software, es un procedimiento llevado a cabo para identificar posibles fallos de implementación, calidad, o usabilidad de un programa. Básicamente es una fase en el desarrollo de software cuyo objetivo es probar las funcionalidades de la aplicación construida.
La prueba de software es un proceso que corre en paralelo al proceso de desarrollo de software, y que se realiza por el convencimiento de que todo sistema debe ser inspeccionado o probado con el objetivo de establecer si el nivel de calidad requerido es alcanzado.

Es un elemento que a menudo se refiere como verificación y validación. En (PRESSMAN 2005) se plantea que “la verificación se refiere al conjunto de actividades que aseguran que el software implementa correctamente una función específica. La validación se refiere a un conjunto diferente de
actividades que aseguran que el software construido se ajusta a los requisitos del cliente”.

1.2 Pruebas de Unidad
Es el proceso de verificación en la menor unidad del diseño del software: el módulo, normalmente realizada por el propio personal de desarrollo en su entorno. Usando la descripción del diseño del procedimiento como guía, se prueban los caminos de control importantes, con el fin de descubrir errores dentro del límite del módulo.

Antes de iniciar cualquier otra prueba es preciso probar el flujo de datos de la interfaz del módulo. Si los datos no fluyen correctamente, todas las demás pruebas no tienen sentido. (PRESSMAN 2005)

Lista de comprobaciones para la prueba de Interfaces.
1. ¿Es igual el número de parámetros de entrada al número de argumentos?
2. ¿Coinciden los atributos de los parámetros y los argumentos?
3. ¿Coinciden los sistemas de unidades de los parámetros y de los argumentos?
4. ¿Son iguales los números de los argumentos transmitidos a los módulos de llamada que el número de parámetros?
5. ¿Son iguales los atributos de los argumentos transmitidos a los
módulos de llamada y los atributos de los parámetros?
6. ¿Son iguales los sistemas de unidades de los argumentos transmitidos a los módulos de llamada y de los parámetros?
7. ¿Son correctos el número de los atributos y el orden de los argumentos de las funciones incorporadas?
8. ¿Existen referencias a parámetros que no estén asociados con el punto de entrada actual?
9. ¿Entran sólo argumentos alterados?
10. ¿Son consistentes las definiciones de variables globales entre los módulos?
11. ¿Se pasan las restricciones como argumentos?
La pruebas del camino básico y de bucles son técnicas muy efectivas para descubrir una gran cantidad de errores en los caminos.
Este nivel de prueba se deben descubrir errores tales como:
l Comparaciones entre tipos de datos distintos.
l Operadores lógicos o procedencia incorrecta.
l Igualdad esperada cuando los errores de precisión la hacen poco probable.
l Las variables o comparaciones incorrectas.
l Terminaciones de bucles inapropiadas o inexistentes.
l Fallo de salida cuando se encuentra una iteración divergente.
l Bucles que manejan variables modificadas de forma inapropiada.

1.2.1 Procedimiento para la Prueba de Unidad. (PRESSMAN 2005)
Debido a que un módulo no es un programa independiente, se debe desarrollar, para cada prueba de unidad, un software que controle y/o resguarde. En la mayoría de las aplicaciones, un controlador no es más que un programa principal que acepta los datos de la prueba, pasa estos datos al módulo (a ser probado) e imprime los resultados importantes. Los resguardados sirven para remplazar módulos que estás subordinados (llamados por) el componente que hay que probar. Un resguardo o un subprograma simulado usa la interfaz del módulo subordinado, lleva a cabo una mínima manipulación de datos, imprime una verificación de entrada y devuelve control al módulo de prueba que lo invocó.

Los controladores y los resguardos son una sobrecarga de trabajo. Es decir, ambos son software que debe desarrollarse (normalmente no se aplica un diseño formal) pero que no se entrega con el producto de software final. Si los controladores y resguardos son sencillos, el trabajo adicional es relativamente pequeño. Desgraciadamente, muchos componentes no pueden tener una adecuada prueba unitaria con un sencillo software adicional. En tales casos, la prueba completa se pospone hasta que se llegue al paso de prueba de integración (donde también se usan controladores o esguardos).
La prueba de unidad se simplifica cuando se diseña un módulo con un alto grado de cohesión. Cuando un módulo sólo realiza una función, se reduce el número de casos de prueba y los errores se pueden predecir y descubrir más fácilmente.

Ventajas de la utilización de este tipo de prueba.
Las ventajas de usar este tipo de pruebas son muchas, entre ellas se pueden plantear:
l Los errores serán más fáciles de localizar.
l Los errores estarán más acotados, ya que se sabrá qué módulos no están pasando las pruebas unitarias.
l Se reducen los errores ocurridos como consecuencia de la eliminación de otros errores, ya que aplicando las pruebas unitarias se pueden ejecutar nuevamente las pruebas y comprobar que el módulo funciona de la forma esperada.
l Con pruebas unitarias, la mayoría de los errores de programación se detectan durante la propia etapa de programación, lo que tiene gran valor, ya que mientras más tiempo permanezca un error en el sistema, más tiempo requerirá eliminarlo y más repercusiones acarreará en otras secciones del programa.
l Las pruebas funcionales se hacen más sencillas, ya que solo se comprobarán la correcta relación entre las distintas unidades.
l El programador escribe código de una forma más lógica, pues lo diseña mucho más simple y accesible para poder realizarle las pruebas.
1.2.2 Guía de pasos para la realización de las Pruebas de Unidad.
1) Debe comenzar inmediatamente se vayan construyendo los módulos y serán desarrolladas por las mismas personas que desarrollaron roles de programadores.
2) Deben ser aplicadas a todo el código.
3) Se recomienda utilizar alguna herramienta de prueba para la automatización de las mismas.
4) Deben aplicarse métodos de caja negra para probar la funcionalidad de los módulos (clases, procedimientos, funciones, métodos, objetos, o componentes).
5) Identificar las clases de equivalencia (de datos válidos y de datos no válidos o erróneos).
6) Identificar casos de prueba a partir de clases de equivalencia.
7) Explorar las condiciones límites de un programa mediante la técnica de análisis de valores límites.
8) Utilizar la técnica de conjetura de errores para determinar los errores que más se repiten y en función de esta elaborar los casos de prueba.
9) Ejecutar los casos generados hasta el momento y analizar la cobertura obtenida para determinar el cumplimiento de los objetivos de prueba trazados.
10) Los módulos que no estén pasando las pruebas deben ser informados al equipo de desarrollo y una vez depurados estos errores deben ejecutarse nuevamente los casos de prueba para verificar que la reparación no ha causado otros errores.
11) Delimitar los errores y sus posibles causas, de este modo el probador podrá asegurarse de que no se repite el error en otras secciones del programa y podrá asegurarse también de que los cambios no introducen un comportamiento no deseado o errores adicionales.
12) Según los principios de las pruebas enunciados por Myers, se recomienda que si se detectan muchos fallos en un módulo, lo mejor sería desecharlo, diseñarlo y codificarlo nuevamente.
13) Los resultados obtenidos con la ejecución de las pruebas deben ser documentados debidamente en el registro de defectos.


2. Comparación de Frameworks para la realización de las Pruebas de Unidad.
Un framework es una estructura de soporte auxiliar en la cual un proyecto de software puede ser organizado y desarrollado. Típicamente, un framework puede incluir soporte de programas, bibliotecas y un lenguaje script entre otros softwares para ayudar a desarrollar y unir los diferentes componentes de un proyecto.
Para la realización de pruebas de unidad, se investigaron frameworks que utilizaran C++ como lenguaje para la programación.
2. Comparación de Frameworks para la realización de las Pruebas de Unidad.
2.1 Criterios para la comparación de los frameworks
1. Mínima cantidad de código a la hora de agregar nuevas pruebas. Si se necesitan hacer muchas pruebas, mientras menos se tenga que teclear para agregar una nueva mejor será, pues así se evita muchas líneas de código y la duplicación de estas. El framework en el cual menos se tenga que implementar más eficiente será a la hora realizar las pruebas en el tiempo establecido.
2. Facilidad para modificarse y ser portable. No debe tener ninguna dependencia con las bibliotecas no estándar, y si es posible no debe basarse en características exóticas de C++.
3. Accesorios de ayuda. Es mas fácil usar solamente una aserción por prueba, las hace más fácil de entender y mantener, pero requiere el uso pesado de accesorios. Un framework sin ellos se elimina inmediatamente.

4. Manejadores de excepciones y de recuperación. No es bueno que paren las pruebas por cierto código que fue ejecutado, porque hubo un acceso a cierta posición de memoria inválida o por una división por cero. El framework de prueba debe reportar las excepciones y tanta información sobre ellas como sea posible. Debe también ser posible correrlo otra vez y tener la ruptura de depuración en el lugar en donde la excepción fue accionada.
5. Buena funcionalidad del ASSERT. De fallar una declaración, el ASSERT debe imprimir el contenido de las variables que fueron comparadas. Debe también proporcionar un buen sistema de ASSERT, el cual proporcione casi todas las posibles comparaciones y los diferentes tipos de datos, así como comprobar si las excepciones fueron o no fueron lanzadas, y sus tipos.
6. Apoya diversas salidas. Debe tener un formato que puedan entender y analizar el IDEs que se esté utilizando, para que sea más fácil de navegar a cualquier fallo en la prueba como si fueran errores de la sintaxis. Pero también debe tener maneras de exhibir diversas salidas.
7. Grupos de accesorios:. De esto depende el buen funcionamiento de un frameworks de prueba. Las pruebas deben formar parte de una suite o súper-clase de prueba de la cual hereden las que implementan los probadores.

Teniendo como guía los criterios presentados a anteriormente se analizaron los siguientes frameworks:
2.2 CppUnit
El CppUnit, es probablemente framework de unidad de prueba más utilizada en C++. En un principio CppUnit fue bastante complicada de utilizar, ya sea con funciones MFC (Windows) o trabajando GUI (Linux). CppUnit ya cuenta con gran bibliografía y el perfeccionamiento de la misma hace que el trabajo con esta unit se haya vuelto más factible.
1. Mínima cantidad de código a la hora de agregar nuevas pruebas: Es una de sus principales ventajas ya que requiere trabajo aún para la prueba más simple.
2. Facilidad para modificarse y ser portable. Se ejecuta sobre Windows y Linux, y la funcionalidad está bien modulada.
3. Accesorios de ayuda: Si se quiere que los objetos sean creados antes de cada prueba, se necesita que sean los objetos sean asignados dinámicamente en la función setup ().
4. Manejadores de excepciones y de recuperación: Utiliza el concepto de protectores. CppUnit intenta captar e identificar las excepciones por defecto, aunque se pueden crear excepciones propias para que sean combinadas con las ya existentes.
5. Buena funcionalidad del ASSERT: Tiene un sistema de pocas declaraciones acertadas, incluyendo la de comparación de números de tipo punto-flotante.
6. Apoya diversas salidas: Tiene bien definida la funcionalidad para las salidas (Lo cual muestra los resultados de las pruebas) así como para los listeners (los cuales obtienen notificaciones mientras las pruebas ocurren).
7. Grupos de accesorios: Si.
2.3 Boost.Test
Boot_Test no es exclusivamente un framework de unidades de prueba, sino que tiene otras prestaciones. No está basado en la familia XUNIT. Boot_Test es una librería con una gran potencialidad, tiene gran soporte para el manejo de excepciones y las declaraciones avanzadas, además de otras funcionalidades únicas como la ayuda para el chequeo de lazos infinitos.
1. Mínima cantidad de código a la hora de agregar nuevas pruebas: requiere un mínimo de trabajo para adicionar nuevas pruebas, se acerca más al framework de prueba ideal que el CppUnit.
2. Facilidad para modificarse y ser portable: Se obtienen marcas combinadas por la misma razón que en el CppUnit. Esta librería permite portabilidad y un mejor trabajo sobre Linux que la mayoría de los frameworks. Hacerles modificaciones a la Boos.Test puede convertirse en algo complejo.
3. Accesorios de ayuda: Boot.Test evita la estructura de montaje/desmontaje de las pruebas del NUNIT a favor de los constructores/destructores de C++. Una de las grandes ventajas de lo descrito anteriormente es que no se necesita la creación de accesorios de objetos dinámicos y en cambio se puede poner el accesorio completo en la pila, o sea, para referirse a las variables hay que hacerlo a través de nombres de objetos. Se haría mejor si el accesorio se pudiera configurar en la pila a través de la macro BOOST_AUTO_UNIT_TEST.
4. Manejadores de excepciones y de recuperación: No solo se hace el manejo de excepciones de manera correcta sino que imprime información sobre ellas, captura las excepciones de Linux y tiene líneas de comandos que deshabilitan el manejo de estas, permitiendo así capturar los problemas fácilmente.
5. Buena funcionalidad del ASSERT: Tiene declaraciones para cualquier tipo de operación deseada, ya sea de igualdad, menor que, mayor que, entre otras. Tiene ayuda para el chequeo de excepciones que se hayan lanzado. Las declaraciones acertadas correctamente imprimen el contenido de las variables que están siendo chequeadas.
6. Apoya diversas salidas: Probablemente lo tenga pero no es exactamente trivial de cambiar.
7. Grupos de accesorios: Al crear el conjunto de ayudas se requiere una cantidad X de declaraciones y modificaciones en el ejecutor de las pruebas.
2.4 Unit++.
El Unit++ se basa más en el uso del C++ para su implementación interna que CppUnit. Esto no es muy recomendable, pues los expertos sugieren que la vinculación del framework con el C++ solo sea a través de su utilización en la ejecución de las pruebas y que la base del mismo sea un lenguaje que facilite su uso, pues con C++ solo se logran dependencias externas y macros difíciles de entender. Su documentación es pobre y carece de ejemplos que ilustren su funcionamiento.
2.5 NanoCppUnit
Es un framework de prueba dirigido solamente a las plataformas Windows. El código de fuente no se estructura muy bien, está lleno de macros de poco entendimiento, haciendo difícil agregarle nuevas características como tipos de la salida definidas por el usuario. Tiene un empaquetado tremendo del framework, lo cual dificulta el trabajo con él. Escasa bibliografía en internet sobre este framework.
2.6 CxxTest
Cxxtest utiliza el lenguaje Perl para generar código C++. Analiza el código de las pruebas implementadas por el usuario y genera a un corredor de prueba en C++ que se ejecuta directamente desde las pruebas del usuario. Por su flexibilidad es posible hacer pruebas rigurosas con código sencillo. Su único requerimiento es instalar Perl y que este se ejecute correctamente.
1. Minima cantidad de código a la hora de agregar nuevas pruebas: Es muy bueno. Es mejor que los frameworks mencionados ateriormente por su sencillez y fortaleza. Permite crear pruebas sin la necesitad de declarar una clase contenedora.
2. Facilidad para modificarse y ser portable. CxxTest requiere el sistema más simple de características de lenguaje. No necesita librerías externas. También se distribuye simplemente como sistema de archivos de cabecera, por lo que no hay necesidad de compilar en una biblioteca separada o algo similar. Funcionalmente es como un pozo separado del código de fuente original, así que la realización de modificaciones es bastante directa.
3. Accesorios de ayuda. Crear los accesorios es bastante directo y apenas requiere la herencia de una clase, pudiendo crear todas las funciones que se necesiten.
4. Manejadores de excepciones y de recuperación buenos. Captura todas las excepciones e imprime la información sobre ellas, de cualquier tipo de error, aunque no captura excepciones del sistema con Linux. Se puede volver a efectuar fácilmente las pruebas. También brinda un paquete de macro el cual permite la captura de excepciones por el usuario siempre que lo necesite.
5. Buena funcionalidad del ASSERT. Implementa una suite de prueba completa, con funciones assert fáciles de entender, incluyendo las de manejo de excepciones, la comprobación de predicados y las relaciones arbitrarias. Incluso se pueden imprimir warnings, los cuales pueden ser usados para diferenciar dos partes del código llamado en una misma prueba o se pueden imprimir mensajes hechos por el usuario.
6. Soporte a diferentes salidas. Da soporte a diversas salidas, pasándole un parámetro que indique cual es el tipo de salida que el usuario quiere que ejecute el proceso del Perl.
7. Un buen soporte de Suite. Si, todas las pruebas forman parte de una suite.
3. Framework escogido a partir de la experiencia.

En el proceso de escoger un framework para realizar las pruebas de unidad, primero se tuvo en cuanta los aspectos antes mencionados. En segundo lugar, con motivo a los requerimientos del ambiente de trabajo: plataforma GNU/Linux. Y la plataforma de software Eclipse (plataforma utilizada para desarrollar entornos de desarrollo integrados) en la cual se implementaron las clases que se desean probar, se escogió el Cxxtest, el cual se integra bien al Eclipse, siendo de fácil instalación y uso.

Con algunas clases con método de entradas y salidas se probó la macro TS_ASSERT_EQUALS, posibilitando respuestas esperadas declaradas con anterioridad en el diseño de las pruebas de unidad.

CONCLUSIONES
l Cada módulo que se desarrolle puede tener una batería de pruebas de unidad que comprueben que funciona correctamente a lo largo del tiempo. Esto combinado con un proceso de integración continua permite conocer el grado de funcionamiento del proyecto completo.
l CxxTest, framework sencillo de utilizar, tiene una gran suite de pruebas y mucha documentación en internet. Se puede utilizar en ambiente GNU/Linux. Su único inconveniente es que necesita de Perl para que funcione, pero esto se logra de forma sencilla y es, además, su principal potencialidad.

BIBLIOGRAFÍA
1. Games from Within. http://www.gamesfromwithin.com/articles
2. IVAR JACOBSON, G. B., JAMES RUMBAUGH. Capítulo 11: PRUEBA. en: El proceso unificado de desarrollo de software. La Habana, Félix Varela, 2004. 1: 435.p.
3. MYERS, G. J. The Art of Software Testing. Hoboken, New Jersey., John Wiley & Sons, Inc., 2004.
4. PRESSMAN, R. S. Capítulo 17: Técnicas de Prueba del Software. en: Ingeniería del Software. Quinta Edición. La Habana, Félix Varela, 2005. Parte 1: 601.p.
5. Wikipedia, Enciclopedia Libre, http://es.wikipedia.org/wiki/


Datos del Autor
Nombre y Apellidos: Irina Elena Argota Vega
Categoria: Ingeniero en Ciencias Informáticas.
Año de Graduación: 2007
Profesión: Profesor de la Universidad de Ciencias Informáticas
Correo electrónico: iargota@uci.cu
Lugar de Procedencia: Santiago de Cuba, Cuba.

Articulos relacionados:
La enseñanza de la programación según un enfoque de currículo invertido (pdf)
Resumen:
La enseñanza de la programación constituye un enorme desarrollo a nivel mundial. Aprender a programar es un objetivo clave en la gran mayoría de los cursos
introductor...
Rupturas de Informe
Resumen:
Definición de una Ruptura de Informe. Especificación de Opciones de Proceso. Una Ruptura de Informe se usa para dividir el informe en grupos de registros ó líneas, cada v...
Derivación por diferencias divididas y por fórmulas de alta precisión en visual basic 2005
Resumen:
Este programa permite derivar funciones matemáticas utilizando los métodos de diferencias divididas y fórmulas de alta precisión. A continuación se presentan algunas impr...
Programación Orientada a Objetos
Resumen:
Procesamiento de Datos. Estructura de un Objeto. Encapsulamiento y ocultación. Organización. Relaciones. Propiedades. Métodos. Polimorfismo. Beneficios del desarrollo con OOP.
Computación "orientada al pensamiento"
Resumen:
La lógica y la matemática. El computador: un "anillo" matemático. Hacia un pensamiento inteligente. Algoritmos y la máquina de Turing. Puntos de vista en auge: Penrose y ...
Copyright © 2011 ilustrados.com, Monografias, tesis, bibliografias, educacion. Tofos los temas y publicaciones son propiedad de sus respectivos autores ©