Wie bereits für das Projekt geschehen, dient der Cucumber-Nagios-eigene Generator auch dazu, das Grundgerüst für ein neues Features zu erschaffen. Dies geschieht im Projektverzeichnis mittels
»cucumber-nagios-gen feature www.xing.com startpage
«
und hat zur Folge, dass zwei neue Dateien generiert werden (siehe
Listing 1
): Die Datei
»features/www.xing.com/startpage.feature
«
beinhaltet das Testszenario. In der Datei
»features/www.xing.com/steps/startpage _steps.rb
«
lassen sich bei Bedarf eigene Steps hinzufügen.
Listing 1
Neue Features mit integriertem Generator
Die
»startpage.features
«
umfasst bereits ein rudimentäres Beispiel, das nach Belieben abgeändert werden kann. Der Admin sieht hier bereits, dass die Syntax sich an den normalen Sprachgebrauch anlehnt und auch ohne Kenntnisse einer Programmiersprache zu beherrschen ist. Die eigentliche Programmlogik ist vorerst unsichtbar in den entsprechenden Steps hinterlegt. Allen Features gemein sind die ersten drei Zeilen.
Die ersten beiden geben dem Feature einen Namen sowie eine kurze, prägnante Beschreibung des zu erwartenden Zustands. Die Beschreibung darf dabei auch mehrere Zeilen umfassen. Im Falle von
Listing 2
beschreibt das Feature, dass die Website
»www.xing.com
«
erreichbar sein soll. Die dritte Zeile leitet dann mittels
»Scenario:
«
das zu testende Szenario ein. Alle weiteren Zeilen enthalten Anweisungen für die entsprechenden Aktionen, die der Service-Check dann auszuführen und zu evaluieren hat.
Listing 2
Erreichbarkeit von www.xing.com
Grundsätzlich finden hier zwei Aktionen statt.
»When I go to http://www.xing.com/
«
bestimmt die initiale Aktion. Das zu erwartende Ergebnis dagegen legt der Term
»Then the request should succeed
«
fest. Diese beiden Informationen reichen aus, um einen funktionsfähigen, erfolgreichen Check für Nagios zu generieren – Erreichbarkeit der Website
»http://www.xing.com
«
vorausgesetzt.
Mit dem Wort
»And
«
zu Beginn einer neuen Zeile lassen sich weitere Bedingungen für einen erfolgreichen Check definieren.
»But
«
dagegen wird benutzt, wenn es Ausschlusskriterien zu definieren gilt. Sinnvoll ist dies, wenn es darum geht, den Inhalt einer Seite zu verifizieren. Im Kontext von
Listing 2
wären also die folgenden zwei Bedingungen sinnvoll, um zu verifizieren, dass man sich auch wirklich auf der Xing-Startseite befindet:
»And I should see "Join XING for free"
«
sowie
»But I should not see "Welcome to Facebook"
«
.
Mit den Methoden
»Given
«
,
»When
«
,
»Then
«
,
»And
«
sowie
»But
«
ist die Liste der möglichen Anweisungen komplettiert. Zu beachten ist, dass Cucumber in technischer Hinsicht zwar nicht zwischen den Anweisungen unterscheidet. Es ist aber von Vorteil, die bestehenden Konventionen zu übernehmen.
»Given
«
kommt immer dann zum Einsatz, wenn ein definierter Status vorausgesetzt werden soll, beispielsweise
»Given I am on http://www.xing.com/
«
.
»When
«
dagegen beschreibt typischerweise die Aktion, die auszuführen ist. Hierzu zählen Interaktionen auf einer Website genauso wie etwa das Prüfen auf das Vorhandensein einer bestimmten Datei. Im Kontext des vorigen Beispiels wäre hier Folgendes denkbar:
» When I fill in "username-field" with "username"
«
.
»And
«
ist als Ersatz für weitere
»Given
«
-,
»When
«
- oder
»Then
«
-Anweisungen gedacht, damit das Szenario verständlicher zu lesen ist. Das Beispiel wird um folgende Anweisungen erweitert:
»And I fill in "password-field" with "password"
«
und
»And I press "login-button"
«
.
»Then
«
wiederum obliegt die Überwachung des Ergebnisses. Im konkreten Falle ist es interessant, ob das Login geklappt hat:
»Then I should see "What's new in your network"
«
.
»But
«
ist
»And
«
sehr ähnlich, definiert aber Ausschlusskriterien. Mit
»But I should not see "Join XING for free"
«
ist das Beispiel komplett. Das Feature für das Prüfen eines Login auf
»http://www.xing.com/
«
sieht demnach aus wie in
Listing 3
.
Listing 3
Login-Prüfung
In vielen Szenarien kommt es nicht nur auf die reine Funktion an, sondern auch auf die Verarbeitungszeit eines Request. Von Websites wird in der Regel höchstmögliche Performance verlangt, um des Benutzers Zeit nicht zu strapazieren. Das Performance-Monitoring via Cucumber-Nagios ist mit Hilfe der vordefinierten Methode
»Given I am benchmarking
«
möglich. Ein Beispiel könnte also wie folgt aussehen:
Scenario: Benchmarking home page Given I am benchmarking When I go to http://www.xing.com/ Then the request should succeed And the elapsed time should be lessthan 1 seconds
Hier werden gleich zwei Elemente geprüft: Ob der HTTP-Statuscode positiv ist und ob die Laufzeit des Request unter einer Sekunde liegt. Ist eine dieser Bedingungen nicht erfüllt, wird je nach Konfiguration des Monitoringsystems der Dienst als kritisch eingestuft und gegebenenfalls gewarnt.
Die eigentliche Arbeit verrichten die bereits angesprochenen Steps im Hintergrund. Dabei handelt es sich um kurze, in Ruby geschriebene Codeblöcke, die die Funktionalität des jeweiligen Checks erst bereitstellen.
Mi einem rekursiven Grep aus dem Projektverzeichnis heraus lässt sich eine nach Methoden geordnete Übersicht erstellen, welche die bereits von Cucumber-Nagios mitgelieferten Funktionen ausgibt. Diese vordefinierten Steps bieten eine solide Grundlage, um bei Bedarf eigene Steps zu definieren:
grep -R '[WT]hen\|Given' features/steps/|awk -F \: '{print $2}'|sort -d
Für einen einfachen Ping-Test ist der Step
»features/steps/ping_steps.rb
«
(
Listing 4
) zuständig. Das entsprechende Feature, um
»www.xing.com
«
via ICMP zu pingen, sieht wie folgt aus:
Listing 4
features/steps/ping_steps.rb
Feature: www.xing.com It should respond Scenario: Ping test When I ping www.xing.com Then it should respond
Eingeleitet wird jeder Step mit den Methoden
»Given
«
,
»When
«
,
»Then
«
,
»And
«
oder
»But
«
. Darauf folgt ein regulärer Ausdruck, der die in den Features verwendete Anweisung erst möglich macht.
»do
«
leitet die eigentliche Logik ein,
»|host|
«
ist die Variable, die das Feature für den getesteten Host definiert.
Wichtig hierbei ist, dass die Methoden letztlich nicht Teil des regulären Ausdrucks sind. Ob in einem Test
»When I ping ...
«
als Anweisung oder mittels
»Given I ping
«
als Vorbedingung definiert ist, bleibt demnach unter Beachtung der Given-When-Then-Konventionen von Cucumber
[8]
variabel.
Zeile 2 des Beispiels in
Listing 4
verrichtet letztlich die eigentliche Arbeit. Sie initialisiert die Instanzvariable
»@result
«
, welche die Ausgabe des Ping-Kommandos empfängt. Diese wird wiederum in den ab Zeile 5 folgenden Steps evaluiert, woraufhin der Rückgabewert entweder auf
»true
«
(Host erreichbar) oder
»false
«
(Host nicht erreichbar) gesetzt wird.
Wer das Beispiel jetzt erweitern und den Autor des Testszenarios in die Lage versetzen will, die Anzahl der zu sendenden Pings zu definieren, passt den regulären Ausdruck an und fügt die entsprechende Variable hinzu:
When /^I ping (.*) (.*) times$/ do |host,count| @result = system("ping -c #{count} #{host} > /dev/null 2>&1") end
Nun lässt sich in dem zugehörigen Feature mit
When I ping www.xing.com 3 times Then it should respond
die Anzahl der zu sendenden Pakete definieren.