Únase a nosotros el 30 de abril: Presentación de la prueba CT de Parasoft C/C++ para pruebas continuas y excelencia en el cumplimiento | Regístrese ahora

Por qué los stubs en las pruebas unitarias mejoran las pruebas de integración

Foto de cabeza de Miroslaw Zielinski, director de gestión de productos de Parasoft
Sábado, Abril 24, 2023
6 min leer

Si ha tenido problemas para agregar stubs a sus pruebas, así es como una opción especial para stubs en Parasoft C/C++test puede facilitarle la generación de stubs automáticos o de usuario.

Un importante e influyente cliente nuestro, que trabajaba en un proyecto crítico para la seguridad que se estaba desarrollando de acuerdo con la norma de seguridad funcional IEC 61508, se puso en contacto con nosotros. Solicitaron orientación para optimizar la productividad de sus desarrolladores al reducir aún más el ruido generado por las pruebas unitarias, el ruido producido por la falta de stubing.

Aprendimos que la forma en que nuestro cliente realizaba sus pruebas unitarias se acercaba más a las pruebas de integración. En su proceso, las unidades a probar no se aislaron de sus componentes dependientes (otros archivos o funciones del proyecto), y los casos de prueba unitaria se ejecutaron contra la mayoría de las aplicaciones completadas.

Tal enfoque no es una prueba unitaria clásica. Se conoce comúnmente como prueba de nivel de integración. Las pruebas de integración son muy eficientes para demostrar una buena cobertura de pruebas para requisitos funcionales y no funcionales. También puede proporcionar una excelente cobertura de prueba si la cobertura de código estructural está habilitada.

¿Qué son los talones en las pruebas?

Prueba unitaria se trata más de aislar la función, el método o el procedimiento, también conocido como una unidad. Este aislamiento se realiza eliminando las dependencias y forzando rutas de ejecución específicas.

Los resguardos toman el lugar del código en la unidad que depende del código fuera de la unidad. También proporciona al desarrollador o probador la capacidad de manipular la respuesta o el resultado del stub para que la unidad se pueda ejercitar de varias maneras y para diversos propósitos, por ejemplo, para garantizar que la unidad funcione de manera confiable, sea segura y, en algunos casos, también está libre de vulnerabilidades de seguridad.

¿Por qué se usan los talones?

La mejor manera de explicar por qué se usan los stubs y el valor que aportan es repasando un caso de uso. Eche un vistazo al siguiente código, por ejemplo.

Captura de pantalla del código para un caso de prueba de unidad que muestra una declaración "si" que prueba si el búfer para muestras se asignó correctamente

Al comienzo de la función, hay una instrucción if que prueba si el búfer para las muestras se asignó correctamente. La mayoría de los casos de prueba para esta función se implementaron sin stubs, ya que se centran 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 el allocateSampleBuffer función para simular la falla.

Una vez que se agrega el código auxiliar, se aplicará de manera consistente al código probado. Un usuario que trabaje en el caso de prueba de "fallo de asignación" tendrá una manera fácil de instalar una función de devolución de llamada especial en el stub, que simulará el efecto deseado: falla de asignación o no hacer nada, ya que de forma predeterminada el stub devuelve un puntero nulo, que es esperado 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 dedicar más tiempo a 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.

Uso de stubs en pruebas unitarias de código C y C++

Parasoft C / C ++test hace que sea mucho más fácil generar automáticamente stubs o crear manualmente stubs. La opción está disponible en dos lugares:

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

Captura de pantalla que muestra el cuadro de selección de stubs generados automáticamente en Parasfot C/C++test con Enable Stub Callbacks e Insert call to original function seleccionado.

Para stubs de usuario y stubs automáticos: Panel de configuración de stubs de la Vista de stubs

Captura de pantalla de Parasoft C/C++test show Stub settings

 

 

 

 

