Ich programmiere ein Spiel in meiner Freizeit, aber ich bin meistens noch ein Anfänger, wenn es um Programmierung geht. Es tut mir leid, wenn diese Frage nicht zum Thema gehört oder wenn sie für andere nicht hilfreich ist, aber hoffentlich wird sie es sein.
Ich habe viel Zeit damit verbracht, Bücher über das Design von Code sowie verschiedene Methoden und Ansätze für das Codieren zu lesen. Im Verlauf dieser Forschung stoße ich immer wieder auf das Konzept der testgetriebenen Entwicklung. Die Leute, die diese Idee vertreten, scheinen normalerweise sehr leidenschaftlich darüber zu sein. Ich glaube, dass es die Geschwindigkeit und Effizienz des Schreibens von Software verbessern kann. Zeit ist eine sehr wertvolle Ressource, daher würde ich lieber lernen, die Dinge am besten zu machen, als mich durchzumischen, ohne mein Wissen über das Programmierhandwerk zu erweitern.
Wie auch immer, möglicherweise weil ich ein Anfänger bin, kann ich mir nicht vorstellen, wie man testgetriebene Entwicklung auf Spiele anwendet. Ich habe ein paar Artikel zu diesem Thema gefunden, aber sie waren nicht sehr hilfreich. Die meisten Beispiele für Unit-Tests, die ich gesehen habe, sind sehr einfache Beispiele für Boilerplates oder Beispiele für Software, die überhaupt nicht wie ein Spiel ist.
In meiner eigenen Codierung versuche ich, es mit einer ähnlichen Denkweise wie die testgetriebene Entwicklung anzugehen, obwohl ich sicher bin, dass es nicht als TDD qualifiziert ist. Ich schreibe die Mindestmenge an Code, um zu versuchen, die Funktion zu implementieren, die ich dem Spiel hinzufüge, und teste das Spiel dann sofort, um festzustellen, ob es funktioniert. Wenn die Dinge nicht so laufen, wie ich es beabsichtigt habe, nehme ich sofort Änderungen vor, um sie näher an das zu bringen, was ich will. Wenn es nicht funktioniert oder defekt ist und ich die Fehler durch Lesen des Codes nicht finden kann, gehe ich die Methoden im Debugger durch, bis ich das unerwartete Verhalten finde, und entferne es dann. Was ich damit sagen will, ist, dass ich das Spiel ständig teste, so ziemlich nach jeder inkrementellen Änderung. Testen treibt meine Entwicklung an. Der "Unit Test" ist in meinem Kopf,
Weiter zu meiner eigentlichen Frage. Wie kann man Unit-Tests für ein komplexes Spiel schreiben? Mit komplex meine ich mit vielen neuen Aspekten des Gameplays, so dass das Fleisch des Gameplays aus der Interaktion zwischen den vielen verschiedenen Elementen im Spiel in Kombination mit den Entscheidungen des Spielers hervorgeht. Zum Beispiel ein schurkenhaftes RPG mit einer prozeduralen Welt. Welche Art von Unit-Tests würde man für ein solches Spiel schreiben? Wie könnte man eine testgetriebene Entwicklung auf ein solches Spiel anwenden?
Antworten:
Unit-Tests testen das Gameplay nicht . Es gibt keine programmatischen Kriterien, um festzustellen, ob ein Spiel Spaß macht oder ein Level die richtige Schwierigkeit ist. Unit-Tests testen, ob Ihr schurkenhafter Mapgen tatsächlich ein Level mit einer Treppe nach oben und einer Treppe nach unten erzeugt. Es wird getestet, ob Ihre Belastungsregeln so eingestellt sind, dass sich Ihr Charakter tatsächlich langsamer bewegt, wenn er gewichtet wird. Dadurch wird sichergestellt, dass Ihr Charakter keine 50 Hüte tragen kann . Dadurch wird sichergestellt, dass die Mechanik alle relativ isoliert korrekt implementiert ist.
quelle
Es ist schwierig, Komponententests für Code zu schreiben, der nicht deterministisch ist. Wenn Sie Code mit Zufallszahlen haben, können Sie keinen Komponententest schreiben, der ein erwartetes Ergebnis bestätigt.
Unit-Tests eignen sich daher besser für den deterministischen Code. Wenn ich einer Methode diese Eingaben gebe, erwarte ich diese Ausgaben. Als Beispiel: Wenn ein Kämpfer mit 15 Stärken mit seinem Zweihand-Breitschwert einen untoten Ghul mit 10 Rüstungen erfolgreich trifft, erwarte ich 8 Schaden. Der nicht deterministische Teil (ob der Treffer erfolgreich war oder nicht) kann nicht unbedingt einem Unit-Test unterzogen werden, aber was danach passiert, kann sein. Selbst wenn die Schadensmenge voraussichtlich in einem bestimmten Bereich liegt, können Sie dies testen.
Wenn Sie Schwierigkeiten haben, Code zum Schreiben von Komponententests zu finden, müssen Sie eine Umgestaltung vornehmen, damit die deterministische Logik in Methoden oder Klassen isoliert ist. Wirf zuerst die Würfel, um den Erfolg zu bestimmen, und übergebe dann die relevanten Eingaben (Klasse, Stärke, Rüstung usw.) an eine testbare Methode.
Bei Ihrem Kommentar zum Unit-Test im Kopf geht es beim Unit-Test nicht nur um frisch geschriebenen Code. Es geht auch darum, darauf zu vertrauen, dass der Code auch nach unvermeidlichen Änderungen noch funktioniert .
quelle
IRandomNumberGenerator
), und alles, was Zufallszahlen verwenden muss, akzeptiert einen Verweis auf diese Dienstschnittstelle in ihrem Konstruktor. Wenn Ihr Test dann dieses Objekt erstellt, um einen Komponententest auszuführen, injiziert er ein ObjektMockRandomNumberGenerator
, das einen festen bekannten Zahlenstrom ausgibt. Dann haben Sie einen wiederholbaren Test. Die gleiche Idee ist nützlich für alles, was das aktuelle Datum / die aktuelle Uhrzeit abrufen oder Informationen von einem Webdienst herunterladen muss - fügen Sie einfach einen Scheindienst ein.RandomNumberGenerator
.