Dise帽o y realizaci贸n de pruebas UT3. Entornos de Desarrollo
1. Planificación de las pruebas. Durante todo el proceso de desarrollo de software, desde la fase de diseño, en la implementación y una vez desarrollada la aplicación, es necesario realizar un conjunto de pruebas, que permitan verificar que el software que se está creando, es correcto y cumple con las especificaciones impuesta por el usuario.
1. Planificaci贸n de las pruebas. Proceso que permite verificar y revelar la calidad de un producto software. Se utilizan para identificar posibles fallos de implementaci贸n, calidad o usabilidad de un programa
1. Planificaci贸n de las pruebas. En el proceso de desarrollo de software, nos vamos a encontrar con un conjunto de actividades, donde es muy f谩cil que se produzca un error humano. Estos errores humanos pueden ser: una incorrecta especificaci贸n de los objetivos, errores producidos durante el proceso de dise帽o y errores que aparecen en la fase de desarrollo.
1. Planificaci贸n de las pruebas. Mediante la realizaci贸n de pruebas se software, se van a realizar las tareas de verificaci贸n (Proceso por el que se comprueba que el software cumple los requisitos especificados) y validaci贸n (Proceso que comprueba si el software hace lo que el usuario deseaba. Tiene que estar verificado) del software
1. Planificación de las pruebas. La verificación es la comprobación que un sistema o parte de un sistema, cumple con las condiciones impuestas. Con la verificación se comprueba si la aplicación se está construyendo correctamente. La validación es el proceso de evaluación del sistema o de uno de sus componentes, para determinar si satisface los requisitos especificados.
1. Planificación de las pruebas. Para llevar a cabo el proceso de pruebas, de manera eficiente, es necesario implementar una estrategia de pruebas. Siguiendo el Modelo en Espiral (Modelo de ciclo de vida de ciclo de vida del software, en el que las actividades se conforman en una espiral. Cada bucle o iteración representa un conjunto de actividades), las pruebas empezarían con la prueba de unidad, donde se analizaría el código implementado y seguiríamos en la prueba de integración, donde se prestan atención al diseño y la construcción de la arquitectura del software.
1. Planificaci贸n de las pruebas.
1. Planificaci贸n de las pruebas.
El siguiente paso ser铆a la prueba de validaci贸n, donde se comprueba que el sistema construido cumple con lo establecido en el an谩lisis de requisitos de software. Finalmente se alcanza la prueba de sistema que verifica el funcionamiento total del software y otros elementos del sistema.
2. Tipos de pruebas.
No existe una clasificaci贸n oficial o formal, sobre los diversos tipos de pruebas de software. En la ingenier铆a del software, nos encontramos con dos enfoques fundamentales:
2. Tipos de pruebas.
2. Tipos de pruebas. Prueba
de la Caja Negra (Black Box Testing): cuando una aplicación es probada usando su interfaz externa, sin preocuparnos de la implementación de la misma.
Aquí lo fundamental es comprobar que los resultados de la ejecución de la aplicación, son los esperados, en función de las entradas que recibe.
2. Tipos de pruebas. Una
prueba de tipo Caja Negra se lleva a cabo sin tener que conocer ni la estructura, ni el funcionamiento interno del sistema.
Cuando
se realiza este tipo de pruebas, solo se conocen las entradas adecuadas que deberá recibir la aplicación, así como las salidas que les correspondan, pero no se conoce el proceso mediante el cual la aplicación obtiene esos resultados.
2. Tipos de pruebas. Prueba
de la Caja Blanca (White Box Testing): en este caso, se prueba la aplicación desde dentro, usando su lógica de aplicación.
2. Tipos de pruebas. En
contraposición a lo anterior, una prueba de Caja Blanca, va a analizar y probar directamente el código de la aplicación.
Como
se deriva de lo anterior, para llevar a cabo una prueba de Caja Blanca, es necesario un conocimiento específico del código, para poder analizar los resultados de las pruebas.
2. Tipos de pruebas.
2. Tipos de pruebas.
2.1. Funcionales. Estamos
ante pruebas de la caja negra. Se trata de probar, si las salidas que devuelve la aplicación, o parte de ella, son las esperadas, en función de los parámetros de entrada que le pasemos.
No
nos interesa la implementación del software, solo si realiza las funciones que se esperan de él.
2.1. Funcionales. Las
pruebas funcionales siguen el enfoque de las pruebas de Caja Negra. Comprenderían aquellas actividades cuyo objetivo sea verificar una acción específica o funcional dentro del código de una aplicación.
Las
pruebas funcionales intentarían responder a las preguntas ¿puede el usuario hacer esto? o ¿funciona esta utilidad de la aplicación?
2.1. Funcionales. Su
principal cometido, va a consistir, en comprobar el correcto funcionamiento de los componentes de la aplicación informática.
Para
realizar este tipo de pruebas, se deben analizar las entradas y las salidas de cada componente, verificando que el resultado es el esperado.
Solo
se van a considerar las entradas y salidas del sistema, sin preocuparnos por la estructura interna del mismo.
2.1. Funcionales. Si
por ejemplo, estamos implementando una aplicación que realiza un determinado cálculo científico, en el enfoque de las pruebas funcionales, solo nos interesa verificar que ante una determinada entrada a ese programa el resultado de la ejecución del mismo devuelve como resultado los datos esperados.
Este
tipo de prueba, no consideraría, en ningún caso, el código desarrollado, ni el algoritmo (Conjunto ordenado de pasos a seguir para la resolución de un problema), ni la eficiencia, ni si hay partes del código innecesarias, etc.
2.1. Funcionales. ď ľDentro
de las pruebas funcionales, podemos indicar tres tipos de pruebas: 
2.1. Funcionales. Particiones
equivalentes: La idea de este tipo de pruebas funcionales, es considerar el menor número posible de casos de pruebas, para ello, cada caso de prueba tiene que abarcar el mayor número posible de entradas diferentes.
Lo
que se pretende, es crear un conjunto de clases de equivalencia, donde la prueba de un valor representativo de la misma, en cuanto a la verificación de errores, sería extrapolable al que se conseguiría probando cualquier valor de la clase.
2.1. Funcionales. Particiones
equivalentes: La idea de este tipo de pruebas funcionales, es considerar el menor número posible de casos de pruebas, para ello, cada caso de prueba tiene que abarcar el mayor número posible de entradas diferentes.
Lo
que se pretende, es crear un conjunto de clases de equivalencia, donde la prueba de un valor representativo de la misma, en cuanto a la verificación de errores, sería extrapolable al que se conseguiría probando cualquier valor de la clase.
2.1. Funcionales. Las cualidades que definen un buen caso de prueba: • Cada caso debe cubrir el máximo número de entradas • Debe tratarse el dominio de valores de entrada dividido en un número finito de clases de equivalencia que cumplan la siguiente propiedad: la prueba de un valor representativo de una clase permite suponer «razonablemente» que el resultado obtenido (existan defectos o no) será el mismo que el obtenido probando cualquier otro valor de la clase
2.1. Funcionales. El
método consiste entonces en:
• Identificación equivalencia • Creación de correspondientes
de los
las casos
clases de
de
prueba
2.1. Funcionales. Identificación de las Clases de Equivalencia • Identificar las restricciones al formato y contenido de los datos de las entradas • Identificar las clases de equivalencia: • De datos Válidos • De Datos no Válidos o Erróneos
2.1. Funcionales. Existen algunas reglas identificar una clase:
que
ayudan
a
• Si se especifica un rango de valores para los datos de entrada, se creará una clase válida y dos clases no válidas • Si se especifica un número de valores, se creará una clase válida y dos no válidas
2.1. Funcionales. • Si se especifica una situación del tipo «debe ser» o booleana (por ejemplo, «el primer carácter debe ser una letra»), se identifican una clase válida («es una letra») y una no válida («no es una letra»)
2.1. Funcionales. Si se especifica un conjunto de valores admitidos y se sabe que el programa trata de forma diferente cada uno de ellos, se identifica una clase vรกlida por cada valor y una no vรกlida.
2.1. Funcionales. • En cualquier caso, si se sospecha que ciertos elementos de una clase no se tratan igual que el resto de la misma, deben dividirse en clases menores.
2.1. Funcionales.
2.1. Funcionales. Desarrollar los casos de prueba • Este proceso consta de los siguientes pasos • Asignación de un número único a cada clase de equivalencia
2.1. Funcionales. Hasta que todas las clases de equivalencia hayan sido cubiertas por (incorporadas a) casos de prueba, se tratará de escribir un caso que cubra tantas clases válidas no incorporadas como sea posible • Hasta que todas las clases de equivalencia no válidas hayan sido cubiertas por casos de prueba, escribir un caso para una única clase no válida sin cubrir.
2.1. Funcionales. Hasta que todas las clases de equivalencia hayan sido cubiertas por (incorporadas a) casos de prueba, se tratará de escribir un caso que cubra tantas clases válidas no incorporadas como sea posible • Hasta que todas las clases de equivalencia no válidas hayan sido cubiertas por casos de prueba, escribir un caso para una única clase no válida sin cubrir.
2.1. Funcionales. Ejemplo: Especificación • Código área: número de 3 dígitos que no empieza ni por 0, ni por 1. • Nombre de identificación: 6 caracteres. • Ordenes posibles: "cheque", "depósito", "pago factura", "retirada de fondos".
2.1. Funcionales.
2.1. Funcionales. Nº Caso
Clases de equivalencia
Código orden
Nombre id
Orden
Resultado
2.1. Funcionales. Análisis
Valores Limite (AVL)
2.1. Funcionales. Los
casos de prueba que exploran las condiciones límite producen mejores resultados
“Los defectos del software se acumulan en las situaciones límite” Diferencias
de AVL con particiones de equivalencia:
No se elige “cualquier elemento” de la clase de equivalencia, sino uno o más de manera que los márgenes se sometan a prueba. Los casos de prueba se generan considerando también el espacio de salida.
2.1. Funcionales. 1. Si una condición de entrada especifica un rango delimitado por los valores a y b, se deben generar casos para a y b y casos no válidos justo por debajo y justo por encima de a y b, respectivamente. 2. Si una condición de entrada especifica un número de valores, se deben desarrollar casos de prueba que ejerciten los valores máximo y mínimo, uno más el máximo y uno menos el mínimo.
2.1. Funcionales. 3. Aplicar las directrices 1 y 2 a las condiciones de salida. (los valores lĂmite de entrada no generan necesariamente los valores lĂmite de salida y no siempre se pueden generar resultados fuera del rango de salida (pero es interesante considerarlo).
2.1. Funcionales. 4. Si las estructuras de datos internas tienen lĂmites preestablecidos, hay que asegurarse de diseĂąar un caso de prueba que ejercite la estructura de datos en sus lĂmites.
2.1. Funcionales.
2.1. Funcionales. ď ľPruebas
aleatorias
2.1. Funcionales. Consiste en generar entradas aleatorias para la aplicaci贸n que hay que probar. Se suelen utilizar generadores de prueba, que son capaces de crear un volumen de casos de prueba al azar, con los que ser谩 alimentada la aplicaci贸n.
2.1. Funcionales. Esta tipo de pruebas, se suelen utilizar en aplicaciones que no sean interactivas, ya que es muy difĂcil generar las secuencias de entrada adecuadas de prueba, para entornos interactivos.
2.2. Estructurales. Enfoque estructural o de caja blanca (transparente): Se
centra en la estructura interna del programa para elegir los casos de prueba.
La
prueba exhaustiva consistiría en probar todos los posibles caminos de ejecución.
n°
caminos lógicos muy alto ( buscar los más importantes).
2.2. Estructurales. Con este tipo de pruebas, se pretende verificar la estructura interna de cada componente de la aplicaci贸n, independientemente de la funcionalidad establecida para el mismo.
2.2. Estructurales. Este tipo de pruebas, no pretenden comprobar la correcci贸n de los resultados producidos por los distintos componentes, su funci贸n es comprobar que se van a ejecutar todas la instrucciones del programa, que no hay c贸digo no usado, comprobar que los caminos l贸gicos del programa se van a recorrer, etc.
2.2. Estructurales. Prueba del Camino Básico. Objetivos: 1. Obtener una medida de la complejidad lógica de un diseño procedimental. Complejidad ciclomática de Mc Cabe
2.2. Estructurales. Usar esa medida como gu铆a para la definici贸n de un conjunto b谩sico de caminos de ejecuci贸n. Los casos de prueba obtenidos garantizan que durante la prueba se ejecuta al menos una vez cada sentencia del programa (cobertura de sentencias). Se puede automatizar.
2.2. Estructurales. Ejemplo:
2.2. Estructurales. Ejemplo:
2.2. Estructurales. Ejemplo:
2.2. Estructurales.
2.2. Estructurales.
2.2. Estructurales. Definiciones □Camino: secuencia de sentencias encadenadas desde la sentencia inicial del programa hasta su sentencia final. □Camino de prueba: un camino que atraviesa, como máximo, una vez el interior de cada bucle que encuentra.
2.2. Estructurales. Definiciones □Camino linealmente independiente de otros: introduce por lo menos un nuevo conjunto de sentencias de proceso o una nueva condición. En términos del grafo de flujo, introduce una nueva arista que no haya sido recorrida anteriormente a la definición del camino
2.2. Estructurales. Definiciones □Camino linealmente independiente de otros: introduce por lo menos un nuevo conjunto de sentencias de proceso o una nueva condición. En términos del grafo de flujo, introduce una nueva arista que no haya sido recorrida anteriormente a la definición del camino
2.2. Estructurales. Definiciones ■Buen criterio de prueba: Ejecución de un conjunto de caminos independientes. ■¿Número máximo de caminos independientes?
2.2. Estructurales. Definiciones ■Complejidad ciclomática de Mc Cabe, V(G): V(G) = a - n + 2 ("a", n° de arcos del grafo; "n", n° de nodos) V(G) = r ("r", n° de regiones del grafo) V(G) = c +1 ("c", n° de nodos de condición) (Case of 1... N cuenta como n-1 en V(G)= c+1)
2.2. Estructurales. Definiciones
2.2. Estructurales. Ejemplo:
2.2. Estructurales. Ejemplo:
EJERCICIO
2.2. Estructurales. Definiciones 1. Usando el diseño o el código como base, dibujamos el correspondiente grafo de flujo. 2. Determinamos la complejidad ciclomática del grafo de flujo resultante, V(G). 3. Determinamos un conjunto básico de hasta V(G) caminos linealmente independientes. 4. Preparamos los casos de prueba que forzarán la ejecución de cada camino del conjunto básico.
2.2. Estructurales. Definiciones Algunos consejos: numerar dividir
los nodos del grafo secuencialmente
las condiciones compuestas en distintos nodos, uno por cada condición simple (así se obtiene cobertura de sentencias y de condiciones)
2.2. Estructurales. Definiciones Algunos consejos: ď ľ
describir el conjunto de caminos independientes (subrayar aristas que los hacen independientes de los anteriores)
1-2-11 1-2-3-4-... ...
2.2. Estructurales. Definiciones Algunos consejos: crear
los caminos “incrementalmente”: cuando se escogen caminos largos al principio, es más probable que no se puedan ejecutar en la práctica, y además se cubren todas las aristas del grafo con un número de caminos menor que V(G) (que recordemos es un valor máximo)
2.2. Estructurales. Definiciones Algunos consejos: a
partir de los caminos, analizar el código para ver qué datos de entrada son necesarios, y qué salida se espera
algunos caminos pueden ser imposibles ⇒ seleccionar otros algunos caminos no se pueden ejecutar solos y requieren la concatenación con otro
2.2. Estructurales. Definiciones
2.2. Estructurales. Definiciones
2.2. Estructurales. Definiciones
2.3. Pruebas de regresi贸n. Pruebas de Regresi贸n. Actividad
3. Herramientas de depuración. Todo entorno de desarrollo, independientemente de la plataforma, así como del lenguaje de programación utilizado, suministra una serie de herramientas de depuración, que nos permiten verificar el código generado, ayudándonos a realizar pruebas tanto estructurales como funcionales.
3. Herramientas de depuraciรณn. Durante el proceso de desarrollo de software, se pueden producir dos tipos de errores: errores de compilaciรณn o errores lรณgicos. Cuando se desarrolla una aplicaciรณn en un IDE, ya sea Visual Studio, Eclipse o Netbeans, si al escribir una sentencia, olvidamos un ";", hacemos referencia a una variable inexistente o utilizamos una sentencia incorrecta, se produce un error de compilaciรณn.
3. Herramientas de depuraci贸n. Cuando ocurre un error de compilaci贸n, el entorno nos proporciona informaci贸n de donde se produce y como poder solucionarlo. El programa no puede compilarse hasta que el programador o programadora no corrija ese error.
3. Herramientas de depuración. El otro tipo de errores son lógicos, comúnmente llamados bugs, estos no evitan que el programa se pueda compilar con éxito, ya que no hay errores sintácticos, ni se utilizan variables no declaradas, etc.
3. Herramientas de depuraci贸n. Sin embargo, los errores l贸gicos, pueden provocar que el programa devuelva resultados err贸neos, que no sean los esperados o pueden provocar que el programa termine antes de tiempo o no termine nunca.
3. Herramientas de depuraci贸n. Para solucionar este tipo de problemas, los entornos de desarrollo incorporan una herramienta conocida como depurador. El depurador permite supervisar la ejecuci贸n de los programas, para localizar y eliminar los errores l贸gicos. Un programa debe compilarse con 茅xito para poder utilizarlo en el depurador.
3. Herramientas de depuración. El depurador nos permita analizar todo el programa, mientras éste se ejecuta. Permite suspender la ejecución de un programa, examinar y establecer los valores de las variables, comprobar los valores devueltos por un determinado método, el resultado de una comparación lógica o relacional, etc.
3. 1. Puntos de ruptura. Dentro del menú de depuración, nos encontramos con la opción insertar punto de ruptura (breakpoint). Se selecciona la línea de código donde queremos que el programa se pare, para a partir de ella, inspeccionar variables, o realizar una ejecución paso a paso, para verificar la corrección del código
3. 1. Puntos de ruptura. Durante la prueba de un programa, puede ser interesante la verificaci贸n de determinadas partes del c贸digo. No nos interesa probar todo el programa, ya que hemos delimitado el punto concreto donde inspeccionar. Para ello, utilizamos los puntos de ruptura.
3. 1. Puntos de ruptura. Los puntos de ruptura son marcadores que pueden establecerse en cualquier línea de código ejecutable (no sería válido un comentario, o una línea en blanco). Una vez insertado el punto de ruptura, e iniciada la depuración, el programa a evaluar se ejecutaría hasta la línea marcada con el punto de ruptura.
3. 1. Puntos de ruptura. En ese momento, se pueden realizar diferentes labores, por un lado, se pueden examinar las variables, y comprobar que los valores que tienen asignados son correctos, o se pueden iniciar una depuraci贸n paso a paso, e ir comprobando el camino que toma el programa a partir del punto de ruptura. Una vez realiza la comprobaci贸n, podemos abortar el programa, o continuar la ejecuci贸n normal del mismo.
3. 1. Puntos de ruptura. Dentro de una aplicaci贸n, se pueden insertar varios puntos de ruptura, y se pueden eliminar con la misma facilidad con la que se insertan.
3. 2. Tipos de Ejecuci贸n Para poder depurar un programa, podemos ejecutar el programa de diferentes formas, de manera que en funci贸n del problema que queramos solucionar, nos resulte m谩s sencillo un m茅todo u otro.
3. 2. Tipos de Ejecución Nos encontramos con lo siguientes tipo de ejecución: paso a paso por instrucción, paso a paso por procedimiento, ejecución hasta una instrucción, ejecución de un programa hasta el final del programa,etc
3. 2. Tipos de Ejecución Algunas veces es necesario ejecutar un programa línea por línea, para buscar y corregir errores lógicos. El avance paso a paso a lo largo de una parte del programa puede ayudarnos a verificar que el código de un método se ejecute en forma correcta.
3. 2. Tipos de Ejecución El paso a paso por procedimientos, nos permite introducir los parámetro que queremos a un método o función de nuestro programa, pero en vez de ejecutar instrucción por instrucción ese método, nos devuelve su resultado. Es útil, cuando hemos comprobado que un procedimiento funciona correctamente, y no nos interese volver a depurarlo, sólo nos interesa el valor que devuelve.
3. 2. Tipos de Ejecuciรณn En la ejecuciรณn hasta una instrucciรณn, el depurador ejecuta el programa, y se detiene en la instrucciรณn donde se encuentra el cursor, a partir de ese punto, podemos hacer una depuraciรณn paso a paso o por procedimiento.
3. 2. Tipos de Ejecuci贸n En la ejecuci贸n de un programa hasta el final del programa, ejecutamos las instrucciones de un programa hasta el final, sin detenernos en las instrucciones intermedias.
3. 2. Tipos de Ejecución Los distintos modos de ejecución, se van a ajustar a las necesidades de depuración que tengamos en cada momento. Si hemos probada un método, y sabemos que funciona correctamente, no es necesario realizar una ejecución paso a paso en él.
3. 3. Depuraci贸n en Eclipse F8
F5 F6 F7
3. 3. Depuración en Eclipse Punto
de ruptura condicional
Punto
de ruptura de Excepciones
Modificar
variables
4. Validación En
el proceso de validación, interviene de manera decisiva el cliente. Hay que tener en cuenta, que estamos desarrollando una aplicación para terceros, y que son estos los que deciden si la aplicación se ajusta a los requerimientos establecidos en el análisis.
4. Validación En
la validación intentan descubrir errores, pero desde el punto de vista de los requisitos (Comportamiento y casos de uso que se esperan que cumpla el software que se está diseñando).
La
validación del software se consigue mediante una serie de pruebas de caja negra que demuestran la conformidad con los requisitos.
4. ValidaciĂłn ď ľ Un
plan de prueba traza la clase de pruebas que se han de llevar a cabo, y un procedimiento de prueba define los casos de prueba especĂficos en un intento por descubrir errores de acuerdo con los requisitos.
4. Validación Tanto
el plan como el procedimiento estarán diseñados para asegurar que se satisfacen todos los requisitos funcionales, que se alcanzan todos los requisitos de rendimiento, que las documentaciones son correctas e inteligible y que se alcanzan otros requisitos, como portabilidad (capacidad de un programa para ser ejecutado en cualquier arquitectura física de un equipo), compatibilidad, recuperación de errores, facilidad de mantenimiento etc.
4. ValidaciĂłn ď ľ Cuando
se procede con cada caso de prueba de validaciĂłn, puede darse una de las dos condiciones siguientes:
4. Validación Las
características de funcionamiento o rendimiento están de acuerdo con las especificaciones y son aceptables O
Se
descubre una desviación de las especificaciones y se crea una lista de deficiencias. Las desviaciones o errores descubiertos en esta fase del proyecto raramente se pueden corregir antes de la terminación planificada.
5. Normas de calidad Los estándares que se han venido utilizando en la fase de prueba de software son: Estándares
BSI
BS 7925‐1, Pruebas de software. Parte 1. Vocabulario. BS 7925‐2, Pruebas de software. Parte 2. Pruebas de los componentes software.
5. Normas de calidad Los estándares que se han venido utilizando en la fase de prueba de software son: Estándares
IEEE de pruebas de software.:
IEEE estándar 829, Documentación de la prueba de software. IEEE estándar 1008, Pruebas de unidad Otros estándares ISO / IEC 12207, 15289
5. Normas de calidad Los estándares que se han venido utilizando en la fase de prueba de software son: Otros
estándares sectoriales
5. Normas de calidad Sin embargo, estos est谩ndares no cubren determinadas facetas de la fase de pruebas, como son la organizaci贸n el proceso y gesti贸n de las pruebas, presentan pocas pruebas funcionales y no funcionales etc. Ante esta problem谩tica, la industria ha desarrollado la norma ISO/IEC 29119.
5. Normas de calidad La norma ISO/IEC 29119 de prueba de software, pretende unificar en una única norma, todos los estándares, de forma que proporcione vocabulario, procesos, documentación y técnicas para cubrir todo el ciclo de vida del software.
5. Normas de calidad Desde estrategias de prueba para la organización y políticas de prueba, prueba de proyecto al análisis de casos de prueba, diseño, ejecución e informe. Con este estándar, se podrá realizar cualquier prueba para cualquier proyecto de desarrollo o mantenimiento de software.
5. Normas de calidad EJERCICIO. Investiga de que partes se compone la norma ISO/IEC 29119, y describe brevemente cada una de ellas.
6. Pruebas unitarias Las pruebas unitarias, o prueba de la unidad, tienen por objetivo probar el correcto funcionamiento de un m贸dulo de c贸digo. El fin que se persigue, es que cada m贸dulo funciona correctamente por separado.
6. Pruebas unitarias Posteriormente, con la prueba de integración, se podrá asegurar el correcto funcionamiento del sistema. Una unidad es la parte de la aplicación más pequeña que se puede probar. En programación procedural, una unidad puede ser una función o procedimiento, En programación orientada a objetos, una unidad es normalmente un método.
6. Pruebas unitarias Con las pruebas unitarias se debe probar todas las funciones o mĂŠtodos no triviales de forma que cada caso de prueba sea independiente del resto.
6. Pruebas unitarias En el diseño de los casos de pruebas unitarias, habrá que tener en cuenta los siguientes requisitos: Automatizable:
no intervención manual.
Completas:
código.
debería
requerirse
una
deben cubrir la mayor cantidad de
6. Pruebas unitarias Repetibles
o Reutilizables: no se deben crear pruebas que sólo puedan ser ejecutadas una sola vez.
Independientes:
la ejecución de una prueba no debe afectar a la ejecución de otra.
Profesionales:
las pruebas deben ser consideradas igual que el código, con la misma profesionalidad, documentación, etc.
6. Pruebas unitarias ď ľ El
objetivo de las pruebas unitarias es aislar cada parte del programa y demostrar que las partes individuales son correctas.
6. Pruebas unitarias ď ľ Las
pruebas individuales nos proporcionan cinco ventajas bĂĄsicas:
6. Pruebas unitarias 1. Fomentan el cambio: Las pruebas unitarias facilitan que el programador cambie el c贸digo para mejorar su estructura, puesto que permiten hacer pruebas sobre los cambios y as铆 asegurarse de que los nuevos cambios no han introducido errores.
6. Pruebas unitarias 2. Simplifica la integraci贸n: Puesto que permiten llegar a la fase de integraci贸n con un grado alto de seguridad de que el c贸digo est谩 funcionando correctamente.
6. Pruebas unitarias 3. Documenta el código: Las propias pruebas son documentación del código puesto que ahí se puede ver cómo utilizarlo.
6. Pruebas unitarias 4. Separación de la interfaz y la implementación: Dado que la única interacción entre los casos de prueba y las unidades bajo prueba son las interfaces de estas últimas, se puede cambiar cualquiera de los dos sin afectar al otro.
6. Pruebas unitarias 5. Los errores están más acotados y son más fáciles de localizar: dado que tenemos pruebas unitarias que pueden desenmascararlos.
6.1. Herramientas para realizar pruebas unitarias EJERCICIO. ¿Qué herramientas nos podemos encontrar en el mercado para poder realizar pruebas unitarias? Para
Java
Para
C
6.2. Junit Los entornos de desarrollo mรกs extendidos, que se utilizan para implementar aplicaciones Java, tales como NetBeans o Eclipse, incorporan un plugin para trabajar con Junit Junit nos va a servir para realizar pruebas unitarias de clases escritas en Java, dentro de un entorno de pruebas. Es un framework con muy pocas clases fรกcil de aprender y de utilizar.
6.2. Junit Una vez que hemos dise帽ado nuestra aplicaci贸n, y la hemos depurado, procedemos a probarla. El objetivo va a ser el dise帽o y ejecuci贸n de algunos casos de prueba.
6.2. Junit En primer lugar, vamos a ver la función de los Inicializadores y Finalizadores. El método SetUp y el método tearDown, se utilizan para inicializar y finalizar las condiciones de prueba, como puede ser la creación de un objeto, inicialización de variables, etc. En algunos casos, no es necesario utilizar estos métodos, pero siempre se suelen incluir.
6.2. Junit El método setUp es un método de inicialización de la prueba y se ejecutan antes de cada caso de prueba, en la clase de prueba. Este método no es necesario para ejecutar pruebas, pero si es necesario para inicializar algunas variables antes de iniciar la prueba.
6.2. Junit El método tearDown es un método finalizador de prueba, y se ejecutará después de cada test en la clase prueba. Un método finalizador no es necesario para ejecutar las pruebas, pero si necesitamos un finalizador para limpiar algún dato que fue requerido en la ejecución de los casos de prueba.
6.2. Junit En segundo lugar, es necesario conocer las aserciones. Los método assertXXX(), se utilizan para hacer las pruebas. Estos métodos, permiten comprobar si la salida del método que se está probando, concuerda con los valores esperados. Las principales son:
6.2. Junit assertTrue()
evalúa una expresión booleana. La prueba pasa si el valor de la expresión es true.
assertFalse()
evalúa una expresión booleana. La prueba pasa si el valor de la expresión es false.
assertNull()
verifica que la referencia a un objeto es nula. assertNotNull() verifica que la referencia a un objeto es no nula.
6.2. Junit ď ľ assertSame()
compara dos referencias y asegura que los objetos referenciados tienen la misma direcciĂłn de memoria. La prueba pasa si los dos argumentos son el mismo objeto o pertenecen al mismo objeto.
6.2. Junit ď ľ assertNotSame()
Compara dos referencias a objetos y asegura que ambas apuntan a diferentes direcciones de memoria. La prueba pasa si los dos argumentos suplidos son objetos diferentes o pertenecen a objetos distintos.
6.2. Junit assertEquals()
Se usa para comprobar igualdad a nivel de contenidos. La igual de tipos primitivos se compara usando "==", la igual entre objetos se compara con el método equals(). La prueba pasa si los valores de los argumentos son iguales.
fails()
causa que la prueba falle inmediatamente. Se puede usar cuando la prueba indica un error o cuando se espera que el método que se está probando llame a una excepción.
6.2. Junit Anotaciones En
versiones anteriores de Junit no existían caracteres especiales, que llamamos anotaciones, y que se han incluído en su versión 4 para intentar simplificar más la labor del programador. Se trata de palabras clave que se colocan delante de los definidos antes y que indican a las librerías JUnit instrucciones concretas.
6.2. Junit @RunWith:
Se le asigna una clase a la que JUnit invocará en lugar del ejecutor por defecto de JUnit
@Before:
Indicamos que el siguiente método se debe ejecutar antes de cada test (precede al método setUp). Si tiene que preceder al método setUpClass, la notación será "@BeforeClass"
6.2. Junit @After:
Indicamos que el siguiente método se debe ejecutar después de cada test (precede al método tearDown). Si tiene que preceder al método tearDownClass, la notación será "@AfterClass"
@Test:
Indicamos a Junit que se trata de un método de Test. En versiones anteriores de JUnit los métodos tenían que tener un nombre con la siguiente estructura: "test". Con esta notación colocada delante de los métodos podemos elegir el nombre libremente.
6.2. Junit Ejemplo Ejercicio1 Ejercicio