Testframework

Im ClassiX® System folgende Qualitätssicherung/Qualitätsmanagement implementiert:

Über das Hauptmenü System->Tools->Testframework ist ein Modul zu erreichen, welches Excel Dateien einlesen und auswerten kann.

Im ClassiX Demosystem liegen bereits vorhandene Testframework Excel Dateien im Verzeichnis appswh\data\qs\demo

Das Format dieser Excel Dateien sieht folgendermaßen aus:

#Flags #Kommentar #ExecuteString #KommandoString #Variable Test-Zugriffsausdrücke

Es dürfen keine Leerzeilen in der Testdatei enthalten sein! Deshalb bitte darauf achten, in gewünschte Leerzeilen immer in der ersten Spalte (#Flags) ein REM; zu schreiben. Dann funktioniert es auch ohne, dass die letzte Zeile nicht mit ausgeführt wird.

Ein paar Hinweise zur Benutzung und Beispiele:

Nehmen wir an, wir wollen eine Bedarfsanforderung erstellen und hieraus eine Bestellung erstellen.

So geht man in folgenden groben Schritten vor:

  1. Leere Bedarfsanforderung erstellen
  2. Bedarfsanforderung über Speichern Button speichern
  3. Teilenummer in Bedarfsanforderungsposition (die sich beim Speichern des Kopfbeleges automatisch öffnet) schreiben und SELECT Message an Teilenummernfeld schicken
  4. Menge ändern und Position über Speichern Button speichern
  5. Kopfbeleg buchen
  6. Variable der Bedarfsanforderungsposition an unser QM Modul zurück schicken
  7. Bestellung über übliche Message erstellen

Es stellen sich folgende zu lösende Problematiken:

  1. Wie schicke ich eine Variable in das QM Modul zurück?
  2. Wie schicke ich meine Bedarfsanforderungsvariable aus dem QM Modul in ein anderes Modul über die Testmessage, die ja nur einen Execute Parameter hat?

..und dazu die Lösungen:

  1. <Variablenname aus Modul z.B. purchaseRequisitionItem> SendMsg(QM_ROW_EXECUTED) in Spalte 1, SendMsg(TEST_PURCHASE_REQUISITION_ITEM) in Spalte 2 und die Zielvariable, in der wir diese Position im QM Modul halten wollen also purchaseRequisitionItem in Spalte 3.
    Das QM Modul empfängt diese Antwortmessage und speichert sie immer in der selben temporären Variable. Dann wird das Objekt aus der temporären Variable in die gewünschte Variable übertragen.
  2. Folgender Trick führt zum Ergebnis, wenn man zum Beispiel die Bedarfsanforderungsposition als Vorgänger in die Bestellung ziehen will:
    Spalte 1: Widget(EditWin, predecessors) SendMsg(PURCHASE_REQUISITION_ITEM_SELECTED, DIRECT)
    Spalte 2: purchaseRequisitionItem Swap SendMsg(TEST_PURCHASE_ORDER_ITEM)
    Durch das Swap wird die Variable purchaseRequisitionItem hinter den auszuführenden String gestellt, sodass sich folgende Anweisung ergibt:
    purchaseRequisitionItem "Widget(EditWin, predecessors) SendMsg(PURCHASE_REQUISITION_ITEM_SELECTED, DIRECT)" SendMsg(TEST_PURCHASE_REQUISITION_ITEM)
    Es liegen beim Auslösen der Testmessage also 2 Parameter auf dem Stack: Unsere Bedarfsanforderungsposition und auf dem TOP der im Zielmodul per Execute auszuführende String.

In jedem Branch ist mindestens eine blanko-Datei und eine vollständig funktionierende "Beispiel" Testdatei eingecheckt. Man findet diese Test Dateien im Verzeichnis: <Projekt>\AppsWH\<Projekt>\data\QS

Zur Benutzung der BREAK; und der REM; Anweisung folgendes:
Diese Anweisung bezieht sich immer genau auf den Beginn der entsprechenden Zeile: Das heißt, genauso wie man mit REM; genau die Zeile auskommentiert, bricht man mit BREAK; auch genau VOR Ausführung dieser Zeile ab!
Die Zeile, in der sich das BREAK; befindet, wird also nicht mehr ausgeführt.

Noch ein Tip: Fenster-Testmessages

Soll ein Makro per Test Message ausgeführt werden, welches Zugriffe auf Widgets beinhaltet, die ohne führendes EditWin, also beispielsweise GetObject(, predecessors) geschrieben sind, so kann bei Bedarf eine lokale Test Message nach folgendem Schema erstellt werden: Erster Teil: Testmessage (TEST_ORDER), zweiter Teil Fenstername: (EDIT_WIN)
= TEST_ORDER_EDIT_WIN
Im Modul, welches die Test Message empfängt, wird eine weitere Testmessage definiert:
Msg(TEST_ORDER_EDIT_WIN)
Dann wird NUR in der Actionlist des Fensters (hier EditWin) diese Message abgefangen und nur durch ein Execute ergänzt:
TEST_ORDER_EDIT_WIN: Execute

So kann man nun auch Makros aus dem Fenster direkt per Execute aufrufen, ohne dass man in allen Makros das EditWin hinzufügen muss, was manchmal sogar falsch wäre (Makro wird von mehreren Fenstern aufgerufen!)!

Allerdings muss dann der Aufruf der Message ein bisschen anders aussehen:
Spalte 1: "SaveObject" SendMsg(TEST_ORDER_EDIT_WIN)
Spalte 2: SendMsg(TEST_ORDER)

Der in der Fenster-Testmessage auszuführende String muss noch mal in Anführungszeichen gesetzt werden, da er sonst bereits vom ersten Execute (TEST_ORDER) ausgeführt werden würde. Mit Anführungszeichen wird er ganz normal als String behandelt und (ohne Anführungszeichen) auf den Stack geladen. Da die Anweisung SendMsg(TEST_ORDER_EDIT_WIN) nicht in selbigen steht, wird diese Anweisung ausgeführt und schickt den vorher geladenen String als nächsten Ausführungsbefehl an die Fenster-Testmessage.

Da nicht in jedem Modul eine solche Message nötig ist, und diese auch auf keinen Fall das Modul triggern sollte (sonst gäbe es wohlmöglich viele doppelte Ausführungen der Tests, weil vielleicht noch Kundenableitungen von diesen Modulen erstellt sind) und es nur eine definierte Schnittstelle zu einem Modul geben soll,  ist diese Message bei Bedarf nach diesem Schema nachzutragen.

Häufige Fehler, die bei der Erstellung einer Testdatei passieren:

LAZY_CREATOR: Wird eine Position eines Beleges in einer Variable in der Testdatei gehalten und diese in einer Spalte zur Auswertung eines Slots o.ä. benutzt, so erscheint die Fehlermeldung "Objekt noch nicht erzeugt", obwohl diese Position bereits mit dem Kopfbeleg verbunden wurde. Da der gesamte Testprozess über die ganze Testsuite in einer Haupttransaktion geschieht, wird dieser LazyCreator nicht in ein persistentes Objekt umgewandelt. Dies muß in der Testdatei über den OBJECT Manager geschehen: position Kopfbeleg GetManager(OBJECT) Call(Instantiate) -> Variable.
Ganz wichtig ist hierbei, daß das Ergebnis des Instantiate in die Variable der Position zurück gespeichert wird. Sonst weist der alte Variablenpointer immer noch auf den LAZY_CREATOR.
Beispiel:
orderItem order GetManager(OBJECT) Call(Instantiate) -> orderItem
Wird orderItem in einer Spalte benutzt, so muß diese Variable, solange sie noch den LazyCreator beinhaltet, anders benannt werden. Denn solange diese noch auf den LazyCreator zeigt, schlagen die Versuche in den Spalten wie zum Beispiel orderItem::sales.pricePer mit einer Fehlermeldung im QM Modul fehl.
ALSO: Variable orderItem erst mal in orderItemTmp umbenennen und erst nach dem Instantiate in die Variable orderItem speichern. Dann kann auch die Spalte vernünftig ausgewertet werden.

Aufrufen mehrerer Testframeworks

Aufruf aus ClassiX®:
    - Mehrfachselektion von Dateien
    - Ordner auswählen um alle darin befindlichen Tests auszuführen

Aufruf mit einer Batch Datei:

Der genaue Pfad der gewünschten Dateien und Ordner wird in Variablen gespeichert und zu einer großen Zeichenkette zusammengesetzt.
Auszug einer Beispiel Datei:

Die Leerzeichen in den Dateinamen müssen durch "***" ersetzt werden:

SET STRING_1=%CX_QS_PATH%\Demo\Testdatei***Mustername1***-***Demo.xls (Testdatei Mustername1 - Demo.xls)
SET STRING_2=%CX_QS_PATH%\Demo\Testdatei***Mustername2***-***Demo.xls
SET STRING_3=%CX_OS_PATH%\Demo\Gueltigkeit

Die einzelnen Zeichenketten werden zu einer zusammengesetzt und sind durch "###" getrennt:

SET CX_ALL_TESTS=%STRING_1%###%STRING_2%###%STRING_3%

Der Aufruf der Datei welche die Tests startet mit der Variable CX_ALL_TESTS als ÜbergabeParameter:

call %CX_ROOTDIR%\projects\Start_Testframework.bat %CX_ALL_TESTS%

Allgemeines:

Die ausgewählten Dateien und Ordner werden zu einer Zeichenkette zusammengesetzt und als Übergabeparameter für die aufrufende Batch Datei benutzt. In dieser wird die Zeichenkette als Umgebungsvariable "CX_TESTFRAMEWORKS" gespeichert. Es wird eine neue ClassiX® Instanz geöffnet, welche die Zeichenkette aus der Umgebungsvariable ausliest, um den ersten Test aufzurufen. Dieser Test wird aus der Zeichenkette entfernt und wenn dieser beendet ist, wird erneut die Batch Datei aufgerufen mit der neuen Zeichenkette als Übergabeparameter. Somit laufen die Testframeworks jeweils in einer eigenen ClassiX® Instanz hintereinander ab.

Falls Fehler auftreten werden Error Dateien erzeugt, allerdings ohne die sonst übliche Abfrage ob ins Testverzeichnis gewechselt werden soll.