Verifikation von Testergebnissen

Inhalt

Top1 Prüfung aufgezeichneter Testereignisse

Für die Überwachung von Kommunikationsabläufen zwischen dem zu testenden Teilsystem und seiner Umgebung werden alle relevanten Ereignisse (typischerweise Methodenaufrufe an die simulierten Objekte oder andere Aktivitäten, die im Test beobachtet werden können) in einem Vektor aus Ereignis-Strings aufgezeichnet.

Eine ausführlichere Darstellung dieses Prinzips findet sich in Zentralisierte Erfassung der Testereignisse (TestEvents).

Ausgangssituation
Nach der Ausführung der für einen Testfall vorgesehenen Aktionen liegen beispielsweise folgende Aufzeichnungen im Ereignis-Vektor vor:

TestEvents after recording

Zusammen mit einigen intern verwendeten Steuervariablen ergibt sich daraus folgendes Bild:

TestEvents after recording

Prinzip: Prüfung auf Textgleichheit und Reihenfolge
Zur Überprüfung auf Korrektheit müssen die aufgezeichneten Ereignisse einzeln verifiziert werden. Ein Ereignis gilt dabei als "erfolgreich" überprüft, wenn der Ereignis-String identisch ist mit einem im Testscript vorgegebenen Vergleichsstring:
TTB_EXP("Number: 2";)
Neben der Übereinstimmung des Ereignis-Strings selbst können unterschiedliche Anforderungen bzgl. der erlaubten Reihenfolgen für die aufgezeichneten Ereignisse bestehen. Für die korrekte Auswahl der verfügbaren Verifikations-Algorithmen ist ein Grundverständnis der prinzipiellen Abläufe hilfreich. Die folgenden Abschnitte geben dazu die notwendige Hilfestellung.

Top1.1 Strikte Ereignisreihenfolgen (TTB_EXP)

Eine strikte Ereignisreihenfolge wird dann erwartet, wenn die aufgezeichneten Ereignisse stets in der gleichen Reihenfolge auftreten müssen.

Dies ist häufig dann der Fall, wenn im betrachteten System

  • keine Parallelitäten/Multithreading-Effekte auftreten oder
  • aus logischen Gründen die Ereignisse nacheinander auftreten müssen.

Top1.1.1 Schematische Darstellung der Verifikationsschritte

Prinzip
  • Das Ereignis wird direkt an der aktuellen Check-Position erwartet.
  • Die aktuelle Check-Position wird auf die nächste noch nicht verifizierte Position gesetzt.

Top1.1.1.1 Schritt 1: Überprüfung des als erstes erwarteten Ereignisses

TestEvents 1 Ok

Da das erwartete 1. Ereignis mit dem 1. Eintrag im Ereignis-Vektor übereinstimmt, wird das Zustandsflag auf true ("OK") gesetzt. Gleichzeitig wird die als nächstes zu prüfende Position inkrementiert.

Top1.1.1.2 Schritt 2: Überprüfung des als zweites erwarteten Ereignisses

TestEvents 2 Ok

Analog zum 1. Schritt wird das betreffende Zustandsflag gesetzt und die als nächstes zu prüfende Position inkrementiert.

Top1.1.1.3 Weitere Schritte: Überprüfung der restlichen erwarteten Ereignisse

TestEvents all Ok

Da alle Ereignisse wie erwartet eingetroffen sind, wurden alle Zustandsflags auf true ("OK") gesetzt. Die als nächstes zu prüfende Position zeigt "hinter" den letzten Eintrag im Vektor. Falls nachfolgend im Testverlauf ein weiteres Ereignis aufgezeichnet wird, kann es unter dieser Position überprüft werden.

Top1.1.2 Formulierung im Testscript

Im Testscript sieht die Sequenz durchgeführter Prüfungen folgendermaßen aus:
TTB_EXP ("Number: 2");
TTB_EXP ("Number: 4");
TTB_EXP ("double value: 88.88");
TTB_EXP ("Number: 6");
TTB_EXP ("double value: 66.66");

Top1.2 Sequentiell aufeinanderfolgende Ereignisse (TTB_EXP_SEQ)

Für viele Systeme muss als wesentliche Eigenschaft nachgewiesen werden, dass bestimmte charakteristische Ereignisse nacheinander auftreten. Dabei ist es jedoch oft gleichzeitig zulässig, dass die nachzuweisende Sequenz von Ereignissen durch andere Ereignisse überlagert wird.