Captura de pantalla que muestra la ubicación de salida de los stubs generados automáticamente por Parasoft C/c++test

Con la opción "Insertar llamada a la función original" marcada, Parasoft C / C ++test cambia la forma predeterminada en que se generan los stubs. El cambio está 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 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. 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, como un puntero nulo o un valor numérico cero.

Cuándo usar talones

Para asegurarnos de que la diferencia sea clara, comparemos la situación con la opción "Insertar llamada a la función original" habilitada y no habilitada 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 la opción “Insertar llamada a la función original”. Funciona de la siguiente manera:

Captura de pantalla en la prueba de Parasoft C/C++ que muestra un código auxiliar generado para la función goo sin la opción "Insertar llamada a la función original".

 

 

 

 

 

Así es como busca el mismo código auxiliar generado para goo función  la opción "Insertar llamada a la función original" marcada:

Captura de pantalla de la prueba Parasoft C/C++ que muestra un código auxiliar generado para la función goo, con la opción "Insertar llamada a la función original" marcada.

Como puede ver, los stubs agregados con la nueva opción son transparentes para el código probado. 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.

Diferencias entre Stubs, Mocks, Spies, Drivers y Dummies

Hay varios dobles de prueba que puede aplicar a los casos de prueba unitaria al probar el software. En las pruebas integradas en tiempo real del código C y C++, como se muestra en esta publicación de blog, los equipos usan stubs y simulacros como mecanismos dobles de prueba.

Para probar aplicaciones web y en la nube que usan Java, C#, VB.NET u otros lenguajes, los equipos pueden aplicar muchos tipos de dobles de prueba, incluidos stubs, simulacros, espías, dummies y controladores.

  • Trozos son pequeños fragmentos de código que ocupan el lugar de otro componente durante la prueba. El beneficio de usar un talón es que devuelve resultados y respuestas enlatados, lo que hace que la prueba sea más fácil de escribir. Puede ejecutar sus pruebas incluso si el otro componente aún no funciona.
  • Simulacros son una pieza de código con comportamiento programado que toma el lugar de otro componente de código durante la prueba. Un simulacro es un trozo más inteligente. Los simulacros, en cierto modo, se determinan en tiempo de ejecución, ya que el código que establece las expectativas debe ejecutarse antes de que haga algo.
  • Spies, a veces denominados simulacros parciales, registran información en función de cómo se llamó. Por ejemplo, un servicio de correo electrónico que registra la cantidad de mensajes que se envió.
  • Dummies son objetos que se pasan de un lado a otro pero nunca se usan. Ayudan a completar los parámetros obligatorios, como en un constructor, pero no tienen efecto en su prueba.
  • Drivers son de implementación compleja y se utilizan cuando el software necesita interactuar con un sistema externo. Se usan más comúnmente para pruebas de integración.

¿Qué son las limitaciones y los desafíos de los talones?

En los casos en que no hay una definición original disponible para una función auxiliar, ¿qué sucede? ¿Cómo se comporta el stub sin una devolución de llamada que defina el comportamiento alternativo?

La belleza de C/C++test es que detecta automáticamente este tipo de situación. El stub se reconfigurará solo durante el tiempo de construcción del arnés de prueba. No llamará a la definición original cuando no haya una devolución de llamada instalada y devolverá un valor predeterminado seguro.

Stubs en pruebas de integración: un ejemplo y resumen

La prueba C/C++ reduce en gran medida la cantidad de interferencia entre los diferentes miembros del equipo cuando se trabaja simultáneamente en los casos de prueba en este tipo de prueba de semiintegració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 auxiliar para uno de los casos de prueba, puede crear una función de devolución de llamada específica del caso de prueba que implemente la lógica alternativa deseada para la función auxiliar e instalar esta devolución de llamada en el código auxiliar existente como una parte de la configuración del caso de prueba.

Aprenda a optimizar las pruebas unitarias para sistemas integrados y críticos para la seguridad.