Est-il pratique d'utiliser un framework de test comme JUnit dans une situation de développement de jeu? Quel type de considérations de conception pouvez-vous suivre pour rendre votre jeu plus testable? Quelles parties d'un jeu peuvent / doivent être testées et quelles parties doivent / doivent être laissées aux tests humains?
Par exemple, si la boucle de jeu est encapsulée dans une fonction, il semble que ce serait terriblement difficile à tester. J'aime refactoriser une fonction de "mise à jour" qui prend un delta de temps et fait avancer la logique du jeu; cela permet des astuces intéressantes comme la possibilité de ralentir le jeu en le nourrissant de faux deltas temporels plus lents.
architecture
unit-testing
Ricket
la source
la source
Réponses:
L'un des principes de TDD est que vous laissez TDD dans certains cas influencer votre conception. Vous écrivez un test pour le système, puis écrivez le code pour réussir ce test, gardez les dépendances aussi peu profondes que possible.
Pour moi, il n'y a que deux choses que je ne teste pas dans le cadre des tests unitaires:
Tout d'abord, je ne teste pas les éléments visuels et l'apparence des choses. Je teste cela et l'objet sera au bon endroit après sa mise à jour, qu'une caméra éliminera un objet en dehors de ses limites, que les transformations (au moins celles qui sont effectuées en dehors des shaders) soient effectuées correctement avant d'être remises au moteur graphique , mais une fois qu'il atteint le système graphique, je trace la ligne. Je n'aime pas essayer de se moquer de choses comme DirectX.
Deuxièmement, je ne teste pas vraiment la fonction de boucle de jeu principale. Je teste que chaque système fonctionnera lorsqu'il passera un delta raisonnable et que les systèmes fonctionneront correctement ensemble quand ils en auront besoin. Ensuite, je viens de mettre à jour chaque système avec le delta correct dans la boucle de jeu. Je pourrais avoir un test pour montrer que chaque système a été appelé avec le bon delta, mais dans de nombreux cas, je trouve cela exagéré (à moins que vous ne fassiez une logique complexe pour obtenir votre delta, alors ce n'est pas exagéré).
la source
Noel Llopis a couvert les tests unitaires dans la mesure où je pense que vous recherchez:
En ce qui concerne le test de la boucle de jeu entière, il existe une autre technique pour empêcher les régressions fonctionnelles dans votre code. L'idée est que votre jeu se joue lui-même via un système de relecture (c.-à-d. D'abord enregistrer les entrées du joueur, puis les rejouer sur une autre piste). Pendant la relecture, vous générez un instantané de l'état de chaque objet pour chaque image. Cette collection d'état peut alors être appelée "l'image dorée". Lors de la refactorisation de votre code, vous réexécutez la relecture et comparez l'état de chaque image à l'état de l'image dorée. S'il diffère, le test a échoué.
Bien que les avantages de cette technique soient évidents, vous devez faire attention à certaines choses:
la source
Je suis d'accord avec les commentaires de Jeff et de jpaver. Je voulais également ajouter que l'adoption d'un modèle de composant pour votre architecture augmente considérablement sa testabilité. Avec un modèle de composant, chaque composant doit effectuer une seule unité de travail et doit pouvoir être testé isolément (ou avec des objets factices limités).
De même, les autres parties du jeu qui dépendent des entités ne devraient compter que sur un sous-ensemble des composants pour fonctionner. En pratique, cela signifie que vous pouvez généralement simuler quelques faux composants pour faciliter le test de ces zones ou vous pouvez simplement composer des entités partielles à des fins de test. par exemple, vous omettez les composants de rendu et d'entrée car ceux-ci ne sont pas nécessaires pour tester la physique.
Enfin, j'ignorerais les conseils sur les performances que vous obtenez de certaines personnes de la communauté du jeu concernant les interfaces. Écrivez bien le code avec les interfaces et si vous rencontrez des problèmes de performances sur la route, vous pouvez facilement profiler, identifier et refactoriser pour résoudre le problème. Je n'ai pas été convaincu par les préoccupations de Noel concernant l'impact sur les performances des interfaces ou la surcharge de complexité qu'elles ont ajoutée.
Cela dit, n'allez pas trop loin pour essayer de tester chaque petite chose indépendamment. Comme la plupart des choses, les tests et la conception visent à trouver le bon équilibre.
la source
J'ai pensé ajouter une deuxième réponse en réponse au commentaire du PO selon lequel l'utilisateur pourrait remplacer les tests unitaires. Je crois que c'est complètement faux car le but des tests unitaires n'est pas d'assurer la qualité. Si vous voulez que des tests soient en place pour garantir la qualité de votre programme, vous devriez probablement enquêter sur des tests de scénarios ou investir dans une excellente surveillance.
(Avec un excellent contrôle et un produit fonctionnant en tant que service, il est en effet possible de pousser certains "tests" sur le client, mais vous devez disposer d'un système sophistiqué qui détecte rapidement les erreurs et annule les modifications responsables. Cela est probablement trop pour une petite équipe de développement.)
Le principal avantage des tests unitaires est qu'ils obligent le développeur à écrire du code mieux conçu. L'acte de test met le développeur au défi de séparer les préoccupations et d'encapsuler les données. Il encourage également le développeur à utiliser des interfaces et autres abstractions afin de ne tester qu'une seule chose.
la source