Eine mögliche Ursache kann darin bestehen, dass parallel zu einem sequentiell stattfindenden Ablauf andere Ereignisse aufgrund von Multithreading an zufälliger Stelle "eingestreut" werden.

So kann die unter "Ausgangspunkt" (siehe oben) beschriebene Situation als Überlagerung zweier sequentieller Abläufe verstanden werden:

  • sequentielle Abfolge der steigenden Zahlenfolge 2, 4, 6
  • sequentielle Abfolge der fallenden Zahlenfolge 88.88, 66.66

Top1.2.1 Schematische Darstellung der Verifikationsschritte

Prinzip
  • Das Ereignis wird irgendwo ab der aktuellen Check-Position bis zum Ende des Ereignis-Vektors gesucht.
  • Die aktuelle Check-Position wird auf die nächste noch nicht verifizierte Position nach dem gefundenen Ereignis gesetzt.

Top1.2.1.1 Schritt 1a: Überprüfung des als erstes erwarteten Ereignisses der ersten Sequenz

TestEvents seq ok 1

Da das als erstes erwartete Ereignis mit dem 1. Eintrag im Ereignis-Vektor übereinstimmt, wird das Zustandsflag auf true ("OK") gesetzt. Gleichzeitig wird die als nächstes zu prüfende Position inkrementiert. Der Ablauf ist zunächst identisch wie bei der Prüfung auf strikte Reihenfolge.

Top1.2.1.2 Schritt 1b: Überprüfung des als zweites erwarteten Ereignisses der ersten Sequenz

TestEvents seq ok 2

Analog zum 1. Schritt wird das betreffende Zustandsflag gesetzt und die als nächstes zu prüfende Position inkrementiert. Auch hier ist der Ablauf zunächst identisch wie bei der Prüfung auf strikte Reihenfolge.

Top1.2.1.3 Schritt 1c: Überprüfung des als drittes erwarteten Ereignisses der ersten Sequenz

TestEvents seq ok 3

Bei der Suche nach dem dritten Ereignis wird der nicht passende nächste Eintrag an Position 2 übersprungen, anschliessend das Zustandsflag für den passenden Eintrag an der nachfolgenden Position 3 auf true gesetzt. Zuletzt wird die als nächstes zu prüfende Position inkrementiert.

Top1.2.1.4 Schritt 2a: Rücksetzen der "Checkposition" vor Prüfung der zweiten Sequenz

TestEvents seq ok 4 reset

Bevor der erste Eintrag der zweiten Sequenz überprüft wird, muss die als nächstes zu prüfende Check-Posiiton zurückgesetzt werden. Nach dem Zurücksetzen zeigt die Check-Position auf die erste noch nicht überprüfte Position innerhalb des Ereignisvektors.

Top1.2.1.5 Schritt 2b: Überprüfung des als erstes erwarteten Ereignisses der zweiten Sequenz

TestEvents seq ok 5

Bei der Suche nach dem ersten Ereignis wird das Zustandsflag für den passenden Eintrag an der Position 2 auf true gesetzt. Anschliessend wird die als nächstes zu prüfende Position auf Position 4 inkrementiert. Der bereits überprüfte Eintrag 3 wird dabei übersprungen. Dadurch ist gewährleistet, dass die Check-Position immer auf einen noch nicht verifizierten Eintrag zeigt.

Top1.2.1.6 Schritt 2c: Überprüfung des als zweites erwarteten Ereignisses der zweiten Sequenz

TestEvents seq ok 5

Bei der Suche nach dem zweiten Ereignis der zweiten Sequnez wird das Zustandsflag für den passenden Eintrag an der Position 4 auf true gesetzt. Anschliessend wird die als nächstes zu prüfende Position auf die nicht vorhandene Position 5 inkrementiert.

Top1.2.2 Formulierung im Testscript

Im Testscript sieht die Sequenz durchgeführter Prüfungen folgendermaßen aus:
// Check that the small numbers have occured in increasing order
TTB_EXP_SEQ ("Number: 2");
TTB_EXP_SEQ ("Number: 4");
TTB_EXP_SEQ ("Number: 6");

// Go back to first unchecked position within the array of events
TheTestEvents()->ResetCurrentCheckPosition();

