10. Juli 2019
Veni, vidi, variavi - Variablenverwendung
Es führt kein Weg daran vorbei: Soll eine Testsuite flexibel, wiederverwendbar und elegant sein, müssen Variablen verwendet werden. Nur wo kann ich Variablen definieren? Welcher der Werte, die ich meiner Variable auf mehrere unterschiedliche Arten vergeben habe, wird letztlich bei der Testausführung genutzt? Und wie kann ich das herausfinden? Diese Fragen versuche ich heute in diesem überdurchschnittlich „v“-lastigen Blogbeitrag zu beantworten.
Welche Variable wird verwendet?
Variablen werden auf zwei Stapeln gespeichert: einem Primär- und einem Sekundärstapel. Auf letzterem werden Rückfallwerte (also auf gut deutsch Defaultwerte) gespeichert, die nur abgerufen werden, sollte sich keine direkte Zuordnung auf dem Primärstapel finden lassen. Diese Stapel sind nicht versteckt, sondern lassen jederzeit zu Programmlaufzeit in QF-Test einsehen. Beispielsweise indem man die Durchführung eines Testlaufs pausiert oder mit der Debug-Funktion arbeitet. Zudem wird der Variablenstack bei einem Fehler im Protokoll aufgelistet (Abb. 1).
Wenn nun der Wert einer Variable benötigt wird, versucht QF-Test diesen im Stack zu finden. Dafür arbeitet es sich „von oben nach unten durch“. Zuerst werden explizite Zuordnungen im Primärstapel gesucht, wobei hier die höheren Definitionen eine höhere Bindungskraft besitzen. Sollte ich die selbe Variable einmal am Anfang für die gesamte Testsuite gesetzt haben, aber später noch einmal in einem kleinen Testfall, wird die Definition aus dem Testfall als Variablenwert genutzt. Sollte sich allerdings nichts im Primärstapel befinden, wird der Sekundärstapel nach Defaultwerten durchsucht.
Dieser Stacktrace hier (Abb. 2) kann zur Visualisierung des Vorgangs verwendet werden. Innerhalb der „Beispielprozedur“ wurde „Variable1“ ein Defaultwert zugewiesen. Beim Aufruf der Prozedur wurde der Wert allerdings explizit auf „nicht default“ gesetzt und der Standardwert auf dem Sekundärstapel somit überschrieben.
Wo sind Variablen definierbar?
Die Möglichkeiten, Variablen zu setzen, sind vielfältig. Unter Bearbeiten → Optionen → Variablen lassen sich bereits die ersten Variablen setzen, bevor die Testsuite überhaupt etwas beinhaltet. Die Gewichtung der unterschiedlichen Variablenkategorien (Systemspezifische Variablen, Variablen der aktuellen Testsuite, Variablen der Kommandozeile, Globale Variablen) lassen sich ebenfalls aus dem Stacktrace (Abb. 2) erkennen.
Wo immer sich die bearbeitbare Tabelle „Standardwerte für Parameter“ finden lässt, lassen sich Defaultwerte für unseren Sekundärstapel setzen.
Innerhalb eines Testfalles oder einer Prozedur kann auch jederzeit ein „Variable setzen“-Knoten auftauchen, um explizit Variablenwerte festzulegen.
Natürlich lassen sich auch Werte aus dem zu testendem Programm auslesen, beispielsweise der Text aus einer Tabellenzelle. Die simpelste Vorgehensweise ist es, einen Mausklick auf das Element aufzunehmen, welches überprüft werden soll, und diesen daraufhin in den gewünschten Knoten zu konvertieren. Das Ergebnis aus dem „Text auslesen“ lässt sich jetzt als Variable mit beliebigem Namen abspeichern und später verwenden. In (Abb. 3) sind die Eigenschaften eines solcher Knoten zu sehen – auffällig ist, dass dieser ein Häkchen bei „Lokale Variable“ vorweist. Warum?
In einem Versuch es möglichst knapp zu erklären: Globale Variablen existieren von ihrer Schöpfung an bis zum Ende allen Seins (des QF-Test Prozesses oder ihrer expliziten Löschung) – auch in anderen, eventuell unzusammenhängenden Testsuites. Das ist einfach zu verstehen, einfach zu verwenden – und führt genauso einfach zu vermeidbaren Fehlern, bei denen die Variable unabsichtlich irgendwo anders überschrieben oder seit einer früheren Testausführung nicht wieder neu gesetzt wurde.
Lokale Variablen sind nach ihrer Festlegung zusammen mit dem Knoten, auf dem sie gültig sind, im Variablenstack zu finden. Der zugehörige Knoten lässt sich unter Verwendung von Debugging erkennen, wie später beschrieben wird. Erfolgt die Definition beispielsweise irgendwo innerhalb eines Testfalls, ist die Variable innerhalb dieses Testfalls und aller untergeordneten Testschritte, Sequenzen etc. bekannt. Nachdem dieser Knoten durchlaufen ist und sein Stapel vom Stacktrace verschwindet, befreien sich folglich auch alle zugehörigen lokalen Variablen von ihren Zuweisungen und Zwängen und treten ins Nirwana ein.
Somit können bei komplexen und umfangreichen Testsuiten versteckte Seiteneffekte vermieden werden.
Zuletzt gibt es da noch Skripte. Eine Variable kann recht einfach in einem Server- oder SUT-Skript erzeugt oder geändert werden.
Einige Beispiele sind in (Abb. 4) zu sehen:
Vor allem bei der Arbeit mit Skripten gilt es zu bedenken, dass alle Variablen in QF-Test grundsätzlich immer als Strings abgespeichert werden! Also nicht vergessen die Variablen (zum Beispiel für Rechnungen) in den gewünschten Typ umzuwandeln, beziehungsweise wie im Beispiel gezeigt mit der richtigen rc-Methode auszulesen.
Wie finde ich den aktuellen Wert einer Variablen heraus?
Defaultwerte in Prozeduren, Testfallsätzen, Testfall- und Prozeduraufrufe mit eigenen Variablen Definitionen, globale Variablen die seit Beginn des Testfalls ihr Unwesen treiben: Da kann man schon einmal den Überblick verlieren, welche Variable gerade welchen Wert angenommen hat. Um dieser Verwirrung entgegenzuwirken gibt es zwei sehr einfache Möglichkeiten:
1. Das klassische „print-debugging“.
An der gewünschten Stelle einfach ein Skript hinzufügen mit qf.println(rc.lookup("Variablenname")), schon erscheint der aktuelle Wert der Variable im Terminal. Die „qf.print“-Methode funktioniert ab Version 4.6 in jeder von QF-Test unterstützten Skriptsprache – natürlich kann auch die skriptspezifische „print“-Methode verwendet werden. Wenn „print“ durch „rc.logMessage“ oder „rc.logError“ ersetzt wird, erscheint der Wert sogar im Protokoll. Wie beim Zelten sollte man danach aber wieder aufräumen, damit keine hässlichen „print“-Statements den sauberen Test entstellen.
2. Normales Debugging.
Mit Strg+F8(Mac: ⌘+⇧+B) lässt sich schnell ein Breakpoint einschalten. Wenn der Testfall ausgeführt wird, stoppt QF-Test den Durchlauf am Breakpoint und wechselt in den Debugging-Modus. Jetzt lassen sich Testschritte mit diesen (Abb. 5) hilfreichen Knöpfen einzeln durchführen, und ein Variablentab neben dem Terminal zeigt den aktuellen Stacktrace an (Abb. 6). Die oberste Definition der Variablen im Stapel ist der aktuell verwendete Wert.