Mehr als Strings – Wie Sie Objektvariablen ab QF-Test 9 effektiv nutzen
Inhalt
00:00 Intro
02:25 Bis QF-Test 8: Alle Variablen sind Zeichenketten
05:45 Ab QF-Test 9: Variablen speichern Original-Objekt
08:05 Darstellung in Protokoll und UI
13:30 Ersetzung von Variablenwerten (expand)
19:20 Vereinfachter Zugriff in Skripten
24:28 Standardwerte
28:06 Rückgaben in Prozeduren
31:34 Konvertierung bei Bedarf
40:56 Austausch Variablen QF-Test <-> SUT
49:00 Zusätzliche Informationen
53:00 Anwendungsbeispiel: Konfigurationen
59:00 Anwendungsbeispiel: Prozess-Parameter
Code-Beispiele und Zusammenfassung
Bis QF-Test 8: Alle Variablen sind Zeichenketten
Einfache Zuordnung: Name (String) -> Wert (String)
Automatische Konvertierungen
Schreiben:
rc.setGlobal("Zahlwert", 23) // -> Konvertiert in den String "23"
rc.setLocal("Wahrheitswert", true) // -> Konvertiert in den String "true"
rc.setProperty("Objekt", new Object()) // -> Konvertiert in den String "java.lang.Object@29f364c"
Lesen:
rc.getStr(…) // -> liefert direkt den Variablenwert
rc.getBool(…) // -> Wert in ("1","y","yes","true","True",…) ?
rc.getInt(…) // -> Integer.valueOf(Wert) / new BigInteger(Wert)
Ab QF-Test 9: Variablen speichern Original-Objekt
Neue Zuordnung: Name (String) -> VariableData
Mit:
- Wert (beliebiges Objekt):
.getObject()
- Stringwert (String):
.toString()
- Beschreibung (String):
.getDescription()
Beim Zugriff ändert sich „von außen“ nichts:
- Wie bisher:
$(name)
bzw.${gruppe:name}
- Wie bisher:
rc.getStr(…)
,rc.getInt(…)
,rc.getBool(…)
, … - Neu:
rc.getObj(name)
bzw.rc.getObj(gruppe, name)
Darstellung in Protokoll und UI
Ersetzung von Variablenwerten (expand)
rc.setLocal('ext', 'TXT')
rc.setLocal('filename', 'qftest.$(ext)')
rc.getStr('filename', expand:true) // -> 'qftest.TXT'
rc.getStr('filename', expand:false) // -> 'qftest.$(ext)'
rc.getStr('filename') // ?
rc.getStr('filename', expand:null) // -> 'qftest.TXT'
rc.setLocal('regexp', Pattern.compile('abc$(ext)'))
rc.getStr('regexp', expand:true) // -> 'abcTXT'
rc.getStr('regexp', expand:false) // -> 'abc$(ext)'
rc.getStr('regexp') // -> 'abc$(ext)' – neu!
Vereinfachter Zugriff in Skripten
obj1 = rc.getObj('varname')
rc.setLocal('answer',42)
obj2 = rc.getObj('groupname','propname')
dir = rc.getObj('qftest','suite.dir')
xxx = rc.getObj('decrypt','C2094F52F62C0D7953E0CEFF81E269A7')
rc.setProperty('neueGruppe','neuerName','neuerWert')
obj1 = rc.vars.varname
rc.vars.answer = 42
obj2 = rc.groups.groupname['propname'] = rc.groups.groupname.propname
dir = rc.groups.qftest['suite.dir'] = rc.groups.qftest.suite.dir
xxx = rc.groups.decrypt['C2094F52F62C0D7953E0CEFF81E269A7']
rc.groups.neueGruppe.neuerName = neuerWert
Standardwerte
dflt = rc.getObj('default','unknown:Standardwert')
dflt = rc.groups.default['unknown:Standardwert']
dflt = rc.withDefault('Standardwert').vars.unknown
gd = rc.withDefault('Standardwert').groups.unknowngrp.unknownprop
dflt = rc.withDefault('Standardwert').getObj('unknown')
gd = rc.withDefault('Standardwert').getObj('unknowngrp','unknownprop')
Rückgaben in Prozeduren
throw new ReturnException('NeuerWert')
rc.returnValue('NeuerWert')
rc.returnValue(myObject)
value = qf.wrapObject(myObject)
value = qf.wrapObject(myObject,'String-Wert','Beschreibung')
rc.returnValue(value)
Konvertierung bei Bedarf
- Bei Ersetzungen in Kombinationen: -> String
"Ich werde heute $(age) Jahre alt."
"${qftest:suite.dir}/test.png"
- Vollständige Ersetzung -> Objekt-Type bleibt erhalten!
"$(data)"
- Weiterhin Automatisch:
rc.getInt(…)
,rc.getNum(…)
,rc.getStr(…)
,rc.getBool(…)
- Explizit mit der speziellen Gruppe „as“:
- String-Expansion:
${as:int:23}
,${as:bool:$(is_available)}
- String-Expansion:
rc.getObj('as','int:23')
rc.getObj('as','bool:$(is_available)')
Gültige Type-Werte:
- str, bool, number, object, pattern, int, long, float, double, cmdline, json
Austausch Variablen QF-Test <-> SUT
- QF-Test und die getestete Anwendung laufen in unterschiedlichen Prozessen
- Datenaustausch über RMI (Java Remote Method Invocation)
- Auch Objekte in Variablen
- Müssen „Serialisierbar“ sein
- Die Klassendefinition muss in beiden Prozessen verfügbar sein
- Klappt zum Beispiel mit Standardklassen:
- String, Wrapper (Integer, Boolean, …), Pattern, Date
- ArrayLists, HashSets (abhängig vom Inhalt)
- Fallback auf „String-Wert“ im anderen Prozess
- Im Original-Prozess weiterhin als Objekt (+String) verfügbar
Zusätzliche Informationen
- Decrypted-Flag
- Wird gesetzt, sobald
${decrypt:…}
expandiert wird. - Die „Beschreibung“ des Wertes (z.B. im Protokoll) ist immer „***“
rc.logMessage(rc.getStr("geheim"))
loggt dennoch den wahren Wert!- Wird bei Expansion „vererbt“
- Wird gesetzt, sobald
- AutoExpandable-Flag
- Verhindert, dass in Zeichenketten „aus Versehen“ Variablen ersetzt werden
- Zum Beispiel im Rückgabewert von
qfs.utils.readTextFromFile
rc.returnValue(text, autoExpandable: false)
wrapped = qf.wrapObject(text); wrapped.setAutoExpandable(false)
- Rerun aus dem Protokoll
- Nur für bestimmte (einfache) Objekte verfügbar