Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

06.12.2014, 15:52

Test-Driven Game Development

Hi, welche Möglichkeiten seht ihr, automatisierte Tests bei der Spieleentwicklung durchzuführen?

In diversen Foren finden sich sehr widersprüchliche Meinungen: Zum einen seien viele Designs so stark gekoppelt, dass das einzelne Testen bestimmter Funktionen nur schwer möglich ist. Zum anderen lassen sich beispielsweise Rendering-spezifische Sachen schwer bis gar nicht testen. Unter'm Strich gibt es also stark divergierende Meinungen.

Nun habe wir hier - soweit ich es mitbekommen habe - auch ein paar professionelle Spieleentwickler unter den Usern :) Welche Möglichkeiten seht ihr TDD bei der Spieleentwicklung zu betreiben? Ein Entity-System (spawn, move, vanish) lässt sich vllt. noch relativ gut testen .. wo seht ihr die Grenzen? Habt ihr Anregungen welche Komponenten sich besonders gut testen lassen - und für welche Komponenten würdet ihr andere Ansätze vorziehen?

LG Glocke

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

06.12.2014, 16:11

Vorweg schonmal: ich bin kein professioneller Spieleentwickler. (Ich mache es nicht beruflich.)

Grundvoraussetzung für ein automatisiertes Testen (bspw. mit Unit-Tests) erfordert in jedem Fall ein sauberes Design als Grundlage. Wenn die einzelnen Komponenten so stark untereinander gekoppelt sind, dass sie nicht einzeln getestet werden können, ist das ein Indiz für ein schlechtes Design.

Ich höre nur immer wieder als Gegenargument, man würde zu viel Zeit für das Schreiben der Testfälle aufbringen, welche man eher mit dem schreiben effektiv nutzbaren Codes verwenden sollte. (Wenn man die Vorteile des automatisierten Tests kennt, dann weiß man, warum der reine Zeitaufwand für das Schreiben von Testfällen eher kein richtiges Argument ist.)

In jedem Fall sollten sich zu Grunde liegende Funktionen und Algorithmen relativ gut testen lassen. Dazu gehören Wegfindung, mathematische Operationen, sofern selbst implementiert, usw.
Bei Spielen muss man aber auch bedenken, dass bestimmte Dinge nicht in solch automatisierten Tests abgedeckt werden können. Dazu gehören nicht nur Shader (wobei diese sich evtl. noch einigermaßen handhaben lassen), sondern vor allem das Spielgefühl. (Man kann nichts automatisiert testen, was der subjektiven Wahrnehmung unterliegt.)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

3

06.12.2014, 18:33

Graphik kann man testen, indem man nach dem Rendern einer Test-Szene den Framebuffer ausliest. Das muss keine komplizierte Computer Vision sein. Es reicht, wenn man weiß welcher Pixel in etwa welche Farbe haben sollte. Selbiges geht auch mit Audio, indem man z.B. testweise automatisch generierte Square Waves rendert und das Ergebnis ausliest. Der Test-Aufwand ist da allerdings seeehr hoch.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

4

06.12.2014, 19:12

Wenn die einzelnen Komponenten so stark untereinander gekoppelt sind, dass sie nicht einzeln getestet werden können, ist das ein Indiz für ein schlechtes Design.

Dieses Indiz zu haben ist einer der Gründe (aber nicht der Hauptgrund), warum ich verstärkt TDD betreiben will :)

Ich höre nur immer wieder als Gegenargument, man würde zu viel Zeit für das Schreiben der Testfälle aufbringen, welche man eher mit dem schreiben effektiv nutzbaren Codes verwenden sollte. (Wenn man die Vorteile des automatisierten Tests kennt, dann weiß man, warum der reine Zeitaufwand für das Schreiben von Testfällen eher kein richtiges Argument ist.)

Als ich das gelesen habe, musste ich grinsen :D Ich habe in letzter Zeit die Vorzüge von Testfällen zu schätzen gelernt .. es ist ein ganz anderes Arbeiten als beim "Fear-based programming" :D

