Zum Inhalt springen

Suchen...

Warum COBOL-Entwickler am liebsten Tests in Java schreiben

COBOL-Entwickler sagten, dass es einfacher sei, Unit Tests in Java zu schreiben als in ihrer eigenen Sprache. Hier ist die Schnittstellenarchitektur, die das auf einem 60 Jahre alten Großrechner möglich machte.

8 Min. Lesezeit
Cover für Warum COBOL-Entwickler am liebsten Tests in Java schreiben

Das Testen von COBOL auf einem Mainframe mit jahrzehntelangen Anpassungen bedeutet, dass Standard-Tools für Unit-Tests nicht anwendbar sind. Die Lösung ist eine Java-basierte API, die Testlogik in Debugger-Skripte übersetzt, die der Mainframe direkt ausführt, und so eine Brücke zwischen alten COBOL-Programmen und Standardwerkzeugen wie SonarQube, Cucumber und Jenkins schlägt. COBOL-Entwickler schreiben Assertions in Java, ohne die Sprache kennen zu müssen.

Das Wichtigste in Kürze

  • Es ist nachhaltiger, eine letzte, gut durchdachte Anpassungsschicht zu bauen, die eine Legacy-Umgebung mit Standardwerkzeugen verbindet, als Ad-hoc-Anpassungen auf unbestimmte Zeit zuzulassen.
  • COBOL-Entwickler befanden es als einfacher, Assertions für Unit-Tests in Java zu schreiben als in COBOL selbst, weil die Java-API so konzipiert wurde, dass keine Java-Vorkenntnisse erforderlich sind.
  • Fehlt in einem Legacy-Stack eine Testfähigkeit, wirkt sich das kaskadenartig aus: Berichte, Validierung von Releases und die Integration mit Tools wie SonarQube und X-Ray werden dadurch blockiert.
  • Die Überdeckung von COBOL-Programmen kann technisch durch die im IBM-Debugger eingebaute Option zur Zeilenverfolgung erreicht werden, ohne dass eine eigene Implementierung erforderlich ist.

Warum kundenspezifische Software immer mehr Anpassungen mit sich bringt

Maßgeschneiderte Software wächst durch Überlagerung. Eine Speziallösung erzwingt die nächste, und mit der Zeit verwirren sich die Schichten zu etwas, dem kein Standardwerkzeug etwas anhaben kann.

Das ist die Falle, die hinter einem System steckt, das sich schon vor Jahrzehnten von Standards und bewährten Verfahren verabschiedet hat. Wenn eine Funktion auf dem Markt nicht verfügbar ist, baut ein Unternehmen seine eigene. Diese erste Entscheidung sieht isoliert aus, aber das bleibt selten so.

Szymon Wałachowski beschreibt den Mechanismus ganz einfach. Wenn du eine Anpassung einführst, brauchst du eine zweite, die darauf aufbaut. Wenn du genug von diesen Schichten aufbaust, verstrickst du dich in Anpassungen, aus denen es keinen klaren Ausweg gibt.

Für ein Unternehmen, das es seit sechzig Jahren gibt, hat diese Geschichte eine lange Tradition. Die Entscheidungen wurden von Menschen getroffen, die zum Teil schon vor der Geburt der heutigen Entwickler/innen da waren. Um herauszufinden, warum die Umgebung so aussieht, wie sie aussieht, musst du Generationen von Entscheidungen zurückverfolgen.

Das fehlende Stück blockiert alles, was stromabwärts liegt

Wenn ein Block in der Toolchain fehlt, sind auch die Blöcke, die von ihm abhängen, verloren.

Das Unternehmen konnte die Standard-Tests von IBM für COBOL nicht verwenden. Diese eine Lücke hatte Folgen, die weit über die Unit Tests hinausgingen. Ohne automatisierte Tests fielen die Berichte weg. Ohne die Möglichkeit, die Korrektheit einer Änderung zu validieren, wurde eine sichere Freigabe schwieriger.

Die Abhängigkeit geht nur in eine Richtung. Man kann keine Berichte, keine Überdeckung und kein Vertrauen in die Freigabe auf der Grundlage einer Testfähigkeit aufbauen, die nicht vorhanden ist. Das Fehlen von Unit-Tests hat also eine ganze Reihe von Praktiken zunichte gemacht, die ein modernes Team als selbstverständlich ansieht.