// Check that the big numbers have occured in decreasing order
TTB_EXP_SEQ ("double value: 88.88"); 
TTB_EXP_SEQ ("double value: 66.66");
Alternativ kann durchgägig das Makro TTB_EXP verwendet werden:
// Alternatively you can also use TTB_EXP and set the required CheckMode
TheTestEvents()->SetCheckType(CheckType::eSEQUENTIAL);

// Check that the small numbers have occured in increasing order
TTB_EXP ("Number: 2");
TTB_EXP ("Number: 4");
TTB_EXP ("Number: 6");

// Go back to first unchecked position within the array of events
TheTestEvents()->ResetCurrentCheckPosition();

// Check that the big numbers have occured in decreasing order
TTB_EXP ("double value: 88.88"); 
TTB_EXP ("double value: 66.66");

Top1.3 Variable Ereignisreihenfolgen (TTB_EXP_VAR)

Für manche Ereignisse kann nicht präzise vorhergesagt werden, in welcher Reihenfolge sie auftreten. Für derartige Ereignisse ist es hinreichend, zu prüfen, dass sie an irgendeiner Stelle im Ablauf aufgetreten sind.

Warnung und Hinweis: Bevorzugung möglichst strenger Prüfungen
Ein Tester sollte sich nicht aus Bequemlichkeit darauf beschränken, lediglich auf das Vorhandensein eines Ereignisses zu prüfen. Selbst wenn die Anforderungen an ein SW-System keine Aussage über Ereignis-Reihenfolgen beinhalten, wird es häufig so sein, dass die gewählte Implementierungs-Strategie eine bestimmte Abarbeitungsreihenfolge verursacht.

Geht man immer nach dem Prinzip der "Maximal-Prüfung" vor, d.h. prüft man immer dann auf Reihenfolgen, wenn sie von der aktuell gewählten Implementierungslösung garantiert werden, so erhält man einen besseren Prüfstein für spätere Refakturierungen. Unbeabsichtigte Veränderungen in der Abarbeitungsreihenfolge werden dann zuverlässig aufgedeckt. Eine Abschwächung der Prüfung bzgl. der Ereignis-Reihenfolgen bzw. eine Umdefinition der Reihenfolgen sollte dann erst bei Bedarf zum Zeitpunkt der Refakturierung erfolgen.

Top1.3.1 Schematische Darstellung der Verifikationsschritte

Prinzip
  • Das Ereignis wird unabhängig von der aktuellen Check-Posiiton überall im Ereignis-Vektor gesucht. Die Suche beginnt dabei am Anfang des Vektors.
  • Die aktuelle Check-Position wird nur dann verändert, wenn das Ereignis an dieser Position gefunden wird. Die aktuelle Check-Posiiton wird dann so angepasst, dass sie stets auf ein noch nicht verifiziertes nachfolgendes Ereignis zeigt.

Top1.3.1.1 Schritt 1: Überprüfung des ersten Ereignisses

TestEvents var ok 1

Das als erstes zu prüfende Ereignis befindet sich an der zweiten Stelle des Ereignisvektors. Dementsprechend wird das Zustandsflag am Position 1 auf true ("OK") gesetzt. Die als nächstes zu prüfende Check-Position zeigt unverändert auf Position 0.

Top1.3.1.2 Schritt 2: Überprüfung des zweiten Ereignisses

TestEvents var ok 2

Das als nächstes zu prüfende Ereignis befindet sich an der ersten Stelle des Ereignisvektors. Dementsprechend wird das Zustandsflag am Position 0 auf true ("OK") gesetzt. Die als nächstes zu prüfende Check-Position wird auf die nächste noch nicht überprüfte Position 2 gesetzt.

Top1.3.1.3 Schritt 3: Überprüfung der restlichen erwarteten Ereignisse

TestEvents var ok 3

Nach den gleichen Prinzipien werden die restlichen Ereignis-Strings überprüft. Die aktuelle Check-Positzion wird jeweils dann verschoben, wenn ihr Eintrag überprüft wurde. Zuletzt zeigt sie auf Position 5, also hinter den letzten existierenden Eintrag.

Top1.3.2 Formulierung im Testscript

Im Testscript sieht die Sequenz durchgeführter Prüfungen folgendermaßen aus:
// Check that events have have occured in any order
TTB_EXP_VAR ("Number: 4");
TTB_EXP_VAR ("Number: 2");
TTB_EXP_VAR ("double value: 66.66");
TTB_EXP_VAR ("Number: 6");
TTB_EXP_VAR ("double value: 88.88");
Alternativ kann durchgängig das Makro TTB_EXP verwendet werden:
// Alternatively you can also use TTB_EXP and set the required CheckMode
TheTestEvents()->SetCheckType(CheckType::eVARIABLE);

