UNIDAD 5.docx
Document Details

Uploaded by FancierRapture7469
Full Transcript
UNIDAD 5 – PRUEBAS Y DEPURACIÓN DEL SOFTWARE 1 – PLANIFICACIÓN DE PRUEBAS A LO LARGO DEL CICLO DE DESARROLLO La mejor manera de minimizar el número de errores de un programa es encontrarlos y eliminarlos durante el análisis y el diseño, de modo que se introduzcan pocos errores en el código fuente. P...
UNIDAD 5 – PRUEBAS Y DEPURACIÓN DEL SOFTWARE 1 – PLANIFICACIÓN DE PRUEBAS A LO LARGO DEL CICLO DE DESARROLLO La mejor manera de minimizar el número de errores de un programa es encontrarlos y eliminarlos durante el análisis y el diseño, de modo que se introduzcan pocos errores en el código fuente. Podemos identificar dos enfoques que casi siempre las pruebas de software son una combinación de ambos pero con tendencia a uno de ellos, son: - Testeo exploratorio - Testeo guiado 1.1 – Testeo exploratorio Su principal característica es que el aprendizaje, el diseño y la ejecución de las pruebas se realizan de forma simultánea, esto quiere decir que mientras se está probando el software el testeador va aprendiendo a manejar el sistema y así genera nuevas pruebas a ejecutar. Estas pruebas son útiles a la hora de probar aplicaciones ya desarrolladas, es decir que no comienzan a la vez que el desarrollo, se le dará libertad al testeador que se pondrá en la piel de un usuario para probarlos. 1.2 – Testeo guiado También llamado testeo basado en procedimientos de prueba, los casos de prueba son diseñados con antelación incluyendo tanto los pasos a realizar como el resultado esperado. Estas pruebas son más tarde ejecutadas por un testeador que compara el resultado actual con el esperado. El objetivo de las pruebas no siempre es detectar errores, muchas veces lo que quiere conseguirse es que el sistema ofrezca un rendimiento determinado, que la interfaz tenga una determinada apariencia y cumpla unas características, etc. Por ello, la ausencia de errores en las pruebas nunca significa que el software las supere. En los planes de pruebas (es un documento que detalla en profundidad las pruebas que se vayan a realizar), generalmente se cubren los siguientes aspectos: Introducción. Breve introducción del sistema describiendo objetivos, estrategia, etc. Módulos o partes del software por probar. Características del software por probar. Características del software que no ha de probarse. Enfoque de las pruebas. Aquí se detallan las personas responsables, la duración, etc. Criterios de validez o invalidez del software. En este apartado se registra cuando el software puede darse como válido o inválido especificando los criterios. Procesos de pruebas. Se especificará el proceso y los procedimientos de las pruebas a ejecutar. Requerimientos del entorno. Incluyendo niveles de seguridad, necesidades hardware, etc. Homologación o aprobación del plan. El plan deberá estar firmado por los interesados o sus responsables. 1.3 – Casos de prueba En la fase de pruebas, se diseñan y preparan los casos de prueba, que se crean con el objetivo de encontrar fallos. Es importante mencionar que las pruebas que tengan que hacerse en la fase de pruebas no implica que tengan que hacerse después en la fase de desarrollo. Es muy importante realizar un buen diseño de las pruebas con buenos casos de pruebas puesto que de esta manera se aumenta la probabilidad de encontrar fallos. 2 – CODIFICAIÓN Y EJECUCIÓN DE LAS PRUEBAS Una vez diseñados los casos de prueba, hay que generar las condiciones necesarias para poder ejecutar dichos casos de prueba. Habrá que codificarlos en muchos casos generando set o conjunto de datos. En estos set de datos, hay que incluir tanto datos válidos e inválidos como algunos datos fuera de rango. También se prepararán las máquinas sobre las que van a hacerse las pruebas instalando el software necesario. Una vez preparado se irán ejecutando los casos de prueba uno a uno y cuando se detecte algún error hay que aislarlo y anotar la acción que estaba probándose, el caso, el módulo, la fecha, etc. para poder documentarlo detalladamente el error. 3 – TIPO DE PRUEBAS Las pruebas con frecuencia se agrupan por su nivel de especificidad. Los principales niveles durante el proceso de desarrollo son: - Pruebas de unidad o pruebas unitarias. - Pruebas de integración. - Pruebas de sistema 3.1 – La prueba de unidad Son las pruebas para verificar el funcionamiento de una sección específica del código y asegurar que los componentes básicos del software trabajan correctamente. Normalmente se escriben por los desarrolladores a medida que trabajan en el código, para asegurarse de que la función específica está funcionando como se esperaba. Sin embargo, las pruebas unitarias no descubrirán todos los errores del código, solo podrán ser efectivas si se usan en conjunto con otras pruebas de software. Ventajas: Fomentan el cambio. Facilitan que el programador cambie el código para mejorar su estructura (refactorización). Simplifican la integración. Ya que permiten llegar a la fase de integración con un nivel alto de seguridad de que el código funciona correctamente. Documentan el código. Las propias pruebas son documentación del código puesto que ahí se puede ver cómo utilizarlo. Separación de la interfaz y la implementación. Los errores están más acotados y son más fáciles de localizar. Dado que tenemos pruebas unitarias que puedan desenmascararlos. 3.2 – Las pruebas de integración Tratan de verificar las interfaces entre los componentes que fueron definidas al diseñar el software. Progresivamente grupos cada vez mayores de componentes de software ya probados se van integrando y probando hasta que el software funciona como un sistema. 3.3 – Las pruebas de sistema Prueban un sistema completamente integrado para verificar que cumple con sus requisitos. Estas pruebas deben garantizar que el software, además de trabajar como se esperaba, no destruye o corrompe parcialmente su entorno operativo ni causa que otros procesos dentro de ese entorno dejen de funcionar. 4 – TÉCNICAS DE PRUEBAS Se clasifican en dos grandes tipos: Pruebas de caja blanca. Se analiza el interior del programa, es decir, la lógica y la estructura de su código fuente. El testeador escoge distintos valores de entrada para examinar cada uno de los posibles flujos de ejecución del programa y cerciorarse de que se devuelven los valores de salida adecuados. Pruebas de caja negra. Interesa conocer qué es lo que hace, pero no cómo lo hace. Por lo que, no interesa el interior del programa, sino que funcione como es debido. 4.1 – Test-Driven Development El Desarrollo de software guiado por pruebas (TDD), involucra dos prácticas: escribir las pruebas primero (Test First Development) y refactorizar. Generalmente utilizan pruebas unitarias: en primer lugar, se escribe una prueba y se verifica que la prueba falla; a continuación, se implementa el código que hace que la prueba se pase satisfactoriamente y seguidamente se refactoriza el código escrito. El propósito del TDD es lograr un código limpio que funcione. Para que el TDD funcione, el software que se programe tiene que ser lo suficientemente flexible como para permitir que sea probado automáticamente; frameworks como Junit proveen de mecanismos para manjear y ejecutar conjuntos de pruebas automatizadas. 4.2 – Pruebas de regresión Se denominan así a las pruebas de un sistema o componente que pretenden verificar que las modificaciones realizadas sobre el mismo no han causado efectos no deseados y que el sistema o componente sigue cumpliendo con sus requisitos especificados. 5 – TÉCNICAS COMUNES DE PRUEBAS DE UNIDAD Para que una prueba unitaria sea buena, debe cumplir los siguientes requisitos: Automatizable. No debería requerirse una intervención manual. Completa. Debe cubrir la mayor cantidad de código. Repetible o reutilizable. No se deben crear pruebas que solo puedan ser ejecutadas una solo vez. Profesional. Las pruebas deben ser consideradas igual que el código, con la misma profesionalidad. Para la realización de las pruebas de unidad se utilizan diversas técnicas: Las pruebas funcionales. Son pruebas de caja negra. Verifican una determinada acción o función del código. Las pruebas estructurales. Son pruebas de caja blanca. Ejercitan la lógica interna de un programa recorriendo rutas de ejecución particulares decidiendo por ejemplo cuáles rutas ejecutar. Mediante las técnicas de prueba de caja blanca se pueden diseñar casos de prueba que: Ejerciten caminos independientes dentro de un módulo. Ejerciten decisiones lógicas en sus vertientes verdadera y falsa. Ejerciten bucles en sus límites y en sus rangos de operación. 6 – PARTICIPACIÓN EN CLASES DE EQUIVALENCIA Y EL ANÁLISIS DE VALORES LÍMITE La participación en clases de equivalencia (ECP – Equivalence Class Partitioning) es una técnica de pruebas de software, habitualmente de caja negra, que divide los datos de entrada y los resultados de salida de una unidad de software en particiones de datos equivalentes de las que se pueden derivar los casos de prueba. En general, una entrada tiene ciertos rangos que son válidos y otros que no lo son. Datos no válidos aquí no quiere decir que los datos sean incorrectos; significa que estos datos se encuentran fuera de la partición específica. Por ejemplo, supóngase una función que toma un parámetro “mes”: el rango válido para el mes es de 1 a 12 (enero a diciembre), este rango válido se denomina partición. En este ejemplo hay dos particiones adicionales de rangos no válidos: la primera partición no válida sería <=0 y la segunda >=13. La técnica ECP afirma que es suficiente seleccionar un caso de prueba de cada partición para comprobar el comportamiento del programa. Utilizar más o incluso todos los casos de prueba de una división no encontrará nuevos fallos en el programa, pues los valores dentro de una partición se consideran “equivalentes”. Así, el número de casos de prueba se puede reducir considerablemente. ECP tiene que ser complementado con el análisis de valores límites (BVA – Boundary-value análisis). BVA es una técnica de pruebas de software por la que los valores en los bordes mínimo y máximo de cada partición de equivalencia se han de incluir en los casos de prueba, dado que estas fronteras son lugares comunes para errores de software. En el ejemplo anterior el número 0 es el valor máximo en la primera partición y el número 1 es el mínimo en la segunda partición. Se deben crear casos de prueba para ambos lados de cada frontera, lo que da lugar a dos casos por cada límite. Cuando un valor límite cae dentro de una partición no válida, el caso de prueba será diseñado para asegurar que el componente software maneja ese valor de una manera controlada. Supongamos que una persona quiere comprar una televisión y puede o no tener suficiente dinero. Habríamos de asegurarnos de que nuestros casos de prueba incliyen: · La propiedad cuesta 100€, tiene 200€ (partición “tiene suficiente dinero”). · La propiedad cuesta 100€, tiene 50€ (partición “no tiene suficiente dinero”). · La propiedad cuesta 100€, tiene 100€ (valor límite). · La propiedad cuesta 100€, tiene 99€ (valor límite). Normalmente una unidad de software recibirá varias entradas. Cuando pase esto, hay que identificar las clases de equivalencia de cada variable; luego se deberán seleccionar valores de cada partición para todas las variables y combinarlos formando los casos de prueba. Este procedimiento puede automatizarse. 7 – PRUEBA DE CAMINOS BÁSICOS (PCB) Esta prueba proporciona el mínimo número de casos de prueba que necesita ser escrito. Es un medio para asegurar que todos los caminos independientes a través de un módulo de código han sido probados. Un camino independiente es cualquier camino a través del código que introduce al menos un nuevo conjunto de instrucciones de procesamiento o una nueva condición. Se deberá escribir un caso de prueba para asegurase de que cada uno de los caminos independientes se prueba al menos una vez. El método diseñado por Watson y McCabe opera en tres etapas: Convertir el código fuente a un grafo de control. Calcular la complejidad ciclomática y obtener la base de caminos. Preparar un caso de prueba para cada camino básico. 8 – PRUEBAS DE COBERTURA La cobertura es una medida de alcance del conjunto de casos de prueba. El significado de los criterios de cobertura es: Cobertura de proposiciones. Se busca un conjunto de casos de prueba que ejecute cada instrucción por lo menos una vez. Cobertura de ramificaciones. Se busca un conjunto de casos de prueba que ejecute cada instrucción de las ramificaciones en cada dirección al menos una vez. Cobertura de condiciones. Cuando existen condiciones compuestas en el software (expresiones lógicas como AND y OR), se busca un conjunto de casos de prueba que evalúe cada condición simple tanto a resultado verdadero como a resultado falso. Cobertura de caminos (o rutas lógicas). Se basa en el orden en que se ejecutan las ramas durante una prueba. Una regla empírica utilizada a menudo para la terminación de las pruebas de unidad es llegar al 85 ó 90% de la cobertura de ramificación. 9 – LAS PRUEBAS DE INTEGRACIÓN Son pruebas en las que módulos individuales de software son combinados y probados como un grupo. Se deberán ejecutar una vez se haya asegurado el funcionamiento correcto de cada componente implicado por separado, es decir, una vez que se haya ejecutado sin errores las pruebas unitarias de estos componentes. Preceden a las pruebas de sistema. En proyectos reales, la distinción entre pruebas unitarias y de integración puede volverse difusa, ya que es poco común poder probar una clase o sujeto de pruebas de forma aislada. Esto se debe a que el Sujeto en Pruebas (SUT) a menudo depende de otras clases, configuraciones de archivos o bases de datos, e incluso de otros componentes del sistema. Para abordar esto, se utilizan artefactos específicos: Stubs: Son componentes auxiliares que simulan el comportamiento de componentes aún no implementados, proporcionando respuestas predefinidas durante la prueba. Objetos Mock: Son objetos pre-programados con expectativas de llamadas que se espera recibir, simulando el comportamiento de componentes del sistema. Aunque similares a los stubs, se utilizan principalmente en orientación a objetos con sutiles diferencias. 9.1 – Estrategias pruebas de integración Hay diferentes estrategias para realizar las pruebas de integración: Pruebas no incrementales (“Big bang approach”). Se integran todos los componentes y entonces se prueba el sistema como un todo. No es una técnica recomendada pues dificulta el aislamiento de errores. Pruebas incrementales. El programa es construido y probado en pequeños incrementos. Esto facilita las pruebas sistemáticas y el aislamiento de errores esto hace que la depuración sea más fácil. Las pruebas incrementales pueden ser: · Descendentes (“Top-down”). La integración se realiza partiendo del programa principal y moviéndonos hacia abajo por la jerarquía de control. Suele requerir de stubs u objetos Mock. Hay a su vez dos modos de descenso: En profundidad (“Depth-first”). La integración se realiza por ramas. Cada rama suele implementar una funcionalidad específica, por lo permite la prueba de funcionalidades completas. En anchura (“Breadth-first”). La integración se realiza por niveles moviéndose en horizontal por la estructura de control. · Ascendentes (“Bottom-up”). La integración se realiza partiendo de módulos atómicos situados en los nodos finales de la jerarquía de control. No suele necesitar de stubs, pero precisa de controladores de prueba o impulsores (“drivers”) que simulan la llamada a los módulos, introduciendo los datos de prueba y recogiendo los resultados. 10 – TÉCNICAS COMUNES DE PRUEBAS DE SISTEMA 10.1 – Pruebas de sistema: técnicas Para realizar las pruebas de sistema se utilizan diferentes técnicas: Pruebas funcionales. Pruebas de rendimiento: Determinan el tiempo de ejecución empleado en las distintas partes del programa, la eficiencia del software y su tiempo de respuesta. Pruebas de resistencia (o de tensión): Su objetivo es tratar de colapsar el programa. Su forma de hacerlo es muy variada: introduciendo gran cantidad de datos de entrada, limitando los recursos de la aplicación, realizando muchas solicitudes simultáneas, etc. Pruebas destructivas: Intentan hacer que el software falle. Verifican que el software funcione correctamente incluso cuando recibe entradas no válidas o inesperadas, estableciendo así la solidez de las rutinas de validación de entradas y de la gestión de errores. Pruebas de recuperación: Se comprueba cómo reacciona el sistema ante un fallo general, y las posibilidades que tiene de solucionar el error. La recuperación del sistema puede realizarla automáticamente el programa, o mediante la intervención del usuario. Pruebas de seguridad: Se comprueba que tanto los datos como el propio sistema están completamente protegidos frente a todo tipo de agresiones externas e internas. Por ejemplo, se intentará entrar indebidamente en el sistema, bloquear el programa, eliminar los datos vitales, etc. Es decir, el probador actuará como un hacker. Pruebas de usabilidad: Se comprueba si la interfaz de usuario es fácil de usar y comprender. Tienen que ver principalmente con el uso de la aplicación. Pruebas de accesibilidad: Se comprueba el cumplimiento de estándares de accesibilidad, tales como la Iniciativa de Accesibilidad Web (WAI) del World Wide Web Consortium (W3C). Pruebas de compatibilidad: Se comprueba el correcto funcionamiento de la aplicación en diferentes entornos (navegadores web, sistemas operativos o dispositivos), pues el software puede presentar errores dependiendo de dónde se ejecute; p. e., botones o enlaces pueden dejar de funcionar, interfaces graficas pueden descuadrarse, etc. 10.2 – Pruebas de sistema: herramientas Para las pruebas de sistema se pueden usar herramientas tales como: Analizadores de cobertura: fija la extensión de la cobertura obtenida en las pruebas de aceptación. Analizadores de tiempos: informa del tiempo empleado en varias regiones del código fuente. Normalmente se cumple el principio de Pareto: el programa estará el 80% del tiempo de ejecución en el 20% del código; este 20% deberá tener pues un buen rendimiento. Verificadores de estándares de codificación, que inspeccionarán el código para ver si se aparta del cumplimiento de estándares. 10.3 – ¿Cómo finalizan las pruebas de sistema en el proceso de desarrollo del software? Con las siguientes pruebas: Pruebas de aceptación. Consisten en pruebas de sistema que pretenden demostrar que el producto software construido satisface las necesidades establecidas en el documento de requisitos. Suelen realizarlas los grupos independientes y los clientes. Pruebas Alfa (α) y Beta (β). Son pruebas de caja negra, en las que el que utiliza el programa es el cliente. Pruebas α. Un cliente usa el programa en la empresa donde se está programando. El encargado del proyecto revisa su uso, y registra sugerencias, errores y mejoras posibles para el proyecto. Es una prueba en un entorno controlado. Pruebas β. Uno o varios clientes usan la aplicación en el lugar de trabajo para el que se ha diseñado. Los clientes son los que van anotando los fallos, sugerencias, mejoras, para que el equipo de desarrollo los solucione. Es una prueba en un entorno no controlado. 11 – DOCUMENTACIÓN DE LAS PRUEBAS El Plan de Pruebas prescribe varias clases de actividades que se realizarán para demostrar que el producto de programación cumple con sus requisitos; describe los objetivos de las pruebas, los criterios de aprobación, el plan de integración (estrategia, calendario, personal responsable), las herramientas particulares y las técnicas a utilizar, así como los casos reales y los resultados esperados. Los documentos relacionados con el diseño de las pruebas son: Plan de pruebas maestro: Proporciona un documento global de planificación y gestión de las pruebas (ya sea dentro de un proyecto o en varios proyectos). Plan de pruebas: Señala el enfoque, los recursos y el esquema de actividades de prueba, así como los elementos a probar, las características, las actividades de prueba, el personal responsable y los riesgos asociados. Especificación del diseño de pruebas: Detalla los casos de prueba y los resultados esperados, así como los criterios de aprobación de pruebas. Especificación de caso de prueba: Especifica los datos de prueba a usar en la ejecución de los casos de prueba identificados en la especificación del diseño de las pruebas. Especificación de procedimiento de prueba: Detalla cómo ejecutar cada prueba, incluyendo condiciones previas de configuración y los pasos que se deben seguir Los documentos más significativos relacionados con la ejecución de las pruebas son: Histórico de pruebas: Provee un registro cronológico de los datos pertinentes sobre la ejecución de las pruebas; por ejemplo, grabación de los casos de prueba realizados, quién los ejecutó, en qué orden, si cada test se superó o falló, etc. Informe de anomalía: Documenta cualquier incidente ocurrido en las pruebas y que requiera de una investigación. Este documento se denomina deliberadamente informe de anomalía, y no informe de fallo; la razón es que una discrepancia entre los resultados esperados y los reales puede ocurrir por razones distintas de un fallo en el sistema. Informe resumen de pruebas: Resume los resultados de las actividades de prueba y aporta evaluaciones y recomendaciones basadas en dichos resultados una vez finalizada la ejecución de las pruebas. Informe de pruebas maestro: Resume los resultados de las actividades de prueba y aporta evaluaciones. Este documento final se utiliza para indicar si el sistema de software bajo prueba ha cumplido los criterios de aceptación definidos por los participantes del proyecto. 12 – HERRAMIENTA DE TESTING (JUNIT) JUnit es un framework que permite realizar test repetibles (pruebas de regresión), es decir, que puede diseñarse un test para un programa o clase concreta y ejecutarlo tantas veces como sea necesario. La ventaja es que puede (o mejor, debe) ejecutarse el test cada vez que se modifique o cambie algo del código y verificar si el programa sigue funcionando correctamente tras los cambios. Para usar JUnit será necesario descargar sus librerías. Podemos hacer uso de Maven para ello. La última versión de JUnit es JUnit5 (Jupiter) para hacer uso de esta versión desde un proyecto Maven, habrá que añadir al pom.xml 12.1 – ¿Para qué sirve Junit? Características de los test unitarios Junit sirve para crear test unitarios. Los tests unitarios prueban las funcionalidades implementadas en el SUT (System Under Test). Si somos desarrolladores Java, para nosotros el SUT será la clase Java. Los tests unitarios deben cumplir las siguientes características: Principio FIRST ✓ Fast: Rápida ejecución. ✓ Isolated: Independiente de otros test. ✓ Repeatable: Se puede repetir en el tiempo. ✓ Self-Validating: Cada test debe poder validar si es correcto o no a sí mismo. ✓ Timely: ¿Cuándo se deben desarrollar los test? ¿Antes o después de que esté todo implementado? Además, podemos añadir estos tres puntos más: ·Sólo pruebas los métodos públicos de cada clase. ·No se debe hacer uso de las dependencias de la clase a probar. Esto quizás es discutible porque en algunos casos donde las dependencias son clases de utilidades y se puede ser menos estricto. Se recomienda siempre aplicar el sentido común. ·Un test no debe implementar ninguna lógica de negocio (nada de if...else...for...etc) Los tests unitarios tienen la siguiente estructura: Preparación de datos de entrada. Ejecución del test. Comprobación del test (assert). No debería haber más de 1 assert en cada test 12.2 – Test en Junit JUnit es un framework Java para implementar test en Java. Se basa en anotaciones: @Test: indica que el método que la contiene es un test. @RepeatedTest: Indica que el siguiente método será llamado las veces que la etiqueta recibe como parámetro. En el caso del ejemplo 2 @BeforeEach: Indica que el siguiente método es llamado antes de ejecutar cada una de las pruebas etiquetadas con @Test, @Repeatedtest o @ParameterizedTest. @AfterEach: Indica que el siguiente método es llamado después de ejecutar cada una de las pruebas etiquetadas con @Test, @Repeatedtest o @ParameterizedTest @BeforeAll: Indica que el siguiente método es llamado una sola vez en toda la ejecucion del programa. A continuación, son llamadas las pruebas etiquetadas con @Test, @Repeatedtest o @ParameterizedTest @AfterAll: Indica que el siguiente método es llamado una sola vez en toda la ejecucion del programa. Antes habrán sido llamadas todas las pruebas etiquetadas con @Test, @Repeatedtest o @ParameterizedTest. @Disabled: evita la ejecución del test. No es muy recomendable su uso porque puede ocultar test fallidos. Si dudamos si el test debe estar o no, quizás borrarlo es la mejor de las decisiones. @ParameterizedTest y @ValueSource. Permite pasar al método de prueba parámetros a utilizar en la ejecución. Se lanza una vez por parámetro pasado. 12.3 – Asserts Las condiciones de aceptación del test se implementan con los asserts. Se encuentran en la clase Assertions y los más comunes son los siguientes: assertTrue/assertFalse (condición a testear): Comprueba que la condición es cierta o falsa. assertEquals/assertNotEquals (valor esperado, valor obtenido). Es importante el orden de los valores esperado y obtenido. assertNull/assertNotNull (object): Comprueba que el objeto obtenido es nulo o no. assertSame/assertNotSame(object1, object2): Comprueba si dos objetos son iguales o no. 12.4 – Hacer cosas en Junit Para empezar, creando una clase de test, deberemos crear una estructura para añadir los test, como estamos usando Maven, los proyectos por defecto con nave te generan un paquete para incorporar los tests. Una vez creado el paquete donde se incorporarán todos los test, estos deberán estar en la misma ruta que la clase. Una vez hecho esto crearemos una clase de test, con el mismo nombre que la clase a probar, pero acabada en Test. La forma de verificar que se lanza una excepción ha cambiado con JUnit5, y ahora se usa una lambda para su correcta verificación. @DisplayName es una anotación en JUnit que se utiliza para asignar un nombre personalizado a un método de prueba. Esto es útil para proporcionar nombres más descriptivos y legibles a los métodos de prueba. Una vez creado el test, para ejecutarlo podemos usar el IDE eclipse, para ello pulsamos con el botón derecho en la clase y con el ratón pulsamos en Run As > Junit Test. Si queremos hacer un debug, pulsaremos en Debug as > Junit Test Por otro lado, como estamos con un proyecto Maven, podemos ejecutar todos los tests con Maven, simplemente ejecutando un clean compile package 12.5 – Cobertura de código La cobertura de código (coverage) es una medida porcentual en las pruebas de software que mide el grado en que el código fuente de un programa ha sido comprobado. Para ello haremos lo siguiente, en la clase de Test pulsaremos con el botón derecho y seleccionaremos la opción Coverage As > Junit Test. También podemos pulsar en Run > Coverage As > Junit Test. Con esto podremos ver el porcentaje de cobertura de código que tenemos y visualmente que código está testeado (verde) y que código no está testeado (rojo). La cobertura de código nos da un índice de que código está probado, pero no nos dice si las pruebas realizadas son las correctas o no. 13 – CALIDAD DEL SOFTWARE Para evaluar el software, es necesario contar con criterios adecuados que permitan analizar el software desde diferentes puntos de vista. Las pruebas de carga se realizan sobre el sistema simulando una serie de peticiones esperadas o un número de usuarios esperado trabajando de forma concurrente, realizando un número de transacciones determinado. En estas pruebas, se evalúan los tiempos de respuesta de las transacciones. Generalmente, se realizan varios tipos de carga (baja, media y alta) para evaluar el impacto y poder graficar el rendimiento del sistema. Otro tipo de pruebas son las pruebas de estrés en las que la carga va elevándose más y más para ver cómo de sólida es la aplicación y cómo se maneja ante un número de usuarios y transacciones extremos. También existen otros tipos de pruebas como las pruebas de estabilidad donde se somete de forma continuada al sistema a una carga determinada o bien pruebas de picos donde el volumen de carga va cambiando. 13.1 – Criterios de calidad del software - Número de errores por un número determinado de líneas de código. - Número de tiempo que la aplicación estará dando servicio. - Número medio de revisiones realizadas a una función o módulo de programa. 13.2 – Métrica calidad del software Tolerancia a errores. Facilidad de expansión. Mide la facilidad con la que pueden añadírsele nuevas funcionalidades a un software concreto. Independencia de plataforma del hardware. Cuanto mayor sea el número de plataformas donde pueda ejecutarse un software, mejor. Modularidad. Número de componentes independientes de un programa. Estandarización de los datos. Se evalúa si se utilizan estructuras de datos estándar a lo largo de un programa. 14 – CALIDAD DEL CÓDIGO 14.1 – Ejes de calidad del código Tener líneas de código duplicado (“Duplicated code”). No respetar los estándares de codificación y las mejores prácticas establecidas (“Coding standards”). Tener una cobertura baja (o nula) de pruebas unitarias, especialmente en partes complejas del programa (“Unit tests”). Tener componentes complejos y/o una mala distribución de la complejidad entre los componentes (“Complex code”). Dejar fallos potenciales sin analizar (“Potential bugs”). Falta de comentarios en el código fuente, especialmente en las APIs públicas (“Comments”). Tener el temido diseño spaghetti, con multitud de dependencias cíclicas (“Design and architecture”) 14.2 – sonarqube SonarQube (conocido anteriormente como Sonar) es una plataforma para evaluar código fuente. Funciones Informa sobre código duplicado, estándares de codificación, pruebas unitarias, cobertura de código, complejidad ciclomática, etc. Aunque pensado para Java, acepta otros lenguajes mediante extensiones. Se integra con Maven, Ant y herramientas de integración continua como Atlassian Bamboo, Jenkins y Hudson.