2. Advent: Prototyp und Testen
TL;DR:
Florian ist diese Woche voll durchgestartet und hat mit einem Prototyp begonnen und mit diesem schon die Kernkomponenten implementiert. Der Prototyp war wichtig, um sicherzustellen dass die Wahl der verwendeten Komponenten (avahi und dbus) sinnvoll ist und wie sich die einzelnen Schichten voneinander abkoppeln lassen. Auf diese Basis kann nun aufgesetzt werden. Zuvor sollte aber auf jeden Fall sichergestellt werden, dass der Kern korrekt funktioniert und wir nicht auf einem Fehlerbehafteten Konzept aufbauen. Deshalb werden wir uns in diesem Beitrag um das Testen der einzelnen Komponenten kümmern.
Der erste Funktionstest besteht bei uns meist darin, die Klassen/Funktionen mit Dummy-Werten auf der Console oder mit simplem Testcode auszuprobieren. Ein paar [pp](http://www.ruby-doc.org/core/files/lib/pp_rb.html)
"s genügen hier meist schon, um sicherzustellen dass die Funktion korrekt arbeitet bzw. die Kommunikation funktioniert. Da noch keinerlei UI besteht, muss man sich damit behelfen.
Ein Vorteil, wenn man standardisierte Schnittstellen bzw. Protokolle verwendet, besteht darin, dass es bereits viele Tools gibt, die mit dieser Schnittstelle umgehen können. Würden wir die Kommunikation mittels HTTP implementieren, könnten wir mit einem normalen Web-Browser testen, ob unsere Implementierung korrekt funktioniert. Ähnlich ist es bei DBus; wie Florian schon erwähnt hat, gibt es unzählige Tools, Bibliotheken und Programme, die darauf aufsetzen. Deshalb gibt es auch Tools wie d-feet, mit dem wir uns statt die 5-Seitige XML-Antwort durchzuackern, interaktiv mit dem Interface arbeiten können.
Dies macht das Testen und Ausprobieren um ein vielfaches einfacher. So können wir die Events (Signals) über eine GUI mit beliebigen Parametern aufrufen und das Ergebnis validieren.
Ähnliches können wir auch mit Avahi machen. Mit avahi-discover können wir uns alle publizierten Services ansehen und somit gleich testen ob unser Service korrekt erkannt und publiziert wird.
Natürlich sind das keine automatisierten Tests, was wir aber in dieser explorativen Phase auch noch nicht benötigen. Ist der Kern der Anwendung dann weitgehend durchdacht und implementiert, können wir uns Gedanken über einige Testfälle machen. Diese können wir dann mit Hilfe eines Test-Frameworks wie RSpec exakt spezifizieren. Hiermit lassen sich Tests definieren, wofür die oben beschriebenen Tools nicht ausreichen. Bspw. 100 Dateien gleichzeitig an einen Client schicken oder lästige Randbedingungen wie eine Datei mit 0 Byte übertragen, Unicode-Zeichen im Dateinamen usw.
Leider ist diese Art von Tests für eine solche Anwendung etwas kniffliger. Manchmal lässt auch die verwendete Bibliothek es nicht zu, automatisierte Testfälle aufzustellen, die auf einem Rechner durchlaufen werden können. Dies ist dann der Fall wenn die Bibliothek (oder auch der eigene Programmcode) stark mit der Hardware oder der Umgebung verbunden ist. Wir hatten das Problem, dass wir DBus schlecht testen konnten, da die Ruby-Lib als Singelton implementiert ist.
Es gibt natürlich auch hier mehrere Möglichkeiten, dieses Problem zu umgehen, allerdings wollen wir es an dieser Stelle nicht zu weit treiben, da es sich hier nicht um eine hoch kritische Anwendung handelt. In der kommenden Woche werden wir uns mit den Themen Dateitransfer und Benutzerinteraktion (UI) beschäftigen.