In jedem Fall sollten sich zu Grunde liegende Funktionen und Algorithmen relativ gut testen lassen. Dazu gehören Wegfindung, mathematische Operationen, sofern selbst implementiert, usw.

Ok, dann bin ich da konzeptuell schon einmal auf dem richtigen Weg. Lose Kopplung vorausgesetzt .. ^^

Graphik kann man testen, indem man nach dem Rendern einer Test-Szene den Framebuffer ausliest.

Allein bei diesem Gedanken kommt schon Freude auf :D

LG Glocke

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

5

06.12.2014, 19:20

Ich hatte mir in letzter Zeit auch ein paar Gedanken zu diesem Thema gemacht und finde das Thema nicht ganz unkompliziert.

Ich denke da muss man aber ein paar Fälle unterscheiden:

  1. Algorithmen
    Das fängt bei so Dingen wie Dot oder Cross Product o.ä. an, geht über Wegfindungsalgorithmen vielleicht sogar bis zu großen Teilen einer KI.
    Alles wo man praktisch einen bestimmten Datensatz reingibt und ein Ergebnis erhält. Sowas ist eh der Traum für Testautomatisierung,
    das ist meiner Meinung nach bei Spielen auch nicht anders.

  2. Ausgabe Schnittstellen (Grafik, Sound, ...)
    Hier wird es deutlich schwieriger. Zu allererst kann man natürlich immer noch automatisiert testen ob der Code durchläuft ohne
    zu crashen. Das heißt aber noch lange nicht das auch irgendetwas sinnvolles ausgegeben worden ist.
    Wie von Evrey angesprochen kann man bei Grafik den Framebuffer auslesen und vergleichen. Ich würde aber z.B. bei DirectX dann
    auf den Referenzrasterizer zurückgreifen um nicht anzufangen ungefähr zu vergleichen. Das lässt aber offen ob das ganze dann auch
    mit einem "echten" Treiber von einer echten GPU harmoniert. Diese könnte man mit dieser Methode ebenfalls automatisieren,
    aber dann kann ein Treiberupdate auch Testfälle zum fehlschlagen bringen. Und das ohne einen echten Bug.

  3. Eingabe Schnittstellen
    Hier sehe ich ein großes Problem. Die direkte Verarbeitung von Eingabedaten (Mauspointerballistiken oder Scancodemappings usw., sofern selbst implementiert)
    kann man wahrscheinlich sogar sehr gut testen. Aber das eigentliche Abfragen der Daten stelle ich mir kaum sinnvoll automatisiert testbar vor. Höchstens
    einen automatischen Smoketest würde ich hier als machbar ansehen.

  4. Netzwerk
    Wieder schwierig. Man könnte vielleicht die Sockets mocken und vorgefertige Daten einspielen und eine entsprechend vorher bekannte Antwort des zu testenden Codes erwarten. Das könnte aber auf Dauer extrem aufwendig sein, besonders wenn man irgendwann komplette Sessions testen möchte wie Login bei einem Server, Spiel suchen, Spiel joinen, Spiel startet usw.

  5. UI Tests
    In Bereichen normaler Anwendungen wurde mittlerweile einiges an Tooling geschaffen um UI Tests automatisiert durchführen zu können. Wobei das auch bei normalen Anwendungen nicht immer ganz einfach ist, besonders wenn sich Oberflächen ändern. Und dann ist im Spielebereich fraglich wie gut das Tooling ist. Andere Aspekte
    sind ja erstmal wichtiger als die "langweilige" 2D Oberfläche in der man das Spiel konfiguriert u.ä. Bugs sind an dieser Stelle trotzdem ärgerlich.

  6. Spielmechaniken
    Spielmechaniken stelle ich mir extrem schwer zu testen vor. Selbst wenn man sie so isoliert hat das sie ohne das Spiel drum rum laufen, sobald sie zufällige Elemente enthalten wird es haarig. Ein Test "Einheit A muss Einheit B im Kampf besiegen" kann auch mal daneben gehen wenn Einheit B ohne Ende kritische Treffer landet. Oder man hält den Seed des RNG identisch.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

