Zusätzlicher Autor dieses Beitrags – Stephen Gennard
Seit den späten 1980er Jahren mit dem Aufkommen von SUnit und weiter in den 90er Jahren mit der Einführung von JUnit hat die Verwendung von Unit-Tests, die durch ein Unit-Test-Framework unterstützt werden, rasant zugenommen und ist zu einem Branchenstandard für Millionen von Softwareentwicklern in der Community der verteilten Anwendungsentwicklung geworden.
Aus langjährigen historischen Gründen besteht eine wahrgenommene Einschränkung im Zusammenhang mit Anwendungscode, der für IBM geschrieben wurde.® Mainframe-Subsysteme im Hinblick auf solche Testmethoden. Überwiegend in COBOL geschrieben und für den Betrieb in den Subsystemen von konzipiert. ® CICS® Bei IMS und JES wurde das Konzept des Unit-Testings dieser Anwendungsprogramme traditionell als ein zu großer Schritt ins Ungewisse betrachtet.
Wir bei Rocket sind seit Langem überzeugt, dass diese Anwendungen und die zu ihrer Entwicklung verwendeten Programmiersprachen bestens in die moderne Softwareentwicklungswelt passen. Rocket® Enterprise Developer (formerly part of Micro Focus) und Rocket® Visual COBOL (formerly part of Micro Focus) stellen seit der Veröffentlichung von Version 2.3 im Jahr 2015 das Unit-Test-Framework bereit.
Vor der Version 9.0 von Enterprise Developer war ein COBOL Programm, das sowohl Geschäftslogik als auch „EXEC SQL“- und/oder „EXEC CICS“-Anweisungen enthielt, nicht optimal für Unit-Tests geeignet. Daher wurde die MFUnit-Funktionalität weiterentwickelt und unterstützt nun das Ignorieren und Simulieren von EXEC CICS- und SQL-Anweisungen. Dadurch wird es einfacher denn je, die Kluft zwischen den beiden Systemen zu überbrücken und intelligentere Testmethoden für Mainframe-Subsystemprogramme zu implementieren. In der neuesten Version 10.0 wurde zudem erste Unterstützung für „EXEC DLI“-Anweisungen hinzugefügt.
Es überrascht daher nicht, dass aufgrund dieser großen Kluft derzeit wenig über den Nutzen von Unit-Tests für Mainframe-Anwendungscode geschrieben wurde. Es gibt jedoch zahlreiche Artikel wie diesen, die den Nutzen von Unit-Tests detailliert erläutern. Wenn man eine bestimmte Softwarekomponente als COBOL -Abschnitt oder -Sektion betrachtet, gelten alle genannten Gründe gleichermaßen für Mainframe-Code.
Bevor wir näher auf die Details eingehen, ist es wichtig, den Kontext für die Verwendung dieser neuen EXEC SQL/CICS-Ignorier- und Mocking-Funktionen zu erläutern.
Ziel ist es, die COBOL Logik in einem EXEC-basierten Programm „offenbar“ zu machen, damit sie getestet werden kann. Es sollte nicht als Methode zum Testen von CICS- und/oder SQL-basierten Anwendungen als Ganzes betrachtet werden.
Der Unit Test Seam Preprocessor (MFUPP) wurde erweitert, um die Erstellung von in sich geschlossenen Unit-Tests zu erleichtern, die "EXEC CICS"-, "EXEC SQL"- oder "EXEC DLI"-Anweisungen enthalten.
Diese EXEC-Anweisungen können je nach Anforderung des Testfalls entfernt oder simuliert werden.
Der Unit Test Runner wurde ebenfalls verbessert, um die Entwicklung dieser Arten von Unit-Tests zu unterstützen. Dazu wurden neue Codegenerierungsoptionen hinzugefügt, die über die Befehlszeilenschnittstelle verfügbar sind.
Abbildung 1 – Vorverarbeitung der Nahtstellen im Unit-Test
Der Unit Test Seam Pre-Processor (MFUPP) ermöglicht die Manipulation von Code, ohne den ursprünglichen Quellcode zu verändern, mit dem alleinigen Ziel, einen Unit-Test zu erstellen.
Es bietet die Möglichkeit, Copybooks in verschiedenen Bereichen einzufügen, bestimmte EXEC-Anweisungen zu entfernen und simulierte Rückrufanweisungen einzufügen.
Ein Programm, das eingebettete SQL-Anweisungen enthält, kann nun mithilfe eines oder beider der folgenden Mechanismen in einen Unit-Test umgewandelt werden:
Es mag seltsam erscheinen, dass ein Präprozessor Code entfernt, aber er ist äußerst nützlich, wenn man einen Unit-Test für einen Abschnitt oder Absatz erstellen möchte, der eingebettetes SQL enthält.
Wenn der zu testende COBOL Abschnitt oder -Paragraph eine einzelne "EXEC SQL"-Anweisung enthält, ist er ein idealer Kandidat für die Verwendung der Entfernungsfunktion des Seam-Präprozessors, da die durch die "EXEC SQL"-Anweisung aktualisierten Werte ohne die Notwendigkeit von Mocking in den Unit-Testfall aufgenommen werden können.
Abbildung 2 – COBOL Absatz mit eingebetteter SQL-Anweisung
Imagine sich ein COBOL Programm vor, das eine EXEC SQL FETCH-Anweisung enthält, um eine neue Datenzeile abzurufen, und anschließend einige Berechnungen (Geschäftslogik) daran durchführt.
Ohne den Einsatz des Seam-Preprozessors müsste eine bereitgestellte/nutzbare Datenbank zum Testen zur Verfügung stehen.
Als nächstes müsste im Testfall ein Cursor geöffnet sein, der für den Abruf bereit ist, bevor der Absatz getestet werden kann.
Dies bedeutet einen erheblichen Aufwand und Konfigurationsaufwand für das Testen eines Abschnitts oder Absatzes. Abbildung 2 – COBOL Absatz mit eingebetteter SQL-Anweisung
Abbildung 3 – Unit-Test, der die SQL-Anweisung ignoriert
Mithilfe der in sich geschlossenen Unit-Test-Funktion des Seam-Präprozessors kann ein Testfall erstellt werden, der in das Programm eingebettet wird.
Dies wird erreicht, indem der Testfall in einer Datei mit dem Präfix MFUPD_ geschrieben wird. Dadurch wird sichergestellt, dass wir auf alle Felder im Programm zugreifen und einen 50-FETCH-UPDATE- Abschnitt ausführen können.
Abbildung 4 - Unit-Test, der die SQL-Anweisung simuliert.
Das vorherige Beispiel von ScanEmployeeTable hat sich nun weiterentwickelt.
Es ist nun unmöglich, die Werte aus dem SQL FETCH zu verfälschen, indem man einfach die EXEC SQL-Anweisung entfernt, da der "test"-Abschnitt als erstes die EMP-TABLE initialisiert und damit alle Variableneinstellungen verwirft.
Jetzt ist also Spott gefragt.
Wie bereits bei der Programmsimulation vor dieser Version muss ein Einstiegspunkt als Controller registriert werden. Dies erfolgt im Metadaten-Einstiegspunkt, wobei der Symbolname im Feld „MFU-MD-EXEC-CONTROLLER“ eingetragen wird.
Als nächstes müssen wir einen Einstiegspunkt deklarieren, der die simulierte SQL-Anweisung verarbeitet. In diesem Beispiel werden hier die erforderlichen Move-Anweisungen eingerichtet, um diese FETCH- Anweisung zu simulieren.
In diesem einfachen Beispiel werden nicht alle Parameter deklariert, da wir sie nicht verwenden.
Die Unterstützung des Unit Test Seam-Präprozessors für „EXEC CICS“-Anweisungen ist so gestaltet, dass sie sich vertraut anfühlt, da ihre Funktionen symmetrisch zu denen für „EXEC SQL“-Anweisungen sind.
Das Ignorieren von „EXEC CICS“- und „EXEC DLI“-Anweisungen ist genauso einfach wie bei „EXEC SQL“-Anweisungen, und das Mocking verwendet denselben Callback-Mechanismus.
Abbildung 5 - Beispiele für das Ignorieren von EXEC DLI-Anweisungen.
Jede Modernisierung erfordert Investitionen, um ihren vollen Nutzen zu erzielen. Testwerkzeuge sollten Entwickler jedoch bestmöglich bei der Erstellung von Testfällen unterstützen. Zu diesem Zweck ist im MFUnit-Framework eine Funktion zur Generierung von Code-Snippets enthalten, mit der Code erstellt werden kann, der die EXEC-Anweisung des zu testenden Programms simuliert.
Abbildung 5 - Beispiele für eindeutige IDs für simulierte Aussagen.
Standardmäßig erstellt der Snippet-Generator für jede EXEC-Anweisung einen Mock-Snippet.
Jeder simulierten Anweisung wird eine eindeutige ID zugewiesen. Diese Kennung kann geändert werden, indem der Code vor der EXEC -Anweisung mit einem Kommentar instrumentiert wird.
Dadurch kann der Snippet-Generator übersichtlicheren Code erzeugen, indem die Codegenerierung auf diese benutzerdefinierten Bezeichner beschränkt wird.
Abbildung 6 – Hilfestellung bei Verwendung von COMMAREA im simulierten Programm
Ein CICS-Programm kann eine COMMAREA verwenden, die normalerweise vom CICS ECM verarbeitet wird. Für einen Testfall kann es jedoch erforderlich sein, dass diese initialisiert und für die Befüllung durch den Testfall verfügbar ist. Der Seam-Präprozessor fügt zwei zusätzliche Paragraphen ein, die verwendet werden können.
Der Abschnitt MFUPP--INIT-CICS weist den COMMAREA zu und legt die Größe in EIBCALEN fest.
Wenn die Verwendung von COMMAREA nicht mehr erforderlich ist, kann der Abschnitt MFUPP--END-CICS verwendet werden.
Das mit Enterprise Developer verfügbare Unit Test Framework verfügt über zwei neue Funktionen im Seam-Präprozessor.
Erstens das Entfernen oder Ignorieren der `EXEC SQL`-, `EXEC CICS`- und "EXEC DLI"-Anweisungen, die die zu testende Logik offenlegen, ohne dass ein Mocking erforderlich ist.
Die zweite Funktion, die Unterstützung für das Mocking von EXEC-Anweisungen, ermöglicht vereinfachte Alternativen zu EXEC-Anweisungen, die dem Programm gerade genügend Daten liefern, um es testen zu können.
Dank dieser zusätzlichen Unterstützung lassen sich Mainframe-Subsystemprogramme schnell testen, da weder das Subsystem selbst noch die Bereitstellung von Daten erforderlich ist. Tatsächlich benötigt man zum Testen des Codes lediglich den Code selbst.
Um einige dieser Funktionen in Aktion zu sehen, schauen Sie sich bitte dieses Video an .
Wir stellen Rocket EVA 2.0 vor.
Wählen Sie den richtigen Weg für die KI-gestützte Codemodernisierung
Finden Sie den Modernisierungspfad, der das schützt, was zählt.
