Seminario web destacado: MISRA C++ 2023: todo lo que necesita saber | Vea ahora

El valor de utilizar una herramienta de prueba unificada de C / C ++

Foto de cabeza de Miroslaw Zielinski, director de gestión de productos de Parasoft
17 de abril de 2023
8 min leer

El entorno más efectivo para las pruebas de desarrollo es uno con una solución de prueba unificada que esté profundamente integrada en el IDE del desarrollador. Por ejemplo, los equipos pueden concentrar las pruebas en el código que se actualizó más recientemente y que presenta un alto riesgo gracias a una herramienta centralizada como Parasoft C/C++test.

Una solución de pruebas unificada con una profunda integración en el IDE del desarrollador proporciona el entorno más productivo para las pruebas de desarrollo. Una herramienta unificada, como Parasoft C/C++test, permite a los equipos centrar sus pruebas en código de alto riesgo y modificado recientemente.

Verificación y validación de software es una parte inherente del desarrollo de software. El esfuerzo y el presupuesto invertidos en proyectos de V&V particulares dependen de muchos factores, como los objetivos de seguridad funcional de un proyecto, el nivel de riesgo comercial o la cultura de calidad de una organización. Independientemente de lo que impulse a una organización a implementar iniciativas y procesos de calidad, se necesita más que determinación para producir productos de software seguros y de alta calidad.

Elegir las metodologías de prueba adecuadas es una tarea desafiante por muchas razones. La tecnología está evolucionando a un ritmo rápido y las empresas deben elegir qué herramientas de prueba de software adoptar. En muchos casos, también es difícil elegir entre productos de código abierto y comerciales.

Esta publicación explica cómo se pueden combinar las técnicas de prueba automatizadas, como el análisis estático avanzado, el monitoreo de la memoria en tiempo de ejecución, la prueba unitaria automatizada y el análisis de flujo, para mejorar los procesos de control de calidad e identifica los beneficios de implementar una solución de prueba unificada. Los conceptos discutidos aquí son genéricos y se pueden aplicar a cualquier lenguaje de programación, pero los ejemplos aquí tienen en mente los lenguajes de programación C y C++, creados usando Parasoft C / C ++test.

Clases de defectos y automatización de herramientas

Al pensar en posibles fallas de software de alto nivel, se pueden distinguir varias clases de errores de software: errores resultantes de requisitos faltantes, errores causados ​​por requisitos especificados incorrectamente y errores que ocurren porque los requisitos se han codificado incorrectamente. Las dos primeras clases de defectos de software entran en la categoría de ingeniería de requisitos y no se discutirán aquí. Me estoy centrando aquí en los errores causados ​​por una implementación incorrecta que incluye una amplia gama de posibles problemas de software con los que luchan muchos equipos.

Entonces, ¿qué significa que un requisito se haya codificado incorrectamente? Puede ser muchas cosas. Tomemos, por ejemplo, un requisito implementado incorrectamente: las pruebas unitarias diseñadas para verificar la implementación correcta fallan y las herramientas de automatización de pruebas detectan e informan el defecto. En otro ejemplo, una herramienta de análisis de tiempo de ejecución puede detectar un error crítico de acceso a la memoria durante una prueba de unidad que no se puede detectar solo a partir de los resultados de la prueba de unidad. Diferentes herramientas son mejores para detectar ciertas clases de errores, como se ilustra a continuación.

Figura 1. Defectos de software y panorama de estrategias de detección.

Obviamente, no todos los proyectos de software necesitan utilizar todas las tecnologías disponibles para probar y mejorar la calidad del software, y las organizaciones enfrentan el dilema de cómo equilibrar el presupuesto y la calidad. Es probable que los proyectos relacionados con la seguridad funcional seleccionen todas las tecnologías disponibles para garantizar una calidad absoluta, así como el cumplimiento de los estándares de seguridad del software, como ISO 26262. Otros equipos pueden decidir elegir solo análisis estático y pruebas unitarias, ya que parecen cubren una parte significativa de los defectos del software, mientras que algunos equipos pueden encontrar suficiente un marco de pruebas unitarias de código abierto.

