Aaron Fischer Ingenieur, Vater, Heimwerker, Problemlöser

19 Dezember, 2009

Tag 20: Testen, Dokumentation und User Contributions

TL;DR:

In den letzten Teilen ging es ziemlich zur Sache. Wir haben eine Menge programmiert, überlegt und konstruiert. Nun wollen wir sicherstellen, das das, was wir gemacht haben, funktioniert und andere auch verstehen. Deshalb werden wir unseren Code testen, dokumentieren und auch eine kleine Bedienungsanleitung schreiben. Da nicht nur ich selbst Code schreibe, sondern auch Patches und andere Anfragen von Benutzern kommen, müssen wir hier auch sicherstellen, diese mit in die Software einfließen zu lassen.

Zuerst werden wir uns unseren Programmcode vornehmen. Bis jetzt ist vor lauter Hackerei kaum Zeit für das Testen übrig geblieben. So ist es meistens und viele hören jetzt auf. Das Spiel ist im groben fertig, doch haben wir es nur auf unserem Rechner gestartet, keine Tests gemacht und nichts dokumentiert. Würden wir es so auf SourceForge, FreshMeat und Co. präsentieren, würden es zwar ein paar anschauen aber gleich wieder wie eine heiße Kartoffel fallen lassen. Alles was wir jetzt haben ist ein Berg Code, mit dem nur wir etwas anfangen können.

Wollen wir aber zuerst prüfen, was wir zuvor fabriziert haben. In den meisten objektorientierten Programmiersprachen sind UnitTests sehr verbreitet. Da wir aber in C weder Objekte noch Klassen haben, ist auch der Programmierstil ein etwas anderer und wir können nicht so einfach UnitTests schreiben. Trotzdem wollen wir unseren Code testen.

Zwar gibt es einige Test Frameworks für C, doch wir wollen uns etwas anderes anschauen, es nennt sich Assertion, also zu deutsch Zusicherung. Dieses Feature ist in der Standardbibliothek von C in der assertion.h versteckt. Hiermit wollen wir das Herzstück unseres Spiels Testen, die drawPixel() Funktion. Dies ist die empfindlichste Stelle im ganzen Code, denn hier dürfen wir uns keinen Fehler leisten, sonst stimmt die Darstellung nicht oder es finden gar hässliche Zuweisungen statt, die nicht erlaubt sind. Prüfen wir also, ob die Eingabewerte in den von uns gewünschten Bereichen befinden:

void drawPixel(int x, int y, int color) {
  assert(x < SCREEN_WIDTH && x >= 0);
  assert(y < SCREEN_HEIGHT && y >= 0);

  // [...]
}

Mit dem assert() Makro können wir also überprüfen, ob eine Bedingung wahr ist oder nicht. Hier prüfen wir, ob sich x und y auf dem Bildschirm befindet.

Lassen wir das Programm ein paar mal laufen. Vermutlich sehen wir nicht viel, da der Fehler gerade jetzt nicht eintritt, deshalb müssen wir ihn provozieren bzw. die Funktion mal richtig durchtesten. Wir können entweder eine kleine Schleife um die generateTerrain() Funktion bauen oder ein kleines Testprogramm schreiben.

Als nächstes wollen wir uns um die Kommentare im Code kümmern. Hier hat jeder so seine eigenen Vorstellungen wie man richtig kommentieren sollte und in jeder Sprache gibt es einen quasi-Standard zum richtigen Kommentieren von Code, bei C gibt es natürlich wieder mehrere, wer hätte es gedacht. Kurzum, kommentiert kann wie man es für richtig hält, aber man sollte konsistent bleiben. Wer aus irgend einem Grund später mal Dokumentation aus dem Code heraus extrahieren will, sollte sich an die von dem entsprechenden Tool vorgegebenen Konventionen halten.

Ich habe in der main.c schon angefangen. Kommentare sollten nicht die einzelnen Zeilen Code beschreiben, sondern den Sinn dahinter. Jeder der die C-Syntax versteht, kann den Code lesen, doch bringt es ungemein mehr, wenn man den Gedankengang und die Intension des Programmierers versteht, warum er was wie und warum so gelöst hat. Dies sind viel wichtigere Informationen als zu wissen, dass auf eine Variable eins drauf addiert wird.

Damit unserer Programm eine runde Sache wird, schreiben wir natürlich auch noch eine Bedienungsanleitung dafür. Natürlich als Manpage, so wie es sich gehört. Manpages werden in (t|g)roff-Syntax geschrieben, was etwa so aussieht:

//[...]
.SH DESCRIPTION
The
.B adventgame
is the resulting output from the advent calendar series
from the website
.I advent.aaron-fischer.net
(in the year 2009).
//[...]

Eine ausführliche Beschreibung dazu findet man hier. Der Vorteil daran ist, dass wir daraus nicht nur eine Manpage generieren können, sondern auch andere Formate wie HTML oder PostScript.

Manpage von adventgame

Zum Schluss werden wir noch ein weiteres Thema beleuchten, von dem Open Source lebt: Den Beiträgen der Benutzer der Software. Da der Code von allen einsehbar ist, kann auch jeder Änderungen vornehmen. Leider ist es so, dass der Prozentsatz, der etwas zu einem Open Source Projekt beisteuert, im Promillebereich liegt. Die meisten sind schlicht zu faul ihre privaten Änderungen an den Autor zu schicken oder gar erst nach dem Fehler zu suchen. Deshalb muss man es den Benutzern so einfach wie möglich machen.

Bisher gab es leider nur eine Einsendung von Florian Eitel. Ich vermute aber mal, dass es an der Jahreszeit liegt. Im Dezember hat man einfach nicht die Zeit, die man im November oder im Januar hat, deshalb hoffe ich auf den Januar :)

Nachdem wir unser Projekt nun aufpoliert und für die Öffentlichkeit nutzbar gemacht haben, können wir es präsentieren. Doch eines fehlt noch, wir müssen es noch zu einem ganzen Paket zusammenschnüren. Wir müssen also unser Makefile etwas überarbeiten und ein make install hinzufügen. Dann bauen wir uns noch ein Debian Package daraus. Zuletzt werden wir uns noch überlegen, was wir tun müssen, um unser Spiel auf andere Plattformen zu portieren. Dazu übermorgen mehr.