// Check that events have have occured in any order
TTB_EXP ("Number: 4");
TTB_EXP ("Number: 2");
TTB_EXP ("double value: 66.66");
TTB_EXP ("Number: 6");
TTB_EXP ("double value: 88.88");

Top1.4 Anzeige typischer Fehlersituationen

Top1.4.1 Erwartetes Ereignis ist nicht an exakt erwarteter Position (TTB_EXP)

TestEvents err ok 1

Neben der im Diagramm rot dargestellten Fehlermeldung werden zusätzlich im Test-Protokoll Angaben zum aktuellen Zustand des Ereignis-Vektors ausgegeben:

List of stored TestEvents (current check position = 1, used checkType = eSTRICT) 
   Ok   0: Number: 2
##  ?   1: Number: 4
    ?   2: double value: 88.88
    ?   3: Number: 6
    ?   4: double value: 66.66
Mögliche Ursachen
  • Das erwartete Ereignis ist gar nicht eingetreten
  • Anstelle des erwarteten Ereignisses ist ein anderes Ereignis eingetreten
  • Die tatsächlich beobachtete Ereignisreihenfolge weicht von den Erwartungen ab (siehe Diagramm)

Top1.4.2 Erwartetes Ereignis ist nicht an einer der nachfolgenden Positionen (TTB_EXP_SEQ)

TestEvents err ok 2

Neben der im Diagramm rot dargestellten Fehlermeldung werden zusätzlich im Test-Protokoll Angaben zum aktuellen Zustand des Ereignis-Vektors ausgegeben:

List of stored TestEvents (current check position = 3, used checkType = eSEQUENTIAL) 
   Ok   0: Number: 2
    ?   1: Number: 4
   Ok   2: double value: 88.88
##  ?   3: Number: 6
    ?   4: double value: 66.66
Mögliche Ursachen
  • Das erwartete Ereignis ist gar nicht eingetreten
  • Anstelle des erwarteten Ereignisses ist ein anderes, mit zumindest leichten Unterschieden im zugehörigen Text eingetreten
  • das erwartete Ereignis liegt an unerwarteter Stelle im Ereignis-Vektor (siehe Diagramm), ggf. muss die Prüfreihenfolge angepasst werden.

Top1.4.3 Erwartetes Ereignis wurde nicht aufgezeichnet (TTB_EXP_VAR)

TestEvents err ok 3

Neben der im Diagramm rot dargestellten Fehlermeldung werden zusätzlich im Test-Protokoll Angaben zum aktuellen Zustand des Ereignis-Vektors ausgegeben:

List of stored TestEvents (current check position = 3, used checkType = eVARIABLE) 
   Ok   0: Number: 2
   Ok   1: Number: 4
   Ok   2: double value: 88.88
##  ?   3: Number: 6
    ?   4: double value: 66.66
Mögliche Ursachen
  • Das erwartete Ereignis ist gar nicht eingetreten
  • Das Ereignis wurde bereits erfolgreich überprüft und wird ein weiteres mal erwartet, ist aber nicht mehr eingetreten (siehe Diagramm)

Top1.5 Expliziter Vergleich von Ereignis-Positionen

Alternativ oder ergänzend zur Überprüfung der Ereignis-Reihenfolgen über die verschiedenen Varianten der TTB_EXP-Makros können die aufgefundenen Positionen der einzelnen Ereignisse innerhalb des Ereignis-Vektors abgefragt und beliebig numerisch verglichen werden.

Top1.5.1 Variante 1: Direkter int-Returnwert von TTB_EXP

int pos_2 = TTB_EXP_SEQ ("Number: 2");
TTB_EXP_SEQ ("Number: 4");
TTB_EXP_SEQ ("Number: 6");
int pos_6666 = TTB_EXP_VAR ("double value: 66.66");
TTB_EXP_VAR ("double value: 88.88"); 

// Check found positions
TTB_CHECK_EQUAL (pos_2+4, pos_6666);
TTB_CHECK_COND (pos_2 < pos_6666)
TTB_CHECK (pos_2, std::less(), pos_6666)

Top1.5.2 Variante 2: Lesbarer mit nachgelagertem StorePos()

int pos_2;
int pos_6666;