La falta de voluntad para implementar una amplia gama de tecnologías de prueba a menudo se debe a la preocupación de que el uso de múltiples técnicas impone una sobrecarga significativa en el ritmo de desarrollo, sin mencionar el presupuesto. Es más probable que esto sea una preocupación real si los equipos deciden seleccionar herramientas no integradas. El costo de múltiples herramientas separadas, la curva de aprendizaje y la necesidad de cambiar entre diferentes modelos de uso e interfaces pueden ser problemáticos. Como resultado, los desarrolladores pueden evitar el uso de herramientas y automatización, ya que redirige su atención de la escritura de código al uso de herramientas, disminuyendo su productividad.

El valor de una solución de prueba unificada

Es importante especificar lo que se espera de una solución de prueba unificada antes de discutir su valor. Idealmente, una solución debería:

  • Admite múltiples tecnologías de prueba
  • Sea fácil de usar
  • Detectar problemas funcionales y regresiones.
  • Proporcionar trazabilidad desde los requisitos hasta las pruebas.
  • Mida la complejidad, portabilidad y capacidad de mantenimiento del código.
  • Eduque a los desarrolladores proporcionando comentarios instantáneos mientras escriben el código
  • Proporcionar información sobre el progreso del desarrollo.
  • Combinar resultados de diferentes técnicas para análisis avanzados

Una solución de prueba unificada e integrada ayuda a evitar una serie de problemas:

  • Múltiples curvas de aprendizaje y problemas de usabilidad con el uso de herramientas independientes con diferentes interfaces.
  • Distraer a los desarrolladores de escribir código
  • Impedir el intercambio de información entre diferentes elementos de una cadena de herramientas
Documento técnico: El valor de utilizar una herramienta de prueba unificada de C / C ++

Detecte tantos defectos como sea posible

Los defectos de software se dividen en diferentes categorías, por lo que no se puede esperar que todos ellos sean identificados por una técnica de prueba. Por ejemplo, pruebas manuales a nivel del sistema. Para proporcionar un ejemplo más concreto, observe el siguiente fragmento de código de ejemplo:

Las pocas líneas de código anteriores contienen varios problemas. Específicamente, en la línea 16, el desarrollador está intentando inicializar el búfer global usando el valor de índice calculado en el calcularIdx () función, pero no validan si está dentro del rango permitido. Incluso si se ejecutan docenas de sesiones de prueba manuales, es posible que no revelen este problema, ya que escribir un valor entero en una ubicación de memoria aleatoria rara vez produce un efecto espectacular de inmediato.

Pero un día, muy probablemente después del lanzamiento, el diseño de la memoria puede cambiar y la operación de la línea 16 bloquea la aplicación. Curiosamente, el análisis estático también puede fallar en señalar este problema debido al ciclo que se usa para calcular el índice. Por razones de rendimiento, el análisis de flujo de datos y control utilizado en las herramientas de análisis estático debe aplicar heurísticas y simplificaciones para finalizar el análisis de código en un tiempo razonable, y es común aplicarlas en bucles, lo que significa que se pueden pasar por alto algunos errores.

Una herramienta de monitoreo de memoria, que instrumenta el código fuente mediante la inyección de controles especiales y reporta operaciones de memoria incorrectas, seguramente detectará este error. Las herramientas de análisis en tiempo de ejecución detectan problemas de software solo en las rutas que se ejecutan realmente, sin hacer conjeturas, una gran ventaja sobre el análisis estático, ya que la precisión de los problemas informados es muy alta.

En este ejemplo, la detección de errores de memoria de Parasoft identificó fácilmente el problema:

Una situación inversa es igualmente posible: el análisis estático puede detectar problemas que la supervisión de la memoria en tiempo de ejecución no puede identificar. Por ejemplo, existe la posibilidad de que se elimine la referencia de un puntero nulo en la línea 27/28 en el fragmento de código siguiente. llamando al almacenarPersonaAArchivo funcionar con el persona que el argumento del puntero sea nulo provoca un error, pero esto ocurre solo si el recuperarPersonaDeDB la función devuelve nulo. Tal condición es poco probable durante las sesiones de prueba del sistema, porque la conexión de la base de datos probablemente funciona como se esperaba, por lo que las herramientas de monitoreo de la memoria en tiempo de ejecución permanecen en silencio. Sin embargo, el análisis de flujo dentro de la herramienta de análisis estático detecta fácilmente el puntero nulo que se devolverá desde esta función e informa de un posible problema de desreferenciación de puntero nulo.