6

08.12.2014, 16:01

Hi,

ich bin gerade dabei mein Entity-Component-System neu zu schreiben und gehe dabei TDD-orientiert vor. Dank loser Kopplung lassen sich so GameObjects und ObjectPhysics separat testen :thumbsup:

Zitat

All tests passed (4173 assertions in 13 test cases)


LG Glocke

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

08.12.2014, 18:31

4173 Assertions? Hast Du da ewig große Loops oder woher kommt diese doch erstaunlich große Zahl an Assertions für so wenige Test-Cases?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

8

08.12.2014, 18:42

4173 Assertions? Hast Du da ewig große Loops oder woher kommt diese doch erstaunlich große Zahl an Assertions für so wenige Test-Cases?

Mit der Frage habe ich gerechnet :D Nun ja, ich prüfe innerhalb der Testcases viele Vor- und Zwischenbedingungen. Unter'm Strich bestehen meine Testcases aus je ~20 Zeilen. Die Testsuite die ich verwende hat ihre Probleme mit komplexeren Ausdrücken, d.h. ich muss die Assertions etwas atomarer aufbauen:

C-/C++-Quelltext

1
2
3
4
// statt REQUIRE(object.getWorldPosition == {1.2f, 3.4f});
auto pos = object.getWorldPosition();
REQUIRE(pos.x == 1.2f);
REQUIRE(pos.y == 3.4f);

Aber vermutlich sollte ich meine Testcases noch weiter zerlegen; z.B. ist dieser Auszug ca. 20% eines bestimmten Testcases.. Allerdings will ich sie nicht "irrwitz klein" machen.. Heute früh hatte ich noch 7 Testcases, die ich dann auf die momentanen 13 Stück zerteilt habe... Still in progress :thumbsup:

/EDIT: Dazu kommt: Ich habe eigentlich nur ~75 Assertions verwendet Oo Ich muss mich mal belesen wo die 4k herkommen :dash: .. die habe ich nicht erzeugt :D

9

08.12.2014, 19:22

Um das mal kurz einzuwerfen (weil wegen 4k assertions): Dieses wir brauchen mindestens 100% code coverage ist auch nicht optimal.
Du brauchst nicht jeden moeglichen edge case zu testen meiner Meinung nach.

Du brauchst nicht mal den genauen Ausgang wissen, ueberpruef einfach ob das ergebnis irgendwie Sinn macht.

Das ist jetzt nicht alles auf die Spieleprogrammierung bezogen sondern so allgemein: Wenn du fuer jede kleine Code aenderung (jaja klar, die specs sind alle von anfang an klar und werden sich auch nie mehr aendern. Du schreibst deine tests bevor du anfaengst zu coden und musst die nie mehr aendern. Blubbla) mehr Zeit brauchst alle tests anzupassen als es dauern wuerde das manuell durchzutesten macht das einfach keinen Sinn mehr. Wenn du dann auch noch die testdaten anpassen musst weil du diese genaue zahl am ende brauchst ists auch einfach nur noch nervig. Irgendwann zeigen dir deine tests dann nur noch das deine testdaten nicht mehr aktuell sind anstelle von echten bugs. Yay.

Versteht mich nicht falsch, ich bin ein grosser fan von tests und man sieht meistens auch direkt an der codequalitaet das etwas keine tests hat (traut sich ja keiner anzufassen/rafactoren) aber wie sooft: Man kanns halt auch uebertreiben...

10

08.12.2014, 19:42

Wie gesagt: ich habe ~75 Assertions auf 13 Testcases - die 4k kommen vermutlich vom Testframework durch irgendwelche Internas (was nicht so toll ist ^^)

Werbeanzeige