J'écris des tests unitaires pour un système de direction pour un jeu vidéo. Le système a plusieurs comportements (éviter cette zone pour la raison A, éviter cette zone pour la raison B, chacun ajoutant un peu de contexte à une carte de la région. Une fonction distincte analyse ensuite la carte et produit le mouvement souhaité.
J'ai du mal à décider comment écrire les tests unitaires pour les comportements. Comme le suggère TDD, je ne m'intéresse qu'à la façon dont les comportements affectent le mouvement souhaité. Par exemple, éviter-pour-raison-A devrait entraîner un mouvement loin de la mauvaise position suggérée. Je me fiche de savoir comment ou pourquoi le comportement ajoute du contexte à la carte, mais seulement que le mouvement souhaité est éloigné de la position.
Donc, mes tests pour chaque comportement configurent le comportement, le font écrire sur la carte, puis exécutent la fonction d'analyse de carte pour déterminer le mouvement souhaité. Si ce mouvement satisfait mes spécifications, je suis content.
Cependant, maintenant mes tests dépendent à la fois des comportements qui fonctionnent correctement et de la fonction d'analyse de la carte qui fonctionnent correctement. Si la fonction d'analyse échoue, j'obtiendrais des centaines de tests ayant échoué plutôt que quelques. De nombreux guides de rédaction de tests suggèrent que c'est une mauvaise idée.
Cependant, si je teste directement par rapport à la sortie des comportements en se moquant de la carte, alors je me connecte sûrement trop étroitement à la mise en œuvre? Si je peux obtenir le même mouvement souhaité de la carte en utilisant un comportement légèrement différent, alors les tests devraient toujours réussir.
Alors maintenant, je souffre de dissonance cognitive. Quelle est la meilleure façon de structurer ces tests?
la source
Réponses:
Dans le monde idéal, vous auriez en effet un ensemble de tests unitaires parfaitement orthogonaux, tous au même niveau d'abstraction.
Dans le monde réel, vous avez généralement des tests sur de nombreux niveaux différents de l'application, donc souvent les tests de niveau supérieur exercent une fonctionnalité qui a déjà été testée par des tests de niveau inférieur dédiés. (Beaucoup de gens préfèrent appeler ces tests de niveau supérieur sous-système / tests d'intégration plutôt que des tests unitaires; néanmoins, ils peuvent toujours fonctionner sur le même cadre de tests unitaires, donc du point de vue technique, il n'y a pas beaucoup de différence.)
Je ne pense pas que ce soit une mauvaise chose. Le but est de faire tester votre code de la meilleure façon qui corresponde à votre projet et à votre situation, de ne pas adhérer à "la voie idéale".
la source
Ce type de test est la raison pour laquelle les simulateurs ont été inventés. L'idée principale: vous écrivez une maquette pour votre objet (carte, comportement, personnage, ...), puis vous écrivez des tests en utilisant cette maquette au lieu de l'objet réel. Les gens appellent parfois des faux moignons et je crois qu'il y a d'autres mots pour les deux.
Dans votre cas, vous écririez une maquette pour la carte chaque fois que vous aurez besoin de tester les comportements, et d'autres simulations pour les comportements chaque fois que vous voudrez tester la carte. Vos simulations seraient idéalement beaucoup plus simples que les comportements réels que vous modifiez, n'incorporant que les méthodes ou les variables dont vous avez réellement besoin pour ce test. Vous devrez peut-être écrire une maquette différente pour chaque test, ou vous pourrez réutiliser certaines simulations. Quoi qu'il en soit, ils devraient être adaptés au test et ne devraient pas essayer de ressembler autant que possible au comportement réel.
Si vous incluez des exemples de cartes ou de comportements, peut-être que quelqu'un pourrait fournir des exemples de simulations que vous pourriez écrire. Pas moi, car je n'ai jamais programmé un jeu vidéo plus avancé que Pong, et même alors, je suivais un livre, mais peut-être quelqu'un qui connaît bien les tests unitaires et le développement de jeux.
la source
Je pense que vous essayez de tester des trucs qui sont d'un niveau beaucoup plus élevé qu'une unité.
La plupart des tests de comportement nécessiteraient une certaine intelligence derrière, pour savoir s'il s'est comporté correctement. Cela ne peut pas être fait facilement à l'aide de tests automatisés.
la source