Figura 4. Ejemplo de resultados de análisis estático.

Detectar problemas funcionales y regresiones

¿Qué pasa con el código que siempre se ejecuta sin problemas, pero no cumple con los requisitos? Análisis estático y dinámico no son útiles para identificar este tipo de problemas. La detección de discrepancias entre el resultado esperado y el resultado real requiere una comparación de los resultados del cálculo con valores predefinidos. Existen muchas formas populares de implementar dichas comprobaciones, incluidas las pruebas manuales a nivel del sistema, las pruebas de integración y las pruebas unitarias.

Hay muchas áreas en las que una solución de prueba unificada puede facilitar el proceso de prueba unitaria. La lista de beneficios incluye:

  • Aumenta la productividad del desarrollador al crear casos de prueba, por ejemplo, al proporcionar asistentes gráficos para crear, editar y configurar casos de prueba.
  • Se integra con Prueba doble Frameworks, lo que permite una fácil simulación y creación de apéndices para simular escenarios de prueba complejos, sin involucrar grandes bases de código.
  • Correlaciona casos de prueba con informes de cobertura de código para evaluar la integridad de las pruebas.
  • Optimiza las sesiones de prueba calculando automáticamente el conjunto mínimo de casos de prueba necesarios para verificar el código delta.
  • Combina informes de cobertura de código de otras técnicas de prueba, como pruebas manuales/a nivel de sistema o pruebas de integración para identificar código no probado.
  • Rastrea los resultados hasta los requisitos para una mejor comprensión del impacto de las pruebas fallidas.

La creación de pruebas con asistentes gráficos o editores puede aumentar la productividad de toda una organización al involucrar a los equipos de control de calidad en el proceso de redacción de pruebas unitarias, lo que los hace contribuir activamente al proceso de desarrollo. Es más fácil para los miembros del equipo de control de calidad usar asistentes gráficos que escribir el código de prueba apropiado en los editores de código, ya que la configuración de valores mediante formularios de entrada (como se muestra a continuación) no requiere habilidades de codificación avanzadas y requiere menos tiempo, especialmente si los miembros del equipo carecen de experiencia. . Por ejemplo, la captura de pantalla a continuación muestra un ejemplo de la capacidad de prueba unitaria de la prueba de Parasoft C / C ++ para C / C ++, un asistente que ayuda con la creación de la prueba unitaria.

Otro beneficio de usar una solución de prueba unificada es la retroalimentación que proporciona sobre la integridad de las pruebas y el estado de salud de los requisitos comerciales críticos. Números bajos en el MC / DC El informe de cobertura puede indicar una cobertura de sucursal insuficiente, incluso si el informe de cobertura del estado de cuenta muestra valores altos. Este tipo de análisis requiere una cadena de herramientas que admita múltiples métricas de cobertura, lo que permite a los equipos comenzar con algo simple, como la cobertura de línea o declaración, y avanzar hacia una cobertura de código más completa a medida que avanzan en la mejora de sus casos de prueba.

Requisitos para probar la trazabilidad

Prueba unitaria y los informes de cobertura de pruebas del sistema son excelentes fuentes de información sobre el proceso de prueba, especialmente cuando se combinan. Pero si los resultados de las pruebas no se correlacionan con los requisitos, los equipos carecen de varias piezas de información crítica. Al ver un informe de trazabilidad de pruebas a requisitos, puede determinar rápidamente el estado de la cobertura de requisitos. A continuación se muestra un ejemplo de dicho informe:

