Testen und Laufzeit im Spiel
Im Kapitel Testen und Laufzeit hast du gelernt, Programme systematisch zu prüfen und abzuschätzen, was sie kosten. Ein Spiel scheint dafür schlecht geeignet: Du testest es, indem du es spielst. Genau das ist das Problem.
Die Leitfragen für dein Spiel:
- Welche Regel in deinem Spiel ließe sich prüfen, ohne dass jemand eine Taste drückt?
- Was macht dein Spiel in jedem Bild, und wie wächst der Aufwand, wenn es mehr Figuren werden?
Woran es hakt
Eine Punkteregel, wie sie in vielen Spielen steht: Wer mehrere Münzen hintereinander einsammelt, bekommt einen Kombo-Bonus. Ab der dritten Münze in Folge zählt jede doppelt, ab der sechsten dreifach. Ein Treffer setzt die Kombo zurück.
Steht diese Regel mitten in Welt oder im Spieler, lässt sie sich nur prüfen, indem man spielt: sechs Münzen einsammeln, ohne getroffen zu werden, und dann nachrechnen. Bei jeder Änderung von vorne. Und ob die Grenze bei der dritten oder der vierten Münze liegt, merkt man dabei kaum.
Die MVPs sind kleine, eigenständig lauffähige Beispiele. Starte ein Beispiel mit ▶ und klicke für die Tastensteuerung in seine Ausgabe. Im Reiter Beispiel.java steht die jeweilige Idee. Falls ein Reiter Baukasten.java dabei ist, enthält er vorbereitete Hilfen für Figuren, Texte und Steuerung. Probiere zuerst die angegebene Änderung aus und übertrage dann die Idee in deine Werkstatt.
Mechaniken
Such dir mindestens eine aus. Du darfst sie verändern, kombinieren oder dir etwas ganz anderes ausdenken.
Eine Regel ohne Bühne
Im Spiel: eine Punktzahl mit Kombo-Bonus und der Anzeige der aktuellen Kombo.
Dahinter steckt: Die Regel braucht keine Grafik, sie braucht nur zu wissen, was passiert ist. Also bekommt sie eine eigene Klasse ohne jede Verbindung zur Bühne. Eine Klasse, die nur rechnet und nichts anzeigt, ist ohne Umgebung lauffähig und deshalb ohne Umgebung prüfbar. Die Welt meldet ihr nur noch treffer(10) und fehler().
public class Punkteregel {
public void treffer(int pGrundwert) {
kombo = kombo + 1;
punkte = punkte + pGrundwert * this.faktor();
}
// ...
}
Aufwand: ★★☆
MVP zum Ausprobieren: Lies die Punktestände nach jedem Treffer. Nach fehler beginnt die Kombo wieder bei eins.
In dein Spiel übertragen: Halte die Regel frei von Grafik und Tastatur. Die Welt meldet nur Ereignisse und liest Ergebnisse.
Tests, die in einer Sekunde laufen
Im Spiel: nichts zu sehen. Aber im Reiter Testrunner unter dem Editor stehen vier grüne Haken.
Dahinter steckt: eine Testklasse, die die Regel nach dem Muster Vorbereiten, Ausführen, Vergleichen prüft. Der Kern sind die Grenzen: 2 → 3 und 5 → 6. Genau dort stehen die >=-Vergleiche, und genau dort passieren die Fehler. Teste immer beide Seiten einer Grenze, den letzten Fall davor und den ersten danach.
@Test
void grenzeZumDoppelten() {
Punkteregel r = new Punkteregel();
r.treffer(10);
r.treffer(10);
assertEquals(20, r.getPunkte(), "Der zweite Treffer zählt noch einfach.");
r.treffer(10);
assertEquals(40, r.getPunkte(), "Der dritte Treffer zählt doppelt: 20 + 20.");
}
Aufwand: ★★☆
MVP zum Ausprobieren: Starte die vier Tests im Testrunner. Ändere >= 3 zu > 3 und prüfe erneut.
In dein Spiel übertragen: Teste beide Seiten jeder Grenze und den Neustart der Kombo nach einem Fehler.
Eine Testliste fürs Spielen
Im Spiel: nichts zu sehen, aber weniger Überraschungen bei der Vorstellung.
Dahinter steckt: Was sich nicht automatisch prüfen lässt, prüfst du nach einer Liste. Sie enthält vor allem die Sonderfälle: Was passiert am Rand? Wenn zwei Gegner gleichzeitig treffen? Wenn das letzte Leben genau beim letzten Einsammeln verloren geht? Wenn man die Leertaste mitten im Spiel drückt?
Aufwand: ★☆☆
MVP zum Ausprobieren: Prüfe die Fälle im Kommentar: Rand, zwei Meldungen im selben Bild, letztes Leben und letzte Münze gleichzeitig, Leertaste während des Spiels.
In dein Spiel übertragen: Lege die Priorität gleichzeitiger Ereignisse fest und halte erwartetes und beobachtetes Verhalten in deiner Testliste fest.
Was kostet die Kollisionsprüfung?
Im Spiel: Mit 5 Gegnern läuft alles flüssig, mit 200 ruckelt es.
Dahinter steckt: Jeder Gegner prüft in jedem Bild, ob er ein Hindernis berührt. Fragt jeder jeden, sind das bei n Figuren etwa n² Vergleiche, 60-mal in der Sekunde. Mit dem Gitter aus dem Kapitel über Felder fragt jeder nur noch seine Nachbarfelder: eine feste Zahl von Zugriffen, egal wie groß das Level ist. Schätze für dein Spiel ab, wie viele Vergleiche ein Bild kostet.
Aufwand: ★★★
MVP zum Ausprobieren: Vergleiche 5, 50 und 200 Figuren. Die Zähler messen Prüfungen, keine Millisekunden.
In dein Spiel übertragen: Ersetze die innere Schleife über alle Figuren durch Zugriffe auf örtliche Nachbarzellen. Bei mehreren Figuren pro Zelle muss auch deren Anzahl berücksichtigt werden.
Die Flutfüllung testen
Im Spiel: nichts zu sehen. Aber du weißt sicher, dass die eingemauerte Münze erkannt wird, auch in Plänen, die du nie gespielt hast.
Dahinter steckt: dieselbe Trennung wie bei der Punkteregel. Eine Klasse Karte bekommt den Plan als Feld von Zeichenketten und beantwortet istErreichbar(zeile, spalte), ganz ohne Bühne. Die Tests prüfen kleine, von Hand gebaute Pläne: ein offener Raum, eine eingemauerte Ecke, ein Start direkt neben der Mauer.
(Nur Leistungskurs.)
Aufwand: ★★★
MVP zum Ausprobieren: Starte die Tests im Testrunner. Entferne eine Öffnung im Testplan.
In dein Spiel übertragen: Teste kleine Pläne mit bekanntem Ergebnis, einschließlich nicht erreichbarer Ziele und Randpositionen.
Und ohne Spiel?
| Im Spiel | Dieselbe Einsicht woanders |
|---|---|
| Punkteregel aus dem Sprite herauslösen | Geschäftslogik von der Benutzeroberfläche trennen |
| Grenzen 2 → 3 und 5 → 6 prüfen | Notengrenzen, Rabattstufen, Altersgrenzen |
| „Das teste ich, indem ich es spiele.“ | „Das teste ich, indem ich es benutze.“ |
| jeder gegen jeden | jeder Datensatz gegen jeden anderen beim Abgleich |
Schlecht testbarer Code ist fast immer schlecht entworfener Code. Wenn ein Test unmöglich erscheint, liegt es selten am Test.
Deine eigene Idee
Welche Regel in deinem Spiel rechnet etwas aus, ohne etwas anzuzeigen? Preise im Laden, Schaden im Kampf, Erfahrungspunkte, Stufenaufstiege? Löse sie heraus und teste sie.
Fürs Tagebuch: Welche Klasse deines Spiels hast du getestet? Liste deine Testfälle auf und markiere, welche davon Grenzfälle sind. Welchen Fehler hätte jeder einzelne gefunden?
Checkpoint
Im Checkpoint nach diesem Kapitel rechnet die Klasse Punkteregel die Punktzahl mit Kombo-Bonus aus, und PunkteregelTest prüft sie mit vier Tests. Starte sie über den Reiter Testrunner. Wie du den Checkpoint lädst, steht auf der Startseite der Werkstatt.
Die Testklasse ist im Format der Online-IDE geschrieben. Auf dem Rechner brauchst du JUnit, das zum Beispiel das Java-Erweiterungspaket von VS Code mitbringt. Entferne dort das @Test vor class PunkteregelTest.
Checkpoint: Testen (Online-IDE)
Weiterbauen kannst du in deiner Werkstatt.