
BTP - ABAP Unit Runner
Wie kannst du deine ABAP Unit Tests auf dem ABAP Environment regelmäßig ausführen und dir die Ergebnisse zukommen lassen? Aktuell gibt es dafür keinen Standard.
Inhaltsverzeichnis
In diesem Artikel setzen wir die Infrastruktur für den ABAP Unit Runner auf und zeigen dir, wie du die Standard API von SAP konsumieren kannst. Am Ende können wir unsere Unit Tests auf dem System regelmäßig prüfen lassen, ohne alles manuell starten zu müssen. Die Umsetzung wurde inspiriert durch eine Rückfrage von Frank Engert.
Einleitung
Bereits im letzten Jahr hatten wir uns das Thema Testautomatisierung im Betrieb angeschaut und wie du mit der richtigen Infrastruktur deine Unit Tests regelmäßig laufen lassen kannst. Im ABAP Environment gibt es den Report RS_AUCV_RUNNER nicht für uns als Kunden, auch wenn er auf dem System verfügbar ist. Aktuell gibt es die Möglichkeit per Jenkins Pipeline die Tests im System zu automatisieren. Doch fällt es Unternehmen mit ABAP Entwicklung nicht so leicht, mal eben eine Pipeline zur Verfügung zu stellen, wenn man sich dort nicht schon mit dem Thema beschäftigt hat. Deshalb schauen wir uns in diesem Artikel eine Alternative an.
Architektur
Was wollen wir also tun? In der folgenden Grafik findest du die geplante Architektur. Wir möchten eine Destination zur Verfügung stellen, welches auf das aktuelle System verweist, um den Service konsumieren zu können. Da es im System keine freigegebene API dafür gibt, verwenden wir hier den externen Service SAP_COM_0735, der auch für die Anbindung von Pipelines verwendet wird.
Schnittstelle
Für die Communication benötigen wir einen technischen User mit den entsprechenden Berechtigungen auf die Schnittstelle und eine Destination im Destination Service des Subaccounts.
Communication Arrangement
Im ersten Schritt müssen wir die Schnittstelle zur Verfügung stellen und einrichten. Dazu legen wir ein Communication Arrangement für SAP_COM_0735 an.
Die Grundkonfiguration für das Communication System und den User kannst du aus diesem Artikel entnehmen. Die Zugangsdaten benötigen wir dann für unsere Destination im gleichen Subaccount auf der BTP. Das Communication Arrangement könnte zum Schluss so aussehen, dabei stehen die Pfade zum Endpunkt nun für uns zur Verfügung.
Destination
Im Subaccount legen wir eine Verbindung an, die auf das ABAP Environment zeigt und hinterlegen User, sowie Passwort. Damit steht die Verbindung zum Service.
Service
Nun können wir mit der eigentlichen Anbindung beginnen. In der SAP Dokumentation (unten verlinkt) finden wir weitere Informationen, wie wir den HTTP Aufruf vorbereiten müssen, um den ersten Lauf anzulegen. Dazu ein Beispiel aus dem Projekt.
Anlage
Wir erzeugen uns über den die Destination einen Client und bereiten den HTTP Aufruf vor. Diesem übergeben wir einige Parameter und die Payload. Über die Methode SET_CSRF_TOKEN erhalten wir eine einfache Methode, einen Token vom Endpunkt zu holen und in unseren Request zu setzen. Dafür müssen wir aber vorher den Endpunkt gesetzt haben. Den Token benötigen wir, da wir einen POST gegen die Schnittstelle absetzen müssen, um unseren ABAP Unit Lauf zu starten.
DATA(destination) = cl_http_destination_provider=>create_by_cloud_destination(
i_name = run_setting-cloud_destination
i_authn_mode = if_a4c_cp_service=>service_specific ).
DATA(client) = cl_web_http_client_manager=>create_by_http_destination( destination ).
DATA(request) = client->get_http_request( ).
request->set_uri_path( zif_aur_runner=>endpoints-runs ).
request->set_content_type( zif_aur_runner=>content_type-start ).
request->set_text( get_request_payload( ) ).
client->set_csrf_token( ).
DATA(response) = client->execute( i_method = if_web_http_client=>post ).
IF response->get_status( )-code = 201.
RETURN response->get_header_field( `location` ).
ENDIF.
Die Payload ist ein XML Objekt, welches wir zuvor aufbereiten müssen. Weitere Informationen und ein Beispiel findest du in der Dokumentation. Über den "LOCATION" Header erhalten wir die URL, wo wir den Status abfragen können.
Status
Um den Status abzufragen, müssen wir nur die URL (Location) per GET Request anfragen, hier benötigen wir keinen CSRF Token mehr. Wurde unsere Anfrage erfolgreich durchgeführt, erhalten wir als Antwort ein XML, welches wir dann wieder einlesen müssen. Im XML finden wir Informationen zum Lauf, den Status der Durchführung und eine URL zum Abruf der Ergebnisse
<?xml version="1.0" encoding="utf-8"?>
<aunit:run title="Testrun This" context="AIE Integration Test" xmlns:aunit="http://www.sap.com/adt/api/aunit">
<aunit:progress status="FINISHED" percentage="100"/>
<aunit:executedBy user="CC0000000000"/>
<aunit:time started="2025-02-06T19:37:22Z" ended="2025-02-06T19:37:38Z"/>
<atom:link href="/sap/bc/adt/api/abapunit/results/02E4C8A8EDEA1EDFB998391DAA3B1664" rel="http://www.sap.com/adt/relations/api/abapunit/run-result" type="application/vnd.sap.adt.api.junit.run-result.v1+xml" title="Run Result (JUnit Format)" xmlns:atom="http://www.w3.org/2005/Atom"/>
<atom:link href="/sap/bc/adt/api/abapunit/results/02E4C8A8EDEA1EDFB998391DAA3B1664" rel="http://www.sap.com/adt/relations/api/abapunit/run-result" type="application/vnd.sap.adt.api.abapunit.run-result.v1+xml" title="Run Result (ABAP Unit Format)" xmlns:atom="http://www.w3.org/2005/Atom"/>
</aunit:run>
Ergebnisse
Zum Abschluss können wir nun die Ergebnisse abholen, ebenfalls als XML. Über die URL aus dem Schritt davor kommen wir an die Ergebnisse des Laufs und können diesen für die Auswertung oder den Versand parsen.
Kapselung
Die Logik für die einzelnen Bestandteil kapseln wir und verteilen sie auf entsprechende Komponenten. Wir benötigen eine Kernkomponente für die Einplanung und Abholung des ABAP Unit Laufs, eine Komponente für das Parsen der XML Datei und eine Komponente zum Versand der E-Mail
Damit wir die Logik entkoppeln und testbar machen, erstellen wir zwei Factorys, die uns Instanzen für den Runner, Parser und die E-Mail erzeugen und verwenden diese in unserem Code. Damit können wir im nächsten Schritt einfach Unit Tests für die Logik bauen. In der aktuellen Version sind keine Unit Tests enthalten, mit dem nächsten Release wird aber auch Joule für ABAP Entwickler zur Verfügung stehen, dann können wir diesen Teil gleich mit testen.
Die Klassen haben auch ein entsprechendes Interface erhalten, damit wir eine saubere Schnittstelle nach außen zur Verfügung stellen. Die Konstanten- und Typdefinitionen befinden sich in den Interfaces, damit halten wir die Klasse etwas sauberer, vor allem da wir viele interne Datentypen für das Mapping und die Datenübergabe verwenden.
Für die Einstellungen verwenden wir eine eigene Struktur, da wir hier nur die Daten durch die Schnittstellen transportieren wollen, aber auch flexibel auf Erweiterungen reagieren wollen. Grundsätzlich hätten wir auch ein Konfigurationsobjekt verwenden können, da wir aber keine Logik in diesem Fall benötigten, haben wir uns für eine Struktur entschieden.
Verwendung
Damit wir nun den Prüflauf im ABAP Environment einplanen können, erstellen wir einen Application Job mit entsprechender Eingabe, damit wir unseren Job regelmäßig einplanen können. Der Job Catalog würde in diesem Projekt wie folgt aussehen.
Nachdem wir dann auch ein Template angelegt haben und erste Initialwerte auf der Maske haben, würde der Job in der App "Application Jobs" (F1240) wie folgt aussehen.
Ist der Mailversand aktiviert, dann erhalten wir entweder im Fehlerfall oder nach Abschluss des ABAP Unit Laufs die Ergebnisse per E-Mail. Die verschiedenen Werte wurden in der Mail formatiert und einzelne Zellen farblich hervorgehoben zur schnelleren Orientierung.
Die Aufbereitung der E-Mail übernimmt die E-Mail Klasse die ein HTML Dokument über ein paar wiederverwendbare Blöcke erzeugt. Die Daten werden als einzelne Tabellen und Überschriften in die Mail übernommen. Grundsätzlich kann über die Methode GET_CSS auch noch einiges am Design der E-Mail Inhalte angepasst werden.
Open Source
Das Projekt findest du als Open Source bei uns im GitHub Repository und kannst es frei einsetzen und nutzen. Änderungen am Projekt werden in Zukunft direkt im Repository stattfinden. Zielplattform ist das ABAP Environment, theoretisch auch die Public Cloud, um die fehlende Funktion der regelmäßigen Tests im System zur Verfügung zu stellen.
Fazit
Es gibt zwar keine interne API zum Starten der ABAP Unit Tests für verschiedene Objekte, allerdings funktioniert die von SAP bereitgestellte externe API sehr gut. Etwas umständlich war leider das Parsen der XML Daten, hier hätten wir uns lieber eine JSON Schnittstelle gewünscht. Es gibt auch einen Artikel in der SAP Community.