La capacidad de correlacionar los requisitos con los resultados de diferentes tipos de pruebas es una gran ventaja de utilizar una solución de pruebas unificada. Las pruebas unitarias, las pruebas del sistema, los resultados de las pruebas de integración, así como los estándares de codificación y los resultados de las métricas de código se pueden correlacionar para proporcionar comentarios sobre el estado de los requisitos críticos y no críticos.

Combinar resultados de diferentes técnicas para análisis avanzado

Cuando combina datos de las diversas técnicas de prueba utilizadas en un proyecto, puede obtener métricas de segundo nivel y análisis más sofisticados. El uso de una solución de prueba unificada permite a los equipos ver el código desde una perspectiva completamente nueva. Un caso de prueba unitaria fallida puede tener un significado diferente para un desarrollador, dependiendo de si ocurre en un código clasificado como de alto o bajo riesgo por análisis de métricas de código. Si esta información se combina con las estadísticas del control de código fuente y se correlaciona con los requisitos, los equipos pueden tomar mejores decisiones sobre cuándo y cómo se debe corregir el código.

Con el conjunto de herramientas de Parasoft, puede aprovechar las pruebas basadas en cambios para mejorar la productividad del equipo. La tecnología de prueba basada en cambios captura la relación entre el código fuente, los casos de prueba y los resultados de cobertura de código para calcular el conjunto óptimo de casos de prueba para la verificación y validación de un delta de código específico. En efecto, los equipos pueden limitar sus sesiones de prueba ejecutando solo un pequeño subconjunto de pruebas en lugar de conjuntos completos de regresión. Este enfoque en solo probar lo que es absolutamente necesario se traduce en ahorros significativos, especialmente para proyectos de tamaño mediano o grande.

Poniendo todo junto: Parasoft C/C++test & DTP

Todas las tecnologías de prueba discutidas anteriormente están disponibles en Parasoft C / C ++test y  DTP de Parasoft. Parasoft C/C++test es una solución de prueba unificada para proyectos C y C++. C/C++test está disponible como complemento para IDE populares, como Eclipse y Visual Studio. La estrecha integración con el IDE evita los problemas discutidos anteriormente.

Los desarrolladores pueden ejecutar instantáneamente verificaciones de cumplimiento de estándares de codificación o ejecutar pruebas unitarias al momento de escribir el código. Los miembros del equipo de control de calidad pueden realizar escenarios de prueba manuales mientras se supervisa la aplicación para detectar errores de tiempo de ejecución y cobertura de código. Los análisis fuera de línea, como el análisis de flujo proporcionado por el análisis estático, se pueden realizar en la fase de integración continua.

Las sesiones del servidor, compatibles con una conveniente interfaz de línea de comandos, informan los resultados del análisis a Parasoft DTP, que agrega información del entorno de desarrollo. Parasoft DTP brinda amplias capacidades de generación de informes, incluida la capacidad de integrar datos de herramientas de terceros, enviar resultados de pruebas a los IDE de los desarrolladores y calcular análisis avanzados. La retroalimentación continua proporcionada en cada fase del flujo de trabajo acelera el desarrollo ágil y reduce el costo de lograr el cumplimiento de los estándares de seguridad.

También debe tenerse en cuenta que el enfoque de los procesos y la arquitectura de garantía de calidad que se analizan aquí no se limita a los proyectos C / C ++. Parasoft ofrece soluciones similares para Java y  C # /. NET.

Conclusión

La mejora de la calidad del software no es un esfuerzo homogéneo y requiere diferentes tecnologías para erradicar diferentes tipos de defectos de software. El desafío clave es cómo hacerlo de una manera eficaz y eficiente que evite devastar los presupuestos de los proyectos y socavar la moral de los desarrolladores.

Una solución de pruebas unificada con una profunda integración en el IDE del desarrollador proporciona el entorno más productivo para las pruebas de desarrollo. Una herramienta unificada, como Parasoft C/C++test, con su capacidad para unificar métricas y resultados de todos los aspectos de las pruebas, proporciona un beneficio adicional al permitir que los equipos centren sus pruebas en código de alto riesgo y modificado recientemente.

Pruebe la prueba Parasoft C / C ++: una solución de prueba unificada y totalmente integrada para el desarrollo de software C / C ++.