Das sind die wahren Kosten von Altlasten und technischen Schulden. Es geht nicht nur um alten Code. Es ist die Kette von Fähigkeiten, die du nicht aufbauen kannst, weil das Fundament dafür nie gelegt wurde.

Baue das fehlende Werkzeug selbst und schließe dann an die Standardwelt an

Die Lösung bestand darin, das fehlende Werkzeug selbst in Java zu schreiben und es als Brücke zu den marktüblichen Werkzeugen zu nutzen.

Da das Tool zum Testen der COBOL-Einheiten in Java geschrieben wurde, konnte das Team Tools einbinden, zu denen die Mainframe-Welt sonst keinen Zugang hat. Cucumber, Jenkins, Allure, SonarQube, X-ray - alle wurden zugänglich. Das hauseigene Tool fungiert als Bindeglied zwischen dem Mainframe und der Mainstream-Toolchain.

Szymon bezeichnet dies als die eine Anpassung, die den Zyklus beendet. Frühere Anpassungen zogen weitere Anpassungen nach sich. Diese Anpassung bewirkt das Gegenteil. Wenn du dich in alles integrieren kannst, musst du nicht mehr für jeden neuen Bedarf spezielle Lösungen entwickeln.

Wir haben eine letzte Anpassung vorgenommen, die den Arbeitsablauf von nun an umstellen sollte, denn da du jetzt in der Lage bist, dich in alles zu integrieren, solltest du danach keine weiteren Anpassungen mehr vornehmen müssen.

  • Szymon Wałachowski

Bartosz Filipek nennt es eine Schnittstelle zur Standardwelt. Diese Metapher trifft zu. Das Tool fügt keine weitere verworrene Schicht hinzu. Es öffnet eine Tür, durch die das Team gehen kann, um alles zu erreichen, was draußen ist.

So funktioniert das COBOL Unit Testing Tool unter der Haube

Du schreibst den Test in Java, und ein Übersetzungsschritt verwandelt ihn in ein Debug-Skript, das der Mainframe-Debugger ausführt.

Die Wahl von Java war eine bewusste Entscheidung. Java bietet von Haus aus ausgefeilte Tools, was bei COBOL nicht der Fall ist. Das Schreiben von Unit-Tests direkt in COBOL wäre zu schwierig gewesen, also entschied sich das Team für die Sprache, die den Entwicklern mehr bietet.

Die Java-Seite wurde so gestaltet, dass du Java nicht kennen musst, um sie zu benutzen. Du folgst den Klammern, öffnest und schließt sie, fügst manchmal einen Punkt hinzu und gibst einfache Literale wie einen Variablennamen und einen Variablenwert ein. Das reicht aus, um einen Testfall zu formulieren.

Von dort aus wird der Java-Test in ein Debug-Skript übersetzt. Der Mainframe führt das Programm im Debugging-Modus aus, und das Debug-Skript steuert die Testlogik. Es hält an bestimmten Punkten an, mockt Werte an den Stellen, an denen du sie deklariert hast, und prüft Werte an bestimmten Stellen.

Da es durch den Debugger läuft, kannst du fast überall anhalten und fast überall hin springen. Diese Freiheit eröffnet dir eine Vielzahl von Möglichkeiten, ein Programm zu testen.

Assertions sind sprachunabhängig

Eine Assertion ist eine abstrakte Sache. Du nimmst eine Variable und vergleichst sie mit einem Wert. Dieser Logik ist es egal, ob der umgebende Code Python, COBOL oder Java ist.

Für die COBOL-Entwickler ist Java also nur eine Möglichkeit, die Validierung auszudrücken, die sie sehen wollen. Die IDE prüft die Syntax sofort und schlägt vor, was an die jeweilige Stelle gehört, indem sie Argumentnamen und JavaDocs liest, um Hinweise zu geben.

Warum COBOL-Entwickler lieber Tests in Java schreiben

Die COBOL-Entwickler befanden es als einfacher, Tests und Assertions in Java zu schreiben als in COBOL, obwohl COBOL ihre erste Programmiersprache ist.

Dieses Ergebnis überraschte Szymon. Ein externes Unternehmen veranstaltete einen Workshop über ein Tool, mit dem man Unit-Tests in COBOL schreiben kann, und er hatte erwartet, dass ihr Tool aufgrund der Vertrautheit gewinnen würde. Die COBOL-Entwickler, die teilnahmen, sagten das Gegenteil. Die einfache API machte Java für sie zum leichteren Weg.

