ABAP Unit - TDF (SQL Double)
In diesem Artikel schauen wir uns den SQL Double etwas näher an und wie du Unabhängigkeit zur Datenbank gewinnen kannst.
Inhaltsverzeichnis
Das Test Double Framework (kurz TDF) stellt Werkzeuge zur Verfügung um für die Objekte Klasse, Tabelle und Core Data Service (CDS) zur Testlaufzeit sogenannte Doubles zu erzeugen und gegen sie zu Testen. Diese Technik soll Abhängigkeiten zu schwer testbaren Objekten reduzieren und sich auf den Test der eigentlichen Komponente (Klasse) fokussieren.
Allgemein
Der SQL Double hat die Aufgabe die Datenbankschicht zu ersetzen und somit alle Anfragen (CRUD) auf eine oder mehrere Tabellen zu ersetzen durch ein entsprechendes Double. Bei der Erzeugung können die Tabellen angegeben werden. Dazu die folgende Übersicht des eigentlichen Tests:
Punkt 1) zeigt das normale Testszenario ohne das Test Double, die Zugriffe des Code under Test gehen immer auf die richtigen Daten in der Datenbank. Punkt 2) zeigt das Ziel, wir haben die Daten in der Tabelle durch ein Double ausgetauscht, alle CRUD Operationen laufen gegen das Double und sind damit durch uns abgesichert.
Datenaustausch
Wir tauschen die Daten dabei aber nicht direkt auf der Datenbank aus, diese sind zu jeder Zeit verfügbar und bleiben konsistent. Der erzeugte Test Double steht uns für unsere Testklasse zur Verfügung und wird nach Durchführung wieder entfernt.
Vorteil dieser Technik ist die Stabilität unserer Testfälle, da wir nicht sicher sein können, dass sich unsere Testdaten auf der Datenbank nicht ändern. Mit dieser Technik bleiben Daten für unsere Test immer die gleichen und du musst nicht die Zugriffe auf die Datenbank in andere Klassen auslagern oder gar anpassen.
Beispiel
Um dir den Einsatz der Methodik etwas näher zu bringen, wollen wir dir das Thema an einem Beispiel veranschaulichen. Dabei wollen wir die folgende Tabelle mit einem Double ersetzen:
Als Inhalt der Tabelle gibt es einige Datensätze, die für unsere Test genügen sollten:
Dazu bauen wir nun eine entsprechende Klasse auf, gegen die wir dann unsere Testklasse laufen lassen können. Dazu benötigen wir nur eine einfache Leseroutine, der wir einen Schlüssel übergeben und dann das Ergebnis der Datenbank-Selektion erhalten.
CLASS zcl_bs_demo_double_sql DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
select_tool
IMPORTING
id_sname TYPE char25
RETURNING VALUE(rs_tool) TYPE zbs_dy_tools.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_bs_demo_double_sql IMPLEMENTATION.
METHOD select_tool.
SELECT SINGLE *
FROM zbs_dy_tools
WHERE short_name = @id_sname
INTO @rs_tool.
ENDMETHOD.
ENDCLASS.
Die entsprechende Testklasse sieht nun wie folgt aus.
CLASS ltc_db_access DEFINITION FINAL FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA:
go_environment TYPE REF TO if_osql_test_environment.
CLASS-METHODS:
class_setup,
class_teardown.
METHODS:
positive_case FOR TESTING,
negative_case FOR TESTING.
ENDCLASS.
CLASS ltc_db_access IMPLEMENTATION.
METHOD class_setup.
DATA:
lt_data TYPE STANDARD TABLE OF zbs_dy_tools WITH EMPTY KEY.
go_environment = cl_osql_test_environment=>create( VALUE #( ( 'ZBS_DY_TOOLS' ) ) ).
lt_data = VALUE #(
( short_name = 'SAW' stock_quantity = 15 )
( short_name = 'WRENCH' stock_quantity = 0 )
( short_name = 'NAIL' stock_quantity = 250 )
).
go_environment->insert_test_data( lt_data ).
ENDMETHOD.
METHOD class_teardown.
go_environment->destroy( ).
ENDMETHOD.
METHOD positive_case.
DATA(lo_cut) = NEW zcl_bs_demo_double_sql( ).
DATA(ls_result) = lo_cut->select_tool( 'NAIL' ).
cl_abap_unit_assert=>assert_not_initial( ls_result ).
ENDMETHOD.
METHOD negative_case.
DATA(lo_cut) = NEW zcl_bs_demo_double_sql( ).
DATA(ls_result) = lo_cut->select_tool( 'HAMMER' ).
cl_abap_unit_assert=>assert_initial( ls_result ).
ENDMETHOD.
ENDCLASS.
Ablauf
Wie du oben am Beispiel siehst, sind einige Schritte für die Vorbereitung nötig und wir verwenden dazu die Hilfsmethoden CLASS_SETUP und CLASS_TEARDOWN.
- In der Setup Methode wird zuerst das SQL Environment aufgebaut und die zu tauschenden Tabellen angegeben
- Übergabe der Testdaten an das Environment
- Ausführung der Testfälle gegen die Testdaten
- Abbau der Umgebung beim Abbau der Testklasse
Die Bereitstellung der Daten kann auch im SETUP erfolgen, dazu werden die Daten an die Methode übergeben und zuvor das SQL Double mit CLEAR_DOUBLES aufgeräumt. Die Methode löscht die vorhandenen Daten und leert alle Tabellen. Das Löschen der Daten aus der Tabelle wird vor allem dann eingesetzt, wenn du CRUD Operationen gegen die Tabellen testen willst.
Fazit
Mit dem Test-Double-Framework kannst du verschiedene Komponenten zur Testlaufzeit überbrücken und austauschen, um so den Test auf deinen Code zu reduzieren. Mit dem SQL Double stellst du sicher, dass deine Zugriffe die gewünschten Daten auch finden.