Unidad de prueba de efectos secundarios-código pesado


10

Estoy empezando a escribir código C ++ para ejecutar un robot, y no sé cómo incorporar pruebas unitarias, si es que puedo. Se me ha proporcionado una biblioteca que permite la creación de "comandos" para el robot, que se programan y ejecutan automáticamente. El mecanismo para crear estos comandos es una subclase de una clase base de comandos que proporcionan, y poner en práctica virtuales void Initialize(), void Execute()y void End()métodos. Estas funciones se ejecutan únicamente por sus efectos secundarios, que le hacen cosas al robot (hacer funcionar motores, extender pistones, etc.). Debido a esto, realmente no veo ningún lugar para adjuntar pruebas unitarias al código, salvo burlarme de toda la biblioteca para poder verificar los estados virtuales antes y después del robot. ¿Hay alguna forma de probar esto que no sea demasiado gravoso?

Editar

Creo que podría haber estado engañando sobre la funcionalidad de la biblioteca. La biblioteca proporciona la mayor parte de la interfaz al robot, así como el sistema de comando / programación, por lo que no es tan simple como burlarse de la clase base del comando, tendría que burlarme de toda la interfaz al hardware. Lamentablemente, no tengo tiempo para hacer eso.


Supongo que puedes deshacer cualquier acción que hagas que haga tu robot, ¿verdad? ¿No puedes deshacer las acciones de tu prueba?
Neil

1
Es una lástima que la biblioteca no haya utilizado la composición en lugar de la herencia, porque podrías burlarte de la clase de comando si ese fuera el caso.
Robert Harvey

@Neil, no estoy muy seguro de lo que estás preguntando. ¿Puedes reformular tu pregunta?
Will Kunkel

Respuestas:


7

Lo que haría en este caso sería introducir mi propia interfaz RobotControl con métodos correspondientes a los de la biblioteca real.

Después de hacer esto, crearía una clase RobotControlImpl que implementa esta interfaz contra la lib real del robot.

Los comandos que escribiría en consecuencia no ampliarían la clase base, sino que operarían en la interfaz que usted introdujo.

De esta manera, puede burlarse de RobotControl, pasar el simulacro a cualquier comando y verificar que haya llamado a los métodos correctos en la interfaz.

En prod, pasaría la implicación real de RobotControl a los comandos que implementó.

¿No estoy seguro de si esto es lo que tenía en mente y consideraba engorroso?

Editar: Ah, y si espera que los comandos se suspendan para esperar su finalización (pesadilla, pero a veces esto es lo que tiene), requeriría que los comandos llamen a un método de suspensión en RobotControl. De esta forma, puede deshabilitar los durmientes durante la prueba y simplemente verificar que el comando intente dormir.


2
+1. ¿No te gusta la interfaz? Haz lo tuyo.
Neil

Parece que estás sugiriendo que me burlo de toda la biblioteca. Casi todas las funciones a las que llamarán los comandos son internas de la biblioteca.
Will Kunkel

0

Creo que es posible hacer que el código sea comprobable de una manera mínimamente invasiva. Con eso quiero decir que puede escribir los comandos exactamente como lo pretenden los autores de la biblioteca de robots. Esto puede ser ventajoso si desea intercambiar código con otros que no están utilizando su capa intermedia.

Requiere una "construcción de prueba unitaria" separada de su código.

Lo que debe hacer es que, en un archivo de encabezado central, verifique que el tiempo de compilación defina si esta es la compilación de prueba unitaria y, de ser así, redefine el nombre de la clase base, y tal vez algunas otras clases en la biblioteca del robot a nombres de clases de su implementación de prueba. Debe definir las mismas funciones virtuales que en la biblioteca del robot, así como proporcionar apéndices para los métodos que invoque en el robot.

Luego, tiene comandos que puede incluir en su propio marco de prueba que invoca los mismos métodos que la biblioteca de robots.

Esto implicará cierta cantidad de golpes y burlas, pero eso es inevitable en cualquier diseño de prueba de unidad.

El cambio del nombre de la clase base se puede hacer con un #define o probablemente preferido, un typedef.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.