Der Grund dafür liegt in der Syntax. COBOL-Assertions brauchen viel Inhalt und enthalten viel Boilerplate. Der Klartext ist schwer zu pflegen und schwer zu lesen. In Java benötigen die Assertions weniger Zeichen zur Deklaration.

Bartosz verweist auf die Programme selbst. Ein kompiliertes COBOL-Programm kann bis zu hunderttausend Zeilen lang sein. In Java zeigt der Test direkt auf die Abschnitte, die als Funktionen fungieren, und auf die spezifischen Variablen, die geprüft werden. Diese Präzision ist in einem ausgedehnten COBOL-Quelltext nur schwer zu erreichen.

Auch die Entwickler haben auf die Erfahrung reagiert. Die IDE überprüfte ihre Syntax, gab ihnen Hinweise und validierte Argumente während der Eingabe - etwas, das der COBOL-Workflow nicht bieten konnte.

Code-Überdeckung gibt es im Debugger umsonst

Der Mainframe-Debugger kann nachvollziehen, welche Zeilen ausgeführt wurden, so dass Überdeckungsdaten ohne zusätzliche Implementierung aus dem bestehenden Setup herausfallen.

Du schaltest eine Option im Debugger ein, und er zeichnet die ausgeführten Zeilen auf und gibt Statistiken als Ausgabe aus. Jeder Test deckt einen anderen Teil des Codes ab, so dass die Ergebnisse kombiniert werden müssen, aber die Rohdaten sind bereits vorhanden und können gesammelt werden.

Die Arbeit, die noch bleibt, ist nicht technischer Natur. Es ist die Einigung. Die COBOL-Entwickler sind Eigentümer des Codes, und es gibt unternehmensspezifische Grundregeln, die bei der Überdeckung beachtet werden müssen. Ein Proof of Concept läuft bereits lokal, so dass die Fähigkeit bewiesen ist. Der Abgleich mit den Eigentümern ist das, was noch aussteht.

Zwei Tools, ein Ziel: das Leben der Menschen einfacher machen

Das Tool zum Testen von Einheiten ist die eine Seite der Medaille. Die andere ist eine REST-API, über die die COBOL-Programme von außerhalb des Mainframes bedient werden können.

Ein universeller Dienst übersetzt JSON in den Bytecode, den die COBOL-Programme verbrauchen. Das macht den Mainframe auch für QS-Leute zugänglich, die keine COBOL-Entwickler sind, was wichtig ist, weil man den Mainframe nicht an einer Universität lernen kann. Die meisten Leute lernen es, nachdem sie in das Unternehmen eingetreten sind.

Bartosz bringt die Absicht in einem Satz auf den Punkt: den Leuten das Leben leichter machen. Das Team will COBOL-Entwicklern ein praktisches Tool für Unit-Tests an die Hand geben und gleichzeitig Tester unterstützen, die mit Standard-Tools und ohne Mainframe-Hintergrund kommen.

Tests öffnen die Tür zum Schrumpfen des Legacy

Sobald die Unit-Tests und funktionalen Tests eingerichtet sind, kann das Team damit beginnen, die technischen Schulden abzubauen und die großen COBOL-Programme in kleinere Stücke zu zerlegen.

Dies geschieht nach dem Würgemuster. Du nimmst das riesige Mainframe-System und zerhackst es mit der Zeit in kleinere Stücke. Das firmeneigene Tool ist nicht dazu gedacht, ewig zu leben. Wenn ein Standardtool irgendwann seine Rolle ausfüllt, würde das Team es gerne austauschen.

Bis jetzt gibt es keinen solchen Ersatz von IBM. Der gesamte Ansatz basiert auf dem Standard-Debugger von IBM, und es gibt kein ähnliches Tool, das diese Aufgabe übernehmen könnte. Deshalb lässt das Team seine eigene Bridge laufen und akzeptiert die fehlende Unterstützung, die damit einhergeht.

Das langfristige Ziel bleibt sichtbar. Mit den Tests können die großen Programme verkleinert und die Altlasten minimiert werden. Die Ziellinie ist noch weit entfernt, aber die Richtung stimmt und die Manager unterstützen die Bemühungen. Für jedes Unternehmen, das mit alten Altsystemen zu kämpfen hat, ist diese Kombination aus einer Schnittstelle zu Standardwerkzeugen und einem Plan zur Verkleinerung des Codes der praktische Weg nach vorn.

Diese Seite teilen

Ähnliche Beiträge