Test unitaire de code lourd à effets secondaires

10

Je commence à écrire du code C ++ pour exécuter un robot, et je ne sais pas comment incorporer les tests unitaires, si c'est possible. On m'a fourni une bibliothèque qui permet la création de "commandes" pour le robot, qui sont automatiquement planifiées et exécutées. Le mécanisme pour créer ces commandes est de la sous - classe d' une classe de base de commande qu'ils procurent, et mettre en œuvre virtuelles void Initialize(), void Execute()et void End()méthodes. Ces fonctions sont exécutées uniquement pour leurs effets secondaires, qui affectent le robot (faire fonctionner les moteurs, étendre les pistons, etc.). Pour cette raison, je ne vois vraiment pas où attacher des tests unitaires au code, à moins de se moquer de la bibliothèque entière afin de pouvoir vérifier les états virtuel avant et après du robot. Existe-t-il un moyen de tester à l'unité ce qui n'est pas trop lourd?

Éditer

Je pense que j'ai peut-être induit en erreur sur la fonctionnalité de la bibliothèque. La bibliothèque fournit la plupart de l'interface au robot ainsi que le système de commande / planification, donc ce n'est pas aussi simple que de se moquer de la classe de base de commande, je devrais me moquer de toute l'interface avec le matériel. Malheureusement, je n'ai tout simplement pas le temps de le faire.

Will Kunkel
la source
Je suppose que vous pouvez annuler toute action que vous faites faire à votre robot, non? Ne pouvez-vous pas annuler les actions de votre test?
Neil
1
C'est dommage que la bibliothèque n'ait pas utilisé la composition au lieu de l'héritage, car vous pourriez simplement vous moquer de la classe de commande si c'était le cas.
Robert Harvey
@Neil Je ne sais pas trop ce que vous demandez. Pouvez-vous reformuler votre question?
Will Kunkel

Réponses:

7

Ce que je ferais dans ce cas serait d'introduire ma propre interface RobotControl avec des méthodes correspondant à celles de la vraie lib.

Après avoir fait cela, je ferais une classe RobotControlImpl qui implémente cette interface par rapport au vrai robot lib.

Les commandes que j'écrirais en conséquence ne prolongeraient pas la classe de base, mais opéreraient plutôt sur l'interface que vous avez introduite.

De cette façon, vous pouvez vous moquer de RobotControl, passer la maquette à n'importe quelle commande et vérifier qu'elle a appelé les bonnes méthodes sur l'interface.

Dans prod, vous passeriez le véritable implément de RobotControl aux commandes que vous avez implémentées.

Je ne sais pas si c'est ce que vous aviez en tête et considéré comme lourd?

Edit: Oh, et si vous vous attendez à ce que les commandes se mettent en veille pour attendre la fin (cauchemar, mais parfois c'est ce que vous avez), j'aurais besoin des commandes pour appeler une méthode de veille sur RobotControl. De cette façon, vous pouvez désactiver les mises en veille pendant le test et vérifier simplement que la commande essaie de s'endormir.

Alexander Torstling
la source
2
+1. Vous n'aimez pas l'interface? Faire votre propre.
Neil
On dirait que vous suggérez que je me moque de toute la bibliothèque. Presque toutes les fonctions que les commandes appellent sont internes à la bibliothèque.
Will Kunkel
0

Je pense qu'il est possible de rendre le code testable d'une manière mini-invasive. J'entends par là que vous pouvez écrire les commandes exactement comme prévu par les auteurs de la bibliothèque de robots. Cela peut être avantageux si vous souhaitez échanger du code avec d'autres qui n'utilisent pas votre couche intermédiaire.

Il nécessite une "version de test unitaire" distincte de votre code.

Ce que vous faites, c'est que dans un fichier d'en-tête central, vous vérifiez un temps de compilation définir s'il s'agit de la construction de test unitaire, et si oui, redéfinit le nom de la classe de base, et peut-être d'autres classes de la bibliothèque de robot en noms de classes de votre implémentation de test. Vous devez définir les mêmes fonctions virtuelles que dans la bibliothèque du robot, ainsi que fournir des stubs pour les méthodes que vous invoquez sur le robot.

Ensuite, vous avez des commandes que vous pouvez lancer dans votre propre framework de test qui invoque les mêmes méthodes que la bibliothèque de robots ferait.

Cela impliquera une certaine quantité de tronçonnage et de moquerie, mais cela est inévitable dans toute conception de test unitaire.

La modification du nom de la classe de base peut être effectuée avec un #define ou probablement préféré, un typedef.

jdv-Jan de Vaan
la source