X
BLOG

Uso de stubs en pruebas de nivel de integración

Uso de stubs en pruebas de nivel de integración Tiempo de leer: 4 minutos
Hace varios meses, uno de nuestros grandes clientes, que trabajaba en un proyecto crítico para la seguridad que se estaba desarrollando de acuerdo con IEC 61508, se puso en contacto con nosotros para pedirnos ayuda para optimizar la productividad de los desarrolladores. El problema al que se enfrentaba el cliente se debía a la cantidad de ruido en los resultados de la prueba generada por los desarrolladores que trabajaban simultáneamente en casos de prueba de unidades y configuraban stubs para las necesidades de sus escenarios de prueba específicos.

Aprendimos que la forma en que nuestro cliente estaba realizando sus pruebas unitarias está más cerca de las pruebas de integración. En su proceso, las unidades probadas no están aisladas de los componentes dependientes (otros archivos en el proyecto), y los casos de prueba unitaria se ejecutan contra la aplicación casi completa, por lo que todas las llamadas entre funciones en los proyectos se conectan exactamente de la misma manera durante las pruebas unitarias como en la producción se construye.

Este enfoque no es una prueba de unidad "clásica", ya que se basa mucho en las pruebas de nivel de integración. Aún así, es muy eficiente para demostrar una buena cobertura de prueba para los requisitos y el código fuente.

En este proceso, los stubs se agregan solo cuando se debe simular un escenario de prueba específico, generalmente una inyección de falla. Tomemos, por ejemplo, el siguiente código:

Al comienzo de la función, hay una instrucción if que prueba si el búfer para muestras se asignó correctamente. La mayoría de los casos de prueba para esta función se implementaron sin ningún código auxiliar, ya que están enfocados en el flujo de control "regular", excepto el caso de prueba, que verifica el comportamiento de la función cuando falla la asignación del búfer. Este caso de prueba requiere un código auxiliar para la función allocateSampleBuffer para simular el error.

Una vez que se agrega el código auxiliar, se aplicará de manera consistente para el código probado. Un usuario que trabaje en el caso de prueba de "falla de asignación" tendrá ahora una manera fácil de instalar una función especial de devolución de llamada en el código auxiliar, que simulará el efecto deseado (error de asignación o no hará nada, ya que el código auxiliar predeterminado devuelve un puntero nulo que se espera para el caso de prueba). Pero todos los demás casos de prueba requieren atención en este momento porque se debe agregar una configuración de stub para evitar cambios no deseados en el flujo de control.

Por supuesto, los desarrolladores pueden volver atrás y reconfigurar su caso de prueba para tener en cuenta el código auxiliar, pero significa tiempo adicional para analizar el motivo de la falla, preparar una función de devolución de llamada dedicada para el código auxiliar y eliminar el ruido en el proceso de prueba, que fue la principal preocupación del cliente cuando se puso en contacto con nosotros.

Así que agregamos una opción especial para stubs en Parasoft C / C ++testLa versión 10.4.3 que hace que sea mucho más fácil generar stubs automáticos o de usuario. La nueva opción está disponible en dos lugares:

  • Para stubs generados automáticamente: Configuración de prueba -> Ejecución -> Símbolos (pestaña)

  • Para stubs de usuario (y también para stubs automáticos): Panel de configuración de stubs de la vista Stubs

Con la "Insertar llamada a la función original" opción marcada, Parasoft C / C ++test cambia la forma predeterminada en que se generan los stubs. El cambio se produce en un comportamiento de código auxiliar cuando no se instala ninguna devolución de llamada. El stub generado con la nueva opción actuará como un proxy y llamará a la definición de función original a menos que el usuario proporcione una función de devolución de llamada específica del caso de prueba que esté destinada a realizar actividades alternativas. Los códigos auxiliares generados sin la nueva opción (incluidos los códigos auxiliares heredados) no intentarán llamar al símbolo original en la situación predeterminada, y si no hay una función de devolución de llamada específica del caso de prueba instalada, el código auxiliar no hará nada y solo devolverá un "valor predeterminado ”Valor, como un puntero nulo o un valor numérico cero.

Para asegurarme de que la diferencia sea clara, permítame comparar rápidamente la situación con la "Insertar llamada a la función original" opción habilitada y sin ella, para el caso en que el usuario no proporcionó una devolución de llamada dedicada:

  • Aquí hay un código auxiliar generado para goo función, sin el "Insertar llamada a la función original" opción. Funciona de la siguiente forma:

  • Así es como busca el mismo código auxiliar generado para goo función, pero esta vez con que el  "Insertar llamada a la función original" opción marcada:

Como puede ver, los stubs agregados con la nueva opción son transparentes para el código probado y simplemente realizan la llamada de proxy a la definición original, a menos que alguien proporcione una devolución de llamada que implemente la acción alternativa deseada.

Es probable que un ingeniero experimentado haga una pregunta aquí como, “Ok, pero ¿qué sucede si no hay una definición original disponible para la función stubped? ¿Cómo se comporta el stub en este escenario cuando no proporciono una devolución de llamada que defina el comportamiento alternativo y no tengo una definición original disponible? "

Bueno, la belleza de esta nueva funcionalidad es que este tipo de situación se detecta automáticamente, y el stub se reconfigurará en el momento de la construcción del arnés de prueba, no para llamar a la definición original cuando no se instala ninguna devolución de llamada, sino para devolver un valor predeterminado seguro. valor.

Esta nueva funcionalidad reduce en gran medida la cantidad de interferencia entre diferentes miembros del equipo cuando se trabaja simultáneamente en los casos de prueba en este tipo de prueba de “semi-integración”. Un stub agregado por el desarrollador A no cambiará el comportamiento del código probado para los casos de prueba agregados por el desarrollador B. Si el desarrollador B decide que necesita configurar una acción alternativa para la función stubped para uno de los casos de prueba, simplemente puede crear una función de devolución de llamada específica del caso de prueba que implementa la lógica alternativa deseada para la función stubped e instala esta devolución de llamada en el stub existente como parte de la configuración del caso de prueba.

Pruebas de desarrollo unificadas para aplicaciones C y C ++

Escrito por

Miroslaw Zielinski

Gerente de producto para las soluciones de prueba integradas de Parasoft, las especialidades de Miroslaw incluyen C / C ++, RTOS, análisis de código estático, pruebas unitarias, gestión de la calidad del software para aplicaciones críticas de seguridad y cumplimiento del software con los estándares de seguridad.

Reciba las últimas noticias y recursos sobre pruebas de software en su bandeja de entrada.

Prueba Parasoft