TTB_EXP_SEQ ("Number: 2"). StorePos(pos_2);
TTB_EXP_SEQ ("Number: 4");
TTB_EXP_SEQ ("Number: 6");
TTB_EXP_VAR ("double value: 66.66"). StorePos(pos_6666);
TTB_EXP_VAR ("double value: 88.88"); 

// Check found positions
TTB_CHECK_EQUAL (pos_2+4, pos_6666);
TTB_CHECK_COND (pos_2 < pos_6666)
TTB_CHECK (pos_2, std::less(), pos_6666)

Top1.5.3 Variante 3: Globale Methode GetLastEventPosition()

Die beim letzten Aufruf eines TTB-EXP-Makros gefundene Event-Position ist über TestEvents::GetLastEventPosition() abfragbar. Insbesondere bei Verwendung der Streaming-Makros TTB_EXP_S ist dies die einzige Möglichkeit an die Ereignis-Position zu gelangen.
int pos_2;
int pos_6666;

TTB_EXP_SEQ ("Number: 2"); pos_2=TheTestEvents()->GetLastEventPosition();
TTB_EXP_SEQ ("Number: 4");
TTB_EXP_SEQ ("Number: 6");
TTB_EXP_VAR ("double value: 66.66"); pos_6666=TheTestEvents()->GetLastEventPosition();
TTB_EXP_VAR ("double value: 88.88"); 

// Check found positions
TTB_CHECK_EQUAL (pos_2+4, pos_6666);
TTB_CHECK_COND (pos_2 < pos_6666)
TTB_CHECK (pos_2, std::less(), pos_6666)

Top1.6 Formatierung von Werten

Top1.6.1 printf-Syntax mit Format-Flags

Die in den Ereignis-Strings enthaltenen (numerischen) Werte können mit Formatflags der herkömmlichen printf-Syntax formatiert werden.

Diese Syntax ist zwar eigentlich zu vermeidender "old style", bietet aber trotzdem eine einfache und praktikable Möglichkeit, um relativ übersichtlich auf kleinem Raum die notwendigen Formatierungen durchzuführen. Die damit einhergehenden, bekannten Sicherheitsrisiken (z.B. versehentliche Verwendung nicht kompatibler Formatflags, falsche Anzahl nachfolgender Parameter) können in Testumgebungen aber in Kauf genommen werden, da sie bei der Testausführung in der Regel sofort entdeckt werden.

Wie bei printf ist die Anzahl der möglichen Parameter variabel. Da die Überprüfung jedoch über Makros vorgenommen werden, muss die jeweilige Anzahl verwendeter Parameter am Ende des Makros ergänzt werden.

Beispiel
Die nachfolgenden Formatierungen
TTB_EXP1     ("Number: %d", 2);
TTB_EXP2     ("%s: %d", "Number", 4);
TTB_EXP_SEQ1 ("Number:%2d", 6);
TTB_EXP_SEQ1 ("Number:%s", " 8");
TTB_EXP_SEQ2 ("Number: %c%c", '1', '0');

TTB_EXP_VAR1 ("double value: %s", "88.88"); 
TTB_EXP_VAR1 ("double value: %.2f", 66.66);
TTB_EXP_VAR1 ("double value: %.2f", 44.4423); // values are rounded before compare
TTB_EXP_VAR1 ("double value:%6.2f", 22.219);  // values are rounded before compare
generieren folgende Formate:
TTB_EXP     ("Number: 2");
TTB_EXP     ("Number: 4");
TTB_EXP_SEQ ("Number: 6");
TTB_EXP_SEQ ("Number: 8");
TTB_EXP_SEQ ("Number: 10",);

TTB_EXP_VAR ("double value: 88.88"); 
TTB_EXP_VAR ("double value: 66.66");
TTB_EXP_VAR ("double value: 44.44");
TTB_EXP_VAR ("double value: 22.22);
Häufig verwendete Format-Flags
%s String-Wert
%d ganzzahliger Wert
%8d ganzzahliger Wert, Ausgabe 8 stellig mit führenden Leerzeichen
%.2f Float-Wert mit 2 Nachkommastellen, Wert wird gerundet
%8.2f Float-Wert mit 2 Nachkommastellen und insgesamt 8 stelliger Anzeige mit führenden Leerzeichen

Weitere Informationen siehe printf Format-Flags (cplusplus.com)

Top1.6.2 Stream-Syntax mit Manipulatoren (TTB_EXP_S)

Die in den Ereignis-Strings enthaltenen (numerischen) Werte können mit regulärer Stream-Syntax und Stream-Manipulatoren formatiert werden.

Unterstützt wird diese Syntax durch entsprechende Makros mit Endung _S: TTB_EXP_S, TTB_EXP_VAR_S, TTB_EXP_SEQ_S.

Beispiel
Die nachfolgenden Formatierungen
TTB_EXP_S     ("Number: " << 2);
TTB_EXP_S     ("Number" << ": " << 4);
TTB_EXP_SEQ_S ("Number:" << std::setw(2) << 6);
TTB_EXP_SEQ_S ("Number:" << " 8");
TTB_EXP_SEQ_S ("Number: " << '1' << '0');

TTB_EXP_VAR_S ("double value: " << "88.88"); 
TTB_EXP_VAR_S ("double value: " << std::fixed << std::setprecision(2) << 66.66); 
TTB_EXP_VAR_S ("double value: " << std::fixed << std::setprecision(2)
    << 44.4423); // values are rounded before compare
TTB_EXP_VAR_S ("double value:" << std::setw(6) << std::fixed << std::setprecision(2)
    << 22.219); // values are rounded before compare
generieren folgende Formate:
TTB_EXP     ("Number: 2");
TTB_EXP     ("Number: 4");
TTB_EXP_SEQ ("Number: 6");
TTB_EXP_SEQ ("Number: 8");
TTB_EXP_SEQ ("Number: 10",);

TTB_EXP_VAR ("double value: 88.88"); 
TTB_EXP_VAR ("double value: 66.66");
TTB_EXP_VAR ("double value: 44.44");
TTB_EXP_VAR ("double value: 22.22);
Häufig verwendete Formate
setw(4) 4-stellige Ausgabe mit führenden Leerzeichen, rechtsbündig
fixed Float-Wert mit Dezimalpunktanzeige, ohne Verwendung von "1e-N"
setprecision(3) Verwendung von 3 Nachkommastellen (Voraussetzung: gleichzeitige Angabe von "fixed" oder "scientific")
left linksbündige Ausgabe
boolalpha Ausgabe von Bool-Ausdrücken als "true" oder "false"

Weitere Informationen siehe Stream manipulators (cplusplus.com)

Einschränkung: Zugriff auf Position eines Ereignisses
Die Makros mit Endung "_S" besitzen keinen Returnwert. Somit ist die Abfrage der gefundenen Position eines Ereignisses innerhalb des Ereignis-Vectors lediglich über die Methode "TestEvents::GetLastEventPosition" möglich.

Beispiel:

int pos_4;
int pos_6;

TTB_EXP_S     ("Number: " << 2);
TTB_EXP_S     ("Number" << ": " << 4);
pos_4 = TheTestEvents()->GetLastEventPosition();
TTB_EXP_SEQ_S ("Number:" << std::setw(2) << 6);
pos_6 = TheTestEvents()->GetLastEventPosition();

TTB_CHECK_COND(pos_6 > pos_4);
TTB_CHECK_EQUAL(pos_6,3);
TTB_CHECK(pos_6,std::greater(),pos_4);

Top2 Prüfung von Werten und Ausdrücken

Innerhalb eines automatisierten Testablaufes kann an verschiedenen Stellen die Notwendigkeit entstehen, einen Wert oder Ausdruck auf seine Gültigkeit hin zu untersuchen. Typische Quellen für derartige zu überprüfende Werte sind:
  • Rückgabewerte von Funktionsaufrufen
  • zurückgelieferte Rückgabeparameter aus Funktionsaufrufen
  • im Rahmen von Callbacks aufgezeichnete Informationen
Je nach Art des zu prüfenden Wertes oder Ausdruckes stehen unterschiedliche Prüfungsfunktionen zur Verfügung.

Top2.1 Überprüfung einer boolschen Bedingung (TTB_CHECK_COND)

Mit dem Makro TTB_CHECK_COND können alle Arten von Boolschen Ausdrücken überprüft werden. Dabei gilt die Überprüfung als bestanden, wenn der Ausdruck erfüllt ist, also "true" zurückliefert.
bool SomeBoolFunc(int i)
{return i>25;}

TTB_TEST_FUNC (CheckCondition)
{
    int i = 23;
    int j = 5;

    // Check bool expression
    TTB_CHECK_COND(i > j);
    TTB_CHECK_COND(i > 0);

    // Check bool variable
    bool someBoolVariable = true;
    TTB_CHECK_COND(someBoolVariable);

    // Check bool function
    TTB_CHECK_COND(SomeBoolFunc(31));
}
Aufzeichnung erfolgreicher Prüfungen im Protokoll
Ist die Aufzeichung im Protokoll aktiviert (Einstellung über TestEvents::SetDetailedCheckLog), so werden Informationen auch zu den erfolgreich überprüften Ausdrücken aufgezeichnet.

Beispiel für einen Protokollabschnitt:

================================================================================
Test: CheckCondition
================================================================================

CheckCondition Ok:  i > j (=true)

CheckCondition Ok:  i > 0 (=true)

CheckCondition Ok:  someBoolVariable (=true)

CheckCondition Ok:  SomeBoolFunc(31) (=true)
Anzeige und Aufzeichnung fehlgeschlagener Prüfungen
Bei der Überprüfung aufgedeckte Abweichungen werden unabhängig von der Einstellung über TestEvents::SetDetailedCheckLog sowohl im Protokoll als auch über StdOut ausgegeben.

Beispiel für Testscript mit fehlschlagendem Check-Makro:

int i = 23;
int j = 5;
TTB_CHECK_COND(j>=i);
Auszug aus dem zugehörigen Protokoll:
!!Error at location
c:\test\testcasescomparevalues.cpp (48):  (call location of error)
CheckCondition NOT OK: j>=i (=false)
Hinweis
Werden Fehler festgestellt, so ist aus den Protokollaufzeichnungen nur ersichtlich, dass der boolsche Ausdruck nicht erfüllt ist. Variablen innerhalb des Ausdruckes werden nicht ausgegeben. Zur besseren Anzeige der Variablen-Werte empfiehlt sich die Verwendung der Makros TTB_CHECK_EQUAL oder TTB_CHECK.

Beispiele:

  • Statt TB_CHECK_COND(x==y) kann TTB_CHECK_EQUAL(x,y) und
  • statt TTB_CHECK_COND(x>y) kann TTB_CHECK(x,std::greater(),y) verwendet werden.

Top2.2 Vergleich zweier Werte auf Gleichheit (TTB_CHECK_EQUAL)

Mit dem Makro TTB_CHECK_EQUAL können zwei Werte oder Ausdrücke beliebigen Typs auf Gleichheit überprüft werden. Zum Vergleich von double-Werten kann die erforderliche Genauigkeit über SetDoublePrecision angegeben werden.
TTB_TEST_FUNC (CheckEqual)
{
    int i = 23;
    int j = 5;

    // Check integer expressions
    TTB_CHECK_EQUAL(i,j+18);

    // Check bool variables
    bool someBool = true;
    bool otherBool = true;
    TTB_CHECK_EQUAL(someBool,otherBool);

    // Check bool expression
    TTB_CHECK_EQUAL(i < j, 2*i==5);

    // Check double values with given precision
    double pi = 3.14159265;
    float   f = 3.1435f;
    TheTestEvents()->SetDoublePrecision(2);
    TTB_CHECK_EQUAL(pi, f);
}
Aufzeichnung erfolgreicher Prüfungen im Protokoll
Ist die Aufzeichung im Protokoll aktiviert (Einstellung über TestEvents::SetDetailedCheckLog), so werden Informationen auch zu den erfolgreich überprüften Ausdrücken aufgezeichnet.

Beispiel für einen Protokollabschnitt:

================================================================================
Test: CheckEqual
================================================================================

CheckEqual Ok:  i (=23)  ==  j+18 (=23),  used type: int

CheckEqual Ok:  someBool (=true)  ==  otherBool (=true),  used type: bool

CheckEqual Ok:  i < j (=false)  ==  2*i==5 (=false),  used type: bool

CheckEqual Ok:  pi (=3.14)  ==  f (=3.14),  used type: specialization
                                            for double, precision is 2
Anzeige und Aufzeichnung fehlgeschlagener Prüfungen
Bei der Überprüfung aufgedeckte Abweichungen werden unabhängig von der Einstellung über TestEvents::SetDetailedCheckLog sowohl im Protokoll als auch über StdOut ausgegeben.

Beispiel für Testscript mit fehlschlagendem Check-Makro:

int i = 23;
int j = 5;

// Check integer expressions
TTB_CHECK_EQUAL(i-4,j+18);

// Check bool variables
bool someBool = true;
bool otherBool = false;
TTB_CHECK_EQUAL(someBool,otherBool);

// Check bool expression
TTB_CHECK_EQUAL(i>=j, 2*i==5);

// Check double values
double pi = 3.14159265;
float   f = 3.1435f;
TheTestEvents()->SetDoublePrecision(4);
TTB_CHECK_EQUAL(pi, f);
Auszug aus dem zugehörigen Protokoll:
!!Error at location
c:\test\testcasescomparevalues.cpp (99):  (call location of error)
CheckEqual NOT OK: i-4 (=19)  ==  j+18 (=23),  used type: int
left :              19              (i-4)
right:              23              (j+18)


!!Error at location
c:\test\testcasescomparevalues.cpp (104):  (call location of error)
CheckEqual NOT OK: someBool (=true)  ==  otherBool (=false),  used type: bool
left :            true              (someBool)
right:           false              (otherBool)


!!Error at location
c:\test\testcasescomparevalues.cpp (107):  (call location of error)
CheckEqual NOT OK: i>=j (=true)  ==  2*i==5 (=false),  used type: bool
left :            true              (i>=j)
right:           false              (2*i==5)


!!Error at location
c:\test\testcasescomparevalues.cpp (113):  (call location of error)
CheckEqual NOT OK: pi (=3.1416)  ==  f (=3.1435),  used type: specialization
                                                   for double, precision is 4
left :          3.1416              (pi)
right:          3.1435              (f)

Top2.3 Freier Vergleich zweier Werte (TTB_CHECK)

Der Anwender kann mit dem Makro TTB_CHECK und einer selbstdefinierten Vergleichsfunktion (oder mit einem binären Prädikat wie z.B. std::less) zwei Werte oder Ausdrücke miteinander vergleichen.
bool IsGreaterThan(int left, int right)
{return left > right;}

TTB_TEST_FUNC (CheckWithCompareFunction)
{
    int i = 23;
    int j = 5;
    double pi = 3.14159265;
    double  f = 3.1435f;

    // User defined compare function (binary predicate)
    TTB_CHECK(i, IsGreaterThan, j);

    // Using standard predicates
    TTB_CHECK(i, std::less_equal(), i);
    TTB_CHECK(pi, std::less(), f);
}
Aufzeichnung erfolgreicher Prüfungen im Protokoll
Ist die Aufzeichung im Protokoll aktiviert (Einstellung über TestEvents::SetDetailedCheckLog), so werden Informationen auch zu den erfolgreich überprüften Ausdrücken aufgezeichnet.

Beispiel für einen Protokollabschnitt:

================================================================================
Test: CheckWithCompareFunction
================================================================================

Check Ok:  i (=23)  IsGreaterThan  j (=5),  used type: int

Check Ok:  i (=23)  std::less_equal()  i (=23),  used type: int

Check Ok:  pi (=3.14159)  std::less()  f (=3.1435),  used type: double
Anzeige und Aufzeichnung fehlgeschlagener Prüfungen
Bei der Überprüfung aufgedeckte Abweichungen werden unabhängig von der Einstellung über TestEvents::SetDetailedCheckLog sowohl im Protokoll als auch über StdOut ausgegeben.

Beispiel für Testscript mit fehlschlagendem Check-Makro:

int i = 23;
int j = 5;
double pi = 3.14159265;
double f = 3.1435f;

// User defined compare function (binary predicate)
TTB_CHECK(j, IsGreaterThan, i);

// Using standard predicates
TTB_CHECK(j, std::greater(), i);
TTB_CHECK(pi, std::greater_equal(), f);
Auszug aus dem zugehörigen Protokoll:
!!Error at location
c:\test\testcasescomparevalues.cpp (153):  (call location of error)
Check NOT OK: j (=5)  IsGreaterThan  i (=23),  used type: int
left :               5              (j)
right:              23              (i)


!!Error at location
c:\test\testcasescomparevalues.cpp (156):  (call location of error)
Check NOT OK: j (=5)  std::greater()  i (=23),  used type: int
left :               5              (j)
right:              23              (i)


!!Error at location
c:\test\testcasescomparevalues.cpp (157):  (call location of error)
Check NOT OK: pi (=3.14159)  std::greater_equal()  f (=3.1435),  used type: double
left :         3.14159              (pi)
right:          3.1435              (f)