ABAP ASSERT Anweisung erklärt: Zusicherungen für Test & Debugging

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Die ASSERT-Anweisung dient dazu, Zusicherungen (englisch: Assertions) über den Zustand Deines Programms zur Laufzeit zu machen und zu überprüfen. Eine Zusicherung ist eine Bedingung, von der Du als Entwickler:in fest davon ausgehst, dass sie an einer bestimmten Stelle im Code immer wahr (abap_true) sein muss.

ASSERT ist primär ein Werkzeug für:

  • Entwicklung und Test: Um logische Fehler im Programm oder falsche Annahmen über Datenzustände frühzeitig zu erkennen.
  • Debugging: Um schnell festzustellen, an welcher Stelle eine Annahme verletzt wurde.
  • Code-Dokumentation: Um Annahmen über den Programmzustand explizit im Code festzuhalten.

Wichtige Abgrenzung: ASSERT ist nicht für die normale Fehlerbehandlung (z. B. ungültige Benutzereingaben, erwartete Fehlerzustände in der Geschäftslogik) in Produktivumgebungen gedacht. Dafür solltest Du IF-Abfragen, MESSAGE, RAISE EXCEPTION usw. verwenden. ASSERT prüft auf Programmierfehler oder Zustände, die eigentlich “nie” auftreten dürften.

Syntax

ASSERT [ ID <zusicherungsgruppe> ]
[ SUBKEY <unterschluessel> ]
[ FIELDS <feld1> <feld2> ... ]
CONDITION <logischer_ausdruck>. " Das Schlüsselwort CONDITION ist obligatorisch!
  • ID <zusicherungsgruppe> (Optional): Ordnet die Assertion einer sogenannten “Checkpoint-Gruppe” oder ” Zusicherungsgruppe” zu. Diese Gruppen können zentral (Transaktion SAAB) aktiviert, deaktiviert oder konfiguriert werden. Das ist sehr nützlich, um das Verhalten von Assertions systemweit oder benutzerspezifisch zu steuern.
  • SUBKEY <unterschluessel> (Optional): Ein zusätzlicher Text (Subschlüssel) zur weiteren Identifizierung oder Kontextualisierung der Assertion innerhalb einer ID-Gruppe.
  • FIELDS <feld1> <feld2> ... (Optional): Hier kannst Du eine Liste von Datenobjekten (Variablen) angeben. Wenn die Assertion fehlschlägt, werden die Werte dieser Felder im Protokoll (Log) oder im Kurzdump angezeigt, was die Fehlersuche erheblich erleichtert.
  • CONDITION <logischer_ausdruck>: Obligatorisch! Dies ist der logische Ausdruck, der ausgewertet wird. Die Assertion gilt als erfüllt (erfolgreich), wenn dieser Ausdruck zu abap_true ausgewertet wird.

Funktionsweise und Verhalten bei Fehlschlag

Zur Laufzeit wird der <logischer_ausdruck> geprüft:

  1. Wenn die Bedingung abap_true (wahr) ist: Die Assertion ist erfüllt. Es passiert nichts weiter, und das Programm läuft normal weiter. Deine Annahme über den Programmzustand war korrekt.
  2. Wenn die Bedingung abap_false (falsch) ist: Die Assertion schlägt fehl. Was nun geschieht, hängt von der * Aktivierungseinstellung* der Assertion ab (gesteuert über die ID, SUBKEY in Transaktion SAAB oder globale Systemparameter):
    • Inaktiv: Die ASSERT-Anweisung wird komplett ignoriert. Sie hat keine Auswirkungen auf die Ausführung oder die Performance. Dies ist die Standardeinstellung für Produktivsysteme.
    • Aktiv - Modus ‘Log’: Der Fehlschlag der Assertion wird protokolliert (z. B. im System-Log, Transaktion SM21, oder in einem speziellen Log für Checkpoint-Gruppen). Die unter FIELDS angegebenen Werte können mitprotokolliert werden. Das Programm läuft danach weiter. Dieser Modus ist nützlich in Test- oder Qualitätssicherungssystemen.
    • Aktiv - Modus ‘Abort’/‘Break’: Das Programm bricht mit einem Laufzeitfehler (Kurzdump) vom Typ ASSERTION_FAILED ab, oder es stoppt im Debugger an dieser Stelle (je nach Einstellung). Dies ist oft die gewünschte Einstellung während der Entwicklungsphase, um sofort auf den logischen Fehler aufmerksam zu werden.

Anwendungsfälle

  • Überprüfung von Vorbedingungen für Methoden oder Funktionsbausteine (z. B. ASSERT CONDITION parameter IS NOT INITIAL.).
  • Überprüfung von Nachbedingungen nach der Ausführung von Codeblöcken (z. B. ASSERT CONDITION ergebnis > 0.).
  • Überprüfung von Invarianten (Zustände, die immer gelten sollten, z. B. innerhalb einer Schleife oder für ein Objekt, ASSERT CONDITION object_ref IS BOUND.).
  • Absicherung gegen “unmögliche” Zustände in CASE- oder IF-Strukturen (z. B. im WHEN OTHERS-Zweig einer CASE -Anweisung, wo man keinen anderen Fall erwartet: ASSERT CONDITION 1 = 0.).

Beispiele

1. Einfache Vorbedingungsprüfung

METHOD calculate_price.
IMPORTING quantity TYPE i.
" Annahme: Menge darf nicht negativ sein für diese Kalkulation
ASSERT CONDITION quantity >= 0.
" ... Preisberechnung ...
ENDMETHOD.

2. Nachbedingungsprüfung mit FIELDS

DATA total TYPE p DECIMALS 2.
DATA item_count TYPE i.
" ... Code, der total und item_count berechnet ...
ASSERT ID zmy_calc_group SUBKEY 'FinalCheck'
FIELDS total item_count
CONDITION total >= 0 AND ( item_count = 0 OR total > 0 ).
" Annahme: Gesamtsumme nie negativ; wenn Items da sind, muss Summe > 0 sein.

3. Prüfung einer Objektreferenz

DATA factory TYPE REF TO zcl_my_factory.
DATA instance TYPE REF TO zif_my_interface.
factory = zcl_my_factory=>get_instance( ).
ASSERT CONDITION factory IS BOUND. " Annahme: Factory existiert immer
instance = factory->create_object( type = 'A' ).
ASSERT CONDITION instance IS BOUND. " Annahme: Objekt wurde erfolgreich erzeugt
instance->do_work( ).

Wichtige Hinweise / Best Practice

  • Nutze ASSERT als Werkzeug zur Qualitätssicherung während der Entwicklung und im Test, nicht zur Behandlung von erwarteten Laufzeitfehlern im Produktivsystem.
  • Verwende immer den ID-Zusatz, um Deine Assertions über SAAB steuerbar zu machen. Wähle sinnvolle Gruppennamen.
  • Nutze den FIELDS-Zusatz, um im Fehlerfall relevante Variablenwerte zu sehen.
  • Stelle sicher, dass Assertions in Produktivsystemen standardmäßig inaktiv geschaltet sind, um Performance-Verluste oder unerwünschte Abbrüche zu vermeiden. Die Aktivierung erfolgt dann gezielt bei Bedarf zur Analyse.
  • Schreibe Assertions für alle nicht-trivialen Annahmen, die Du über Deinen Code oder Deine Daten triffst.