Sie sind auf Seite 1von 92

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

bung und Prosa zum 2-tages Workshop


ABAP Checkpoint
Hhere Softwarequalitt durch ABAP-Checkpoints
In diesen Punkten unterscheiden sich ABAP-Checkpoints von den brigen ABAPAnweisungen. Aus technischer Sicht handelt es sich um operative Anweisungen. Sie werden
ausgefhrt, wenn sie whrend des Programmablaufs erreicht werden. Im Gegensatz zu
normalen operativen Anweisungen sind sie jedoch nicht Teil der Programmlogik. Sie knnen
in den Quelltext eingefgt werden, um die Gltigkeit von Annahmen zu prfen (ASSERT),
um aufzuzeichnen, dass eine bestimmte Programmstelle erreicht wurde und um aktuelle
Variablenwerte festzuhalten (LOG-POINT) oder um in den Debugger zu verzweigen
(BREAK-POINT). Whrend durch ASSERT-Anweisungen die Korrektheit des Programms
garantiert werden kann, tragen Letztere im Wesentlichen zu einer vereinfachten
Programmwartung bei.
Aufgabe : Checkpoint Group anlegen
Transaktion SAAB starten

Name : ZABAP_CHECKPOINTS
Anlegen

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


-

Enter

Paket ZBLKA_00 benutzen


Enter x 3

Enstellen wie oben + sichern

- Einstellungen belassen + Enter

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Testprogramm anlegen

parameters:
p_carrid like sflight-carrid.
*data : max type i.
*Types Declarations of sflight
types : begin of type_s_sflight,
carrid type sflight-carrid,
connid type sflight-connid,
fldate type sflight-fldate,
price type sflight-price,
max type i,
end of type_s_sflight.
*Field String Declarations for sflight
data: fs_sflight type type_s_sflight.
*Internal table for Sflight Data
data : t_sflight like
standard
table of fs_sflight.
data yh1316_subkey type char200.
if p_carrid is initial.
select carrid
connid
fldate
price
from sflight
into fs_sflight.
write: / fs_sflight-carrid,
fs_sflight-connid,
fs_sflight-fldate,
fs_sflight-price.
append fs_sflight to t_sflight.
assert id zabap_checkpoints subkey
'ZABAP_CHECKPOINTS_parameter_if_initial'
fields p_carrid
t_sflight
fs_sflight-carrid
fs_sflight-connid
fs_sflight-fldate
fs_sflight-price
condition p_carrid is initial.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


endselect.
assert id zabap_checkpoints subkey
fields p_carrid
t_sflight
condition p_carrid eq 'LH' .
exit.
else.

'ZABAP_CHECKPOINTS_1'

assert id zabap_checkpoints subkey 'ZABAP_CHECKPOINTS_2'


fields p_carrid
t_sflight
condition p_carrid eq 'lh'.
select carrid connid fldate max( price ) as max
into corresponding fields of fs_sflight
from sflight
where carrid eq p_carrid
group by carrid connid fldate
order by carrid max descending.
if sy-dbcnt < 4.
append fs_sflight to t_sflight.
log-point id zabap_checkpoints subkey 'LOG_POINT'
fields p_carrid
t_sflight
fs_sflight-connid
fs_sflight-fldate
fs_sflight-max.
write: / fs_sflight-carrid, fs_sflight-connid, fs_sflight-fldate,
fs_sflight-max.
endif.
endselect.
endif.

Kontrolle der Haltepunkte im Debugger


Kontrolle der Protokolle ber SAAB
Kontrolle der SQL-Zugriffe ber Debugger Trace
Deaktivierung der Checkpoint Group im Debugger einleiten

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

ABAP Unit Assert_equals


Methodenausprgung :

CL_AUNIT_ASSERT=> ASSERT_EQUALS
CL_ABAP_UNIT_ASSERT=> ASSERT_EQUALS
(Identisch)

Aufgabe : Testen der Methode mit verschiedenen Parametereinstellungen


Prft die Annahme, ob zwei Objekte gleich sind. Die Objekte mssen einen vergleichbaren
Typ besitzen. Es wird ein tiefer Vergleich durchgefhrt, d.h. Tabellen und Strukturen (auch
geschachtelt) werden auf den Inhalt ihrer Komponenten geprft.
Beispielprogramm dazu
report zbeispiel1_00_unit_00.
* Klassen sind Vorlagen fr Objekte.
* Umgekehrt kann man auch den Typ eines Objekts als seine Klasse bezeichnen.
* Eine Klasse ist eine abstrakte Darstellung oder bildlich gesehen eine Bauanleitung
* fr Objekte.
* Zur Beschreibung der Eigenschaften von Objekten enthalten Klassen Komponenten,
* welche den Zustand und das Verhalten von Objekten definieren.
* Lokale Klassen bestehen aus ABAP-Quelltext, der innerhalb der Anweisungen CLASS ENDCLASS
* eingeschlossen ist.
* Eine vollstndige Klassendefinition besteht aus einem Deklarationsteil und falls
erforderlich aus
* einem Implementationsteil.
* Der Deklarationsteil enthlt die Deklaration aller Komponenten (Attribute, Methoden,
Ereignisse)
* einer Klasse.
* Bei lokalen Klassen gehrt der Deklarationsteil von Klassen zu den globalen
Datendeklarationen und
* sollte deshalb auch am Anfang des Programms stehen.
* Falls im Deklarationsteil einer Klasse Methoden deklariert werden, bentigt die Klasse
auch einen
* Implementationsteil. Dieser besteht aus einem Anweisungsblock
class counter definition.
* Public Section
*
* Alle im ffentlichen Abschnitt deklarierten Komponenten
* sind fr alle Verwender sowie in den Methoden aller Erben
* und der Klasse selbst ansprechbar.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


* Die ffentlichen Komponenten stellen die Schnittstelle
* der Klasse zu jedem Verwender dar.
public section.
* Methoden sind klasseninterne Prozeduren, die das Verhalten eines
* Objekts bestimmen.
* Sie haben Zugriff auf alle Attribute ihrer Klasse und knnen
* somit den Zustand eines Objekts verndern.
* Methoden haben eine Parameterschnittstelle, ber die sie beim
* Aufruf mit Werten versorgt werden und ber die sie Werte an
* den Aufrufer zurckgeben knnen.
* Die privaten Attribute einer Klasse knnen nur durch Methoden
* der gleichen Klasse gendert werden.
* Bezglich Definition und Parameterbergabe hneln Methoden
* den bisherigen Funktionsbausteinen.
* Eine Methode meth wird im Deklarationsteil einer Klasse deklariert
* und im teil der Klasse durch den Verarbeitungsblock
methods: set importing value(set_value) type i,
increment,
get returning value(get_value) type i.
* Private Section
*
* Alle im privaten Abschnitt deklarierten Komponenten sind nur
* in den Methoden der Klasse selbst ansprechbar und auch nicht
* fr die Erben sichtbar.
* Die privaten Komponenten stellen somit keine Schnittstelle zu den
* Verwendern der Klasse dar.
private section.
data count type i.
endclass.
class counter implementation.
method set.
count = set_value.
endmethod.
method increment.
add 1 to count.
endmethod.
method get.
get_value = count.
endmethod.
endclass.
"mytest IMPLEMENTATION
data number type i value 5.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

* Klassenreferenzen werden vollstndig mit dem Zusatz


* ... TYPE REF TO class
* der TYPES- oder DATA-Anweisung definiert, wobei class eine Klasse bezeichnet.
* Eine Referenzvariable vom Typ Klassenreferenz heit Klassenreferenzvariable
* oder ebenfalls kurz Klassenreferenz.
data cnt type ref to counter.
start-of-selection.
break se80.
* Die Anweisung CREATE OBJECT erzeugt eine Instanz einer Klasse bzw. ein Objekt
* und weist die Referenz auf das Objekt der Referenzvariablen oref zu.
* Direkt nach der Erzeugung des Objekts wird der Instanzkonstruktor
* der Klasse ausgefhrt.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
write number.
im ndern Mode Code ergnzen

*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
methods mytest for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

*----------------------------------------------------------------------*
class counter_test implementation.
method mytest.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
cl_aunit_assert=>assert_equals( act = number
exp = '24'
msg = 'Wert wurde falsch berechnet'
*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,
* Folgeaktionen ableiten zu knnen.
*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
==================================================================
====================
level = '0'
quit = '2'
tol = '2'
).
endmethod.
"mytest
endclass.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

- act ist der zu berprfende Ist-Wert.


- exp ist der erwartete Wert fr den Vergleich
- tol ist die Toleranz fr Vergleiche von Gleitpunktzahlen (bei den Assert-Methoden
assert_differs und assert_equals).
_ msg bietet die Mglichkeit, einen erluternden Text zur Fehlerursache zu bergeben, der
dann in der Ergebnisanzeige angezeigt wird. Das kann hilfreich sein, falls zum Beispiel eine
Testmethode mehrmals dieselbe Assert-Methode ruft.
_ level definiert die Prioritt des Fehlers und kann einen der Werte
if_aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert ist critical.
Beim Auftreten eines Fehlers spiegelt sich die Prioritt
in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests ntzlich sein, um die
Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit, Folgeaktionen ableiten zu
knnen.
_ quit wirkt sich auf den Kontrollfluss der Testausfhrung aus und kann einen der Werte
if_aunit_constants=>no, method, class oder program annehmen, der Standardwert ist method.
_ no bedeutet, dass der Test bei einem Fehler nicht unterbrochen, sondern mit der
nachfolgenden Anweisung fortgesetzt wird. Das ermglicht der Testmethode, mehrere
Fehler zu melden.
_ method legt fest, dass die Ausfhrung der Testmethode beendet wird, wenn ein
Fehler auftritt.
_ class bedeutet, dass ein Fehler die Ausfhrung aller Methoden der Testklasse
abbricht.
_ program gibt an, dass eine weitere Ausfhrung von Tests des Programms nicht
sinnvoll ist.
-

testen Sie ber

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

10

1. Fehlerarten
Fhrt die Ausfhrung eines Modultests in der Workbench zu einem Fehler, erscheint
automatisch die Ergebnisanzeige (siehe Abbildung). Die Anzeige ist in drei Bereiche
aufgeteilt. Der linke Bereich enthlt eine Hierarchie aller getesteten Programme und
ausgefhrten Testklassen und Testmethoden, rechts oben steht eine Liste der aufgetretenen
Fehler, und der rechte untere Bereich zeigt die Details zu einem Fehler an.

Die Anzeige der Testhierarchie spiegelt die Testaufgabe wider. Wie zum Beispiel in der
Abbildung dargestellt, wurde in der Testaufgabe die lokale Klasse counter mit allen
enthaltenen Testklassen und dazugehrigen Testmethoden berprft. Hinter den einzelnen
Elementen erscheinen eine Ikone, die den Status darstellt, sowie die Summe der jeweils
aufgetretenen Fehler. Die Ikone hat dabei folgende Bedeutung:
_ Ein grnes Quadrat ( ) zeigt an, dass der Test ohne Fehler ausgefhrt wurde.
_ Ein gelbes Dreieck ( ) bedeutet, dass der Test ausschlielich tolerierbare Meldungen
ausgelst hat.
_ Ein roter Kreis ( ) weist darauf hin, dass mindestens ein nicht tolerierbarer Fehler whrend
des Tests aufgetreten ist.
Mit der Funktion Meldungsart kann die Darstellung der Summen auf die Fehlerart umgestellt
werden. Die Auswahl einer Summe aktualisiert die Fehlerliste entsprechend, das heit alle
betreffenden Fehlermeldungen erscheinen in der Liste.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

testen Sie die Fehlerarten ber die Anpassung


level = '0'
level = '1'
level = '2'

2.. Toleranz
Definieren Sie einen Toleranzwert und testen diesen

level = '2'
quit = '2'
*
* Toleranz 2 testen
* ===================
tol = '2'
).

Passen Sie den Eingangswert Wert an (6/7/9)

data number type i value 5.

Ausfhren mit Strg + Umsch F10

11

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

12

ABAP Unit in Form-Routiinen


Methodenausprgung :

CL_AUNIT_ASSERT=> ASSERT_DIFFERS
CL_ABAP_UNIT_ASSERT=> ASSERT_DIFFERS
(Identisch)

Stellt die Verschiedenheit zweier elementaren Datenobjekte (Typ SIMPLE) sicher. Sollten die
Typen der Datenobjekte nicht ineinander konvertierbar sein, wird einen Prffehler ausgelst.

Aufgabe : Testen der Methode mit verschiedenen


Parametereinstellungen

report zbeispiel2_00_unit_00.
* Klassen sind Vorlagen fr Objekte.
* Umgekehrt kann man auch den Typ eines Objekts als seine Klasse bezeichnen.
* Eine Klasse ist eine abstrakte Darstellung oder bildlich gesehen eine Bauanleitung
* fr Objekte.
* Zur Beschreibung der Eigenschaften von Objekten enthalten Klassen Komponenten,
* welche den Zustand und das Verhalten von Objekten definieren.
* Lokale Klassen bestehen aus ABAP-Quelltext, der innerhalb der Anweisungen CLASS ENDCLASS
* eingeschlossen ist.
* Eine vollstndige Klassendefinition besteht aus einem Deklarationsteil und falls
erforderlich aus
* einem Implementationsteil.
* Der Deklarationsteil enthlt die Deklaration aller Komponenten (Attribute, Methoden,
Ereignisse)
* einer Klasse.
* Bei lokalen Klassen gehrt der Deklarationsteil von Klassen zu den globalen
Datendeklarationen und
* sollte deshalb auch am Anfang des Programms stehen.
* Falls im Deklarationsteil einer Klasse Methoden deklariert werden, bentigt die Klasse
auch einen
* Implementationsteil. Dieser besteht aus einem Anweisungsblock
class counter definition.
* Public Section
*
* Alle im ffentlichen Abschnitt deklarierten Komponenten
* sind fr alle Verwender sowie in den Methoden aller Erben
* und der Klasse selbst ansprechbar.
* Die ffentlichen Komponenten stellen die Schnittstelle
* der Klasse zu jedem Verwender dar.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

public section.
* Methoden sind klasseninterne Prozeduren, die das Verhalten eines
* Objekts bestimmen.
* Sie haben Zugriff auf alle Attribute ihrer Klasse und knnen
* somit den Zustand eines Objekts verndern.
* Methoden haben eine Parameterschnittstelle, ber die sie beim
* Aufruf mit Werten versorgt werden und ber die sie Werte an
* den Aufrufer zurckgeben knnen.
* Die privaten Attribute einer Klasse knnen nur durch Methoden
* der gleichen Klasse gendert werden.
* Bezglich Definition und Parameterbergabe hneln Methoden
* den bisherigen Funktionsbausteinen.
* Eine Methode meth wird im Deklarationsteil einer Klasse deklariert
* und im teil der Klasse durch den Verarbeitungsblock
methods: set importing value(set_value) type i,
increment,
get returning value(get_value) type i.
* Private Section
*
* Alle im privaten Abschnitt deklarierten Komponenten sind nur
* in den Methoden der Klasse selbst ansprechbar und auch nicht
* fr die Erben sichtbar.
* Die privaten Komponenten stellen somit keine Schnittstelle zu den
* Verwendern der Klasse dar.
private section.
data count type i.
endclass.
class counter implementation.
method set.
count = set_value.
endmethod.
method increment.
add 1 to count.
endmethod.
method get.
get_value = count.
endmethod.
endclass.
"mytest IMPLEMENTATION
data number type i.
* Klassenreferenzen werden vollstndig mit dem Zusatz

13

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

14

* ... TYPE REF TO class


* der TYPES- oder DATA-Anweisung definiert, wobei class eine Klasse bezeichnet.
* Eine Referenzvariable vom Typ Klassenreferenz heit Klassenreferenzvariable
* oder ebenfalls kurz Klassenreferenz.
data cnt type ref to counter.
start-of-selection.
break se80.
perform prozess_ablauf .
write number.
*
* Die Anweisung CREATE OBJECT erzeugt eine Instanz einer Klasse bzw. ein Objekt
* und weist die Referenz auf das Objekt der Referenzvariablen oref zu.
* Direkt nach der Erzeugung des Objekts wird der Instanzkonstruktor
* der Klasse ausgefhrt.
*
==================================================================
=============
form prozess_ablauf.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
endform.
*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
methods number_test for testing.
methods formroutine_test for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test implementation.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

15

method number_test.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
* cl_aunit_assert=>assert_equals( act = number
cl_abap_unit_assert=>assert_equals( act = number
exp = '7'
* TEXT-001 'Wert wurde falsch berechnet'
msg = 'Wert wurde falsch berechnet'(001)
*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,
* Folgeaktionen ableiten zu knnen.
*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
==================================================================
====================
level = '2'
quit = '2'
*
* Toleranz 2 testen
* ===================
tol = '0'
).
endmethod.
"mytest
method formroutine_test.
*DATA ACT
TYPE SIMPLE.
*DATA EXP
TYPE SIMPLE.
*DATA TOL
TYPE F.
data msg
type string.
*DATA LEVEL
TYPE AUNIT_LEVEL.
*DATA QUIT
TYPE AUNIT_FLOWCTRL.
data assertion_failed type abap_bool.
perform prozess_ablauf.
assertion_failed = cl_abap_unit_assert=>assert_differs(
act
= number

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

exp
tol
msg
level
quit
).

16

= '3'
= tol
= msg
= if_aunit_constants=>critical
= if_aunit_constants=>program

endmethod.
endclass.

testen der Ausprgung


quit
= if_aunit_constants=>program
quit
= if_aunit_constants=>class
quit
= if_aunit_constants=>method

ABAP Unit mit Globalen Klassen


Methodenausprgung : CL_AUNIT_ASSERT=> ASSERT_INITIAL/
ASSERT_NOT_INITIAL
CL_ABAP_UNIT_ASSERT=> => ASSERT_INITIAL/ ....
(Identisch)
Prft ein Objekt auf seinen Initialwert, indem sie die ABAP-Eigenschaft IS INITIAL testet.
Stellt sicher, dass ein Datenobjekt NICHT seinen Initialwert hat (Prfung auf die ABAPEigenschaft IS NOT INITIAL).

Aufgabe : Testen der Methoden mit dem Fokus auf die


Ergebnisanzeige
Beispielprogramm

report zbeispiel3_00_unit_00.
* Klassen sind Vorlagen fr Objekte.
* Umgekehrt kann man auch den Typ eines Objekts als seine Klasse bezeichnen.
* Eine Klasse ist eine abstrakte Darstellung oder bildlich gesehen eine Bauanleitung
* fr Objekte.
* Zur Beschreibung der Eigenschaften von Objekten enthalten Klassen Komponenten,
* welche den Zustand und das Verhalten von Objekten definieren.
* Lokale Klassen bestehen aus ABAP-Quelltext, der innerhalb der Anweisungen CLASS ENDCLASS
* eingeschlossen ist.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


* Eine vollstndige Klassendefinition besteht aus einem Deklarationsteil und falls
erforderlich aus
* einem Implementationsteil.
* Der Deklarationsteil enthlt die Deklaration aller Komponenten (Attribute, Methoden,
Ereignisse)
* einer Klasse.
* Bei lokalen Klassen gehrt der Deklarationsteil von Klassen zu den globalen
Datendeklarationen und
* sollte deshalb auch am Anfang des Programms stehen.
* Falls im Deklarationsteil einer Klasse Methoden deklariert werden, bentigt die Klasse
auch einen
* Implementationsteil. Dieser besteht aus einem Anweisungsblock
class counter definition.
* Public Section
*
* Alle im ffentlichen Abschnitt deklarierten Komponenten
* sind fr alle Verwender sowie in den Methoden aller Erben
* und der Klasse selbst ansprechbar.
* Die ffentlichen Komponenten stellen die Schnittstelle
* der Klasse zu jedem Verwender dar.
public section.
* Methoden sind klasseninterne Prozeduren, die das Verhalten eines
* Objekts bestimmen.
* Sie haben Zugriff auf alle Attribute ihrer Klasse und knnen
* somit den Zustand eines Objekts verndern.
* Methoden haben eine Parameterschnittstelle, ber die sie beim
* Aufruf mit Werten versorgt werden und ber die sie Werte an
* den Aufrufer zurckgeben knnen.
* Die privaten Attribute einer Klasse knnen nur durch Methoden
* der gleichen Klasse gendert werden.
* Bezglich Definition und Parameterbergabe hneln Methoden
* den bisherigen Funktionsbausteinen.
* Eine Methode meth wird im Deklarationsteil einer Klasse deklariert
* und im teil der Klasse durch den Verarbeitungsblock
methods: set importing value(set_value) type i,
increment,
get returning value(get_value) type i.
* Private Section
*
* Alle im privaten Abschnitt deklarierten Komponenten sind nur
* in den Methoden der Klasse selbst ansprechbar und auch nicht
* fr die Erben sichtbar.
* Die privaten Komponenten stellen somit keine Schnittstelle zu den

17

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

18

* Verwendern der Klasse dar.


private section.
data count type i.
endclass.
class counter implementation.
method set.
count = set_value.
endmethod.
method increment.
add 1 to count.
endmethod.
method get.
get_value = count.
endmethod.
endclass.
"mytest IMPLEMENTATION
data number type i.
* Klassenreferenzen werden vollstndig mit dem Zusatz
* ... TYPE REF TO class
* der TYPES- oder DATA-Anweisung definiert, wobei class eine Klasse bezeichnet.
* Eine Referenzvariable vom Typ Klassenreferenz heit Klassenreferenzvariable
* oder ebenfalls kurz Klassenreferenz.
data cnt type ref to counter.
start-of-selection.
break se80.
perform prozess_ablauf .
write number.
*
* Die Anweisung CREATE OBJECT erzeugt eine Instanz einer Klasse bzw. ein Objekt
* und weist die Referenz auf das Objekt der Referenzvariablen oref zu.
* Direkt nach der Erzeugung des Objekts wird der Instanzkonstruktor
* der Klasse ausgefhrt.
*
==================================================================
=============
form prozess_ablauf.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

19

number = cnt->get( ).
endform.
*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
data: lv_abap_bool type abap_bool.
methods number_test for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test implementation.
method number_test.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
cl_aunit_assert=>assert_initial( act = number
* TEXT-001 'Wert wurde falsch berechnet'
msg = 'Wert ist nicht initial'(001)
*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,
* Folgeaktionen ableiten zu knnen.
*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
==================================================================
====================

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

endmethod.
endclass.

level = '2'
quit = '2' ).
"mytest

Prfung durchfhren

ber SE24 lokale Klasse in globale Klasse umsetzen

Funktion auswhlen

Programmnamen eingeben + enter


1.Zeile markieren
Prefix Z eingeben suffix Gruppe anpassen
Importieren (F5)
Sichern

20

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Klasse aktivieren
Klasse testen

Methode Set belegen


Methode increment ausfhren
Methode get ausfhren

21

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Ergebnis kontrollieren

Passen Sie ihr Programm an

*&---------------------------------------------------------------------*
*& Report ZBEISPIEL1_00
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
report zbeispiel3_00_unit_00.
data number type i.
* Klassenreferenzen werden vollstndig mit dem Zusatz
* ... TYPE REF TO class
* der TYPES- oder DATA-Anweisung definiert, wobei class eine Klasse bezeichnet.
* Eine Referenzvariable vom Typ Klassenreferenz heit Klassenreferenzvariable
* oder ebenfalls kurz Klassenreferenz.
data cnt type ref to zcl_counter_99.
start-of-selection.
break se80.

22

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

23

perform prozess_ablauf .
write number.
*
* Die Anweisung CREATE OBJECT erzeugt eine Instanz einer Klasse bzw. ein Objekt
* und weist die Referenz auf das Objekt der Referenzvariablen oref zu.
* Direkt nach der Erzeugung des Objekts wird der Instanzkonstruktor
* der Klasse ausgefhrt.
*
==================================================================
=============
form prozess_ablauf.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
endform.
*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
data: lv_abap_bool type abap_bool.
methods number_test for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test implementation.
method number_test.
create object cnt.
cnt->set( exporting set_value = number ).
do 3 times.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


*

24

cnt->increment( ).
enddo.
number = cnt->get( ).
* cl_aunit_assert=>assert_equals( act = number
cl_aunit_assert=>assert_not_initial( act = number
* TEXT-001 'Wert wurde falsch berechnet'
msg = 'Wert ist initial'(001)
*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,
* Folgeaktionen ableiten zu knnen.
*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
==================================================================
====================
level = '2'
quit = '2' ).
endmethod.
"mytest
endclass.

Testen Sie das Programm

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

25

Ergebnisliste
Fhrt die Ausfhrung eines Modultests in der Workbench zu einem Fehler, erscheint
automatisch die Ergebnisanzeige (siehe Abbildung). Die Anzeige ist in drei Bereiche
aufgeteilt. Der linke Bereich enthlt eine Hierarchie aller getesteten Programme und
ausgefhrten Testklassen und Testmethoden, rechts oben steht eine Liste der aufgetretenen
Fehler, und der rechte untere Bereich zeigt die Details zu einem Fehler an.

Die Anzeige der Testhierarchie spiegelt die Testaufgabe wider. Wie zum Beispiel in
Abbildung 10.3 dargestellt, wurde in der Testaufgabe die globale Klasse zcl_counter_99 mit
allen enthaltenen Testklassen und dazugehrigen Testmethoden berprft. Hinter den
einzelnen Elementen erscheinen eine Ikone, die den Status darstellt, sowie die Summe der
jeweils aufgetretenen Fehler. Die Ikone hat dabei folgende Bedeutung:
_ Ein grnes Quadrat ( ) zeigt an, dass der Test ohne Fehler ausgefhrt wurde.
_ Ein gelbes Dreieck ( ) bedeutet, dass der Test ausschlielich tolerierbare Meldungen
ausgelst hat.
_ Ein roter Kreis ( ) weist darauf hin, dass mindestens ein nicht tolerierbarer Fehler whrend
des Tests aufgetreten ist.
Mit der Funktion Nachrichtentyp kann die Darstellung der Summen auf die Fehlerart
umgestellt werden.
_ Prffehler
Ein gelber Blitz steht fr einen Prffehler. Das bedeutet, dass eine der Assert-Methoden eine
Verletzung der Testannahme festgestellt hat.
_ Ausnahmefehler
Ausnahmefehler sind durch das Stoppsignal dargestellt. Beim Auftreten einer klassenbasierten
Ausnahme fngt ABAP Unit diese automatisch ab. Es ist empfehlenswert, diese nicht im Test
zu fangen und danach mit einem eigenen Aufruf einer Assert-Methode zu melden, da dabei
die Stack-Information verloren geht.
_ Laufzeitfehler
Der rote Blitz ist die Folge eines Laufzeitfehlers. Ein Programm kann aus verschiedenen
Grnden, wie zum Beispiel durch einen Programmierfehler oder explizit mit dem Befehl
ASSERT durch einen Laufzeitfehler, abgebrochen werden. Die Ursache kann dem dazu

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

26

abgespeicherten Kurzdump entnommen werden, der ber die ABAP-Dumpanalyse


(Transaktion ST22) angezeigt werden kann (mehr dazu in Kapitel 7, Einsatz der ABAP-Testund -Analysewerkzeuge in allen Phasen des Entwicklungsprozesses).
_ Warnungen
Warnungen deuten nicht auf Fehler im getesteten Programm, sondern im Modultest hin. So
darf eine Testklasse zum Beispiel keinen Instanzkonstruktor mit nicht optionalen Parametern
haben. Falls doch, kann ABAP Unit die Testklasse nicht instanzieren, und es gibt die
entsprechende Warnung.
Detailsicht
Die Detailanzeige zeigt fr einen Fehler Informationen zu seiner Ursache und gibt die
zugehrigen Programmstellen aus. Die Ausgabe enthlt eine Erluterung der Fehlermeldung
und gibt den Grund fr die Meldung an. Fr Prffehler wird in dieser Analyse beschrieben,
weshalb die Assert-Methode fehlgeschlagen
ist.
Wenn Sie zum Beispiel zwei Strings mithilfe der Methode assert_equals vergleichen, zeigt die
Fehleranalyse, an welcher Position sich die Strings wie unterscheiden (siehe Beispiel )
Bei Ausnahmen wird der Text der ausgelsten Ausnahme angezeigt. Im Fall von Warnungen
liefert dieser Abschnitt gegebenenfalls weitere Informationen. Unterhalb des Knotens Stack
finden sich die fr den Test relevanten Stack-Informationen, das heit eine Liste mit
(Include-)Programmen und Zeilennummer. Die Auswahl eines Stack-Eintrags fhrt direkt zur
Anzeige des entsprechenden Quelltextes

ABAP Unit mit Impliziten (Fixture) Methoden

Methodenausprgung : CL_AUNIT_ASSERT=> ASSERT_BOUND/


ASSERT_NOT_BOUND
CL_ABAP_UNIT_ASSERT=> => ASSERT_BOUND/ ....
(Identisch)
Ungltigkeit /Gltigkeit einer Referenz fr eine Referenzvariable sicherstellen

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Beispielprogramm

*&---------------------------------------------------------------------*
*& Report ZBEISPIEL2_00
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
report zbeispiel4_00_unit_00.
class counter definition.
public section.
methods: constructor importing value(set_value) type i,
increment,
get returning value(get_value) type i.
private section.
data count type i.
endclass.
class counter implementation.
method constructor.
count = set_value.
endmethod.
method increment.
add 1 to count.
endmethod.
method get.
get_value = count.
endmethod.
endclass.
data number type i value 5.
data cnt type ref to counter.
start-of-selection.
break se80.
create object cnt exporting set_value = number.
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).

27

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

28

write number.
*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
data: lv_abap_bool type abap_bool.
methods: setup, teardown.
methods number_test for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class counter_test implementation.
method number_test.
break se80.
do 3 times.
cnt->increment( ).
enddo.
number = cnt->get( ).
cl_aunit_assert=>assert_not_bound( act = cnt
msg = 'Nullreferenz erwartet'(001)
*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,
* Folgeaktionen ableiten zu knnen.
*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
==================================================================
====================
level = '2'
quit = '2' ).
endmethod.
"mytest
method teardown.
break se80.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

29

free cnt.
endmethod.
method setup.
break se80.
create object cnt exporting set_value = number.
endmethod.
endclass.

Debugging und Ablauf erkennen

Haben alle Testmethoden identische Anforderungen an das Umfeld, bietet sich die
Verwendung der Spezialmethoden setup und teardown an. Sind Methoden dieser Namen in
der PRIVATE SECTION der Testklasse definiert, fhrt die ABAPLaufzeitumgebung sie
automatisch vor bzw. nach Aufruf jeder einzelnen Testmethode
aus, es ist kein expliziter Aufruf erforderlich. ABAP Unit startet zunchst setup, dann eine
Testmethode und schlielich teardown. Sie gleichen also einer Art Konstruktor und
Destruktor fr Testmethoden.
Ist die Erzeugung des Umfeldes teuer, kann es sinnvoll sein, dieses nur einmal fr die
Testklasse aufzubauen. Mit den statischen Methoden class_setup bzw. class_teardown ist es
mglich, einen bergreifenden Kontext fr alle Testmethoden zur Verfgung zu stellen. Dabei
sollten die Testmethoden auf gemeinsam genutzte Daten nur lesend zugreifen, da sonst
Abhngigkeiten zwischen den Testmethoden entstehen, die oft ein instabiles Verhalten der
Tests zur Folge haben.
ABAP Unit mit Enhancement Technologie
Methodenausprgung : CL_AUNIT_ASSERT=>ASSERT_CHAR_NP/ CP
CL_ABAP_UNIT_ASSERT=> =>ASSERT_CHAR_NP/ CP
(Identisch)
Stellt sicher, dass eine Zeichenkette zu einem einfachen Muster passt. Mgliche Ersatzzeichen
sind Asterisk (*) und Fragezeichen (?)
Stellt sicher, dass eine Zeichenkette nicht zu
einem einfachen Muster passt. Mgliche Ersatzzeichen sind Asterisk (*) und Fragezeichen
(?).

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Beispielprogramm

report zbeispiel6_00_unit_00 .
data: it_sbook type table of sbook,
wa_sbook type sbook.
data: int_sw type i.
data: t1 type i, t2 type i, t3 type i, t4 type i.
data: d1 type i.
select-options : socarrid for wa_sbook-carrid,
soconnid for wa_sbook-connid.
start-of-selection.
get run time field t1.
perform lesen_sbook.
get run time field t2.
sort it_sbook.
get run time field t3.
loop at it_sbook into wa_sbook.
at new fldate.
new-page.
format color col_heading intensified on.
write: / wa_sbook-carrid,
wa_sbook-connid,
wa_sbook-fldate.
uline.
int_sw = 1.
endat.
if int_sw = 1.
format intensified on.
int_sw = 0.
else.
format intensified off.
int_sw = 1.
endif.
format color col_normal.
write: / wa_sbook-bookid,
wa_sbook-customid,
wa_sbook-custtype,
wa_sbook-smoker,

30

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


wa_sbook-luggweight unit wa_sbook-wunit,
wa_sbook-wunit,
wa_sbook-class,
wa_sbook-forcuram currency wa_sbook-forcurkey,
wa_sbook-forcurkey,
wa_sbook-cancelled.
endloop.
get run time field t4.
d1 = t2 - t1.
write: / 'CPU Select' , d1.
d1 = t3 - t2.
write: / 'CPU Sort ' , d1.
d1 = t4 - t3.
write: / 'CPU Loop ' , d1.
form lesen_sbook.
select *
from sbook
into table it_sbook
where carrid in socarrid
and connid in soconnid.
endform.

Programm anlegen und in den Anzeigen-Mode wechseln

in den Erweiternmode wechseln

31

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

implizite Erw-Optionen einblenden

Popup ausfllen

Enter

32

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

33

Zeile 72 erweitern

*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lesen_sbook_test definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
data: lv_abap_bool type abap_bool.
methods lesen_sbook for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lesen_sbook_test implementation.
method lesen_sbook.
break se80.
perform lesen_sbook.
loop at it_sbook into wa_sbook.
cl_aunit_assert=>assert_char_cp( act = wa_sbook-smoker
exp = 'X'
msg = 'X nicht gefunden'(001)
*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

34

* Folgeaktionen ableiten zu knnen.


*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
==================================================================
====================
level = '2'
quit = '2' ).
endloop.
endmethod.
"mytest
endclass.

Testen
Ggf mit SAUNIT_CLIENT_SETUP - ABAP-Unit-Konfiguration nutzen und
Level hochsetzen

ABAP Unit mit dem Testklassen-Wizzard


Methodenausprgung :

CL_ABAP_UNIT_ASSERT=>ASSERT_TABLE_CONTAINS

Stellt sicher, dass ein Datenobjekt als Zeile einer internen Tabelle vorkommt.
Legen Sie eine Klasse ber SE24 an

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Cut & Paste

BANKS
CH_BNKA

Importing
Exporting

Type BNKA-BANKS
Type BF_BNKA

'DE'

method lesen.
select * from bnka into table ch_bnka where banks = banks.
endmethod.

Testen der Methode

Legen Sie eine Testklasse ber den Wizzard an

Testklassenwizzard starten

35

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

weiter

anlegen

36

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

37

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

fertig stellen
beide Klassen aktivieren

Klasse testen

Stellen Sie den Test auf die Methode


CL_AUNIT_ASSERT=>ASSERT_TABLE_CONTAINS um

38

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

lokale Testklassen anklicken

neue Codesequenz einbinden

39

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

class zcl_bank_00_test definition for testing


duration long
risk level critical
.
*?<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
*?<asx:values>
*?<TESTCLASS_OPTIONS>
*?<TEST_CLASS>zcl_Bank_00_Test
*?</TEST_CLASS>
*?<TEST_MEMBER>f_Cut
*?</TEST_MEMBER>
*?<OBJECT_UNDER_TEST>ZCL_BANK_00
*?</OBJECT_UNDER_TEST>
*?<OBJECT_IS_LOCAL/>
*?<GENERATE_FIXTURE>X
*?</GENERATE_FIXTURE>
*?<GENERATE_CLASS_FIXTURE>X
*?</GENERATE_CLASS_FIXTURE>
*?<GENERATE_INVOCATION>X
*?</GENERATE_INVOCATION>
*?<GENERATE_ASSERT_EQUAL>X
*?</GENERATE_ASSERT_EQUAL>
*?</TESTCLASS_OPTIONS>
*?</asx:values>
*?</asx:abap>
private section.
data:
f_cut type ref to zcl_bank_00. "class under test
class-methods: class_setup.
class-methods: class_teardown.
methods: setup.
methods: teardown.
methods: lesen for testing.
endclass.
"zcl_Bank_00_Test
class zcl_bank_00_test implementation.
method class_setup.

endmethod.
method class_teardown.
endmethod.
method setup.
create object f_cut.
endmethod.

40

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

method teardown.
free f_cut.
endmethod.
method lesen.
data banks type banks.
data ch_bnka type bf_bnka.
banks = 'DE'.
f_cut->lesen(
exporting
banks = banks
importing
ch_bnka = ch_bnka
).
data line
type line of bf_bnka.
*DATA MSG
TYPE CSEQUENCE.
*DATA LEVEL
TYPE AUNIT_LEVEL.
*DATA QUIT
TYPE AUNIT_FLOWCTRL.
data assertion_failed type abap_bool.
select single * from bnka into corresponding fields of line where banks =
'DE'. " mit DE und EN testen
assertion_failed = cl_abap_unit_assert=>assert_table_contains(
line
= line
table
= ch_bnka
msg
= 'Buchungssatz nicht gefunden'
* level
= IF_AUNIT_CONSTANTS=>CRITICAL
* quit
= IF_AUNIT_CONSTANTS=>METHOD
).
endmethod.

endclass.

Einbetten + aktivieren + testen

41

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

- Ergebnis kontrollieren

ABAP Unit als globale Klasse (EMAIL-Validation)


Methodenausprgung : CL_ABAP_UNIT_ASSERT=>

ASSERT_TEXT_MATCHES
ASSERT_TRUE
Stellt sicher, dass eine Zeichenkette die Bedingungen eines regulren Ausdrucks erfllt.

42

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Legen Sie eine Klasse ber SE24 an

anlegen

Testklasse markieren
Final raus
Abstrakt einstelln
sichern

method email_validieren.
*
* ^ Anchor character for the start of a line
* $ Anchor character for the end of a line
* [ ] Definition of a value set for single characters
* Placeholder for any alphanumeric character including _

43

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

44

* {n,m} Concatenation of at least n and a maximum of m single characters


*
==================================================================
====
data pattern
type string value '^[=-]+@[-]+[]{2,3}$'.
* DATA TEXT
TYPE CSEQUENCE.
* DATA MSG
TYPE CSEQUENCE.
* DATA LEVEL
TYPE AUNIT_LEVEL.
* DATA QUIT
TYPE AUNIT_FLOWCTRL.
data assertion_failed type abap_bool.
assertion_failed = cl_abap_unit_assert=>assert_text_matches(
pattern
= pattern
text
= im_mail
msg
= 'Mail nicht valide'
*
level
= IF_AUNIT_CONSTANTS=>CRITICAL
*
quit
= IF_AUNIT_CONSTANTS=>METHOD
).
endmethod.

Schnittstellenparameter definieren

Statische Methode
Button Parameter anklicken

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Aktivieren

45

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

46

Fertige Klasse
class ZCL_AUTEST_EMAIL_01 definition
public
abstract
create public
for testing .
public section.
class-methods EMAIL_VALIDIEREN
importing
!IM_MAIL type STRING .
protected section.
private section.
ENDCLASS.

CLASS ZCL_AUTEST_EMAIL_01 IMPLEMENTATION.


* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Static Public Method ZCL_AUTEST_EMAIL_01=>EMAIL_VALIDIEREN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_MAIL
TYPE
STRING
* +-------------------------------------------------------------------------------------</SIGNATURE>
method EMAIL_VALIDIEREN.
*
* ^ Anchor character for the start of a line
* $ Anchor character for the end of a line
* [ ] Definition of a value set for single characters
* Placeholder for any alphanumeric character including _
* {n,m} Concatenation of at least n and a maximum of m single characters
*
======================================================
================
data pattern
type string value
'^[\w\.=-]+@[\w\.-]+\.[\w]{2,3}$'* DATA MSG
TYPE CSEQUENCE.
* DATA LEVEL
TYPE AUNIT_LEVEL.
* DATA QUIT
TYPE AUNIT_FLOWCTRL.
data assertion_failed type abap_bool.
assertion_failed = cl_abap_unit_assert=>assert_text_matches(
pattern
= pattern
text
= im_mail
msg
= 'Mail nicht valide'
*
level
= IF_AUNIT_CONSTANTS=>CRITICAL
*
quit
= IF_AUNIT_CONSTANTS=>METHOD
).
endmethod.
ENDCLASS.

aktivieren

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Hauptklasse ZCL_EMAIL_00 / methode EMAIL_LESEN anlegen

sichern

method EMAIL_LESEN.
data: email type string value 'roland.kirsch@t-online.de'.

47

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

48

ch_email = email.
endmethod.

value( CH_EMAIL ) TYPE STRING

als Returning-Parameter

- aktivieren
Fertige Klasse

class ZCL_EMAIL_00 definition


public
final
create public .
public section.
methods EMAIL_LESEN
returning
value(CH_EMAIL) type STRING .
protected section.
private section.
ENDCLASS.

CLASS ZCL_EMAIL_00 IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMAIL_00->EMAIL_LESEN
* +-------------------------------------------------------------------------------------------------+
* | [<-()] CH_EMAIL
TYPE
STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
method EMAIL_LESEN.
data: email type string value 'roland.kirsch@t-online.de'.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


ch_email = email.
endmethod.
ENDCLASS.

Generieren Sie eine Testklasse zur globalen Klasse im Enhancement-Konzept

Klasse Erweitern

- Popup ausfllen

enter
sichern

49

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Testklasse generieren

weiter

50

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Testklasse anlegen

enter

weiter

51

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Supertyp zuordnen

weiter

52

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

weiter + fertig stellen

Codesequence zcl_email_00_test=> email_lesen


data: ch_email type string.
create object f_cut.
ch_email = f_cut->email_lesen( ).
email_validieren( ch_email ).

aktivieren und testen

53

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Legen Sie einen Code-Inspektor Ablauf an (Transaktion SCI)

Prfvariante

Objektmenge

54

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Inspektion

ausfhren

Ergebnis als Tabelle

55

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Ergebnis als Tabelle analysieren

Favoriten im AbapUnitBrowser
Hilfsmittel - Einstellungen Workbench allgemein

enter

56

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

57

ne
-

Favorit anlegen (ihr Paket)

enter

Elemente einfgen

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

ausfhren

auswhlen

58

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

sichern
ausfhren

Kontrolle

ATC nutzen (ggf SE03 mit einbeziehen)

ATC konfigurieren

59

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Standardeinstellung prfen

Funktionsbaustein zur Anlage von Bankdaten anlegen (SHDB)

neue Aufzeichnung

60

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Aufzeichnung starten

Ausfllen 7654XXNN XX = Gruppe NN = laufende Nummer


Enter

sichern

61

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

sichern

im neuen Modus Funktionsgruppe ber SE80 anlegen

Funktionsgruppe ZBLKA_99

sichern

dann im 1.Modus

62

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Funktionsbaustein

Enter

ber SE80 Baustein testen

Vorlauf definieren (Zange)

63

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Datensatz sichern

bernehmen + ausfhren

64

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Secatt Testdatenerstellen
Transaktion SECATT aufrufen

- Script anlegen

- Muster einfgen

65

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

einmal Enter + Parameter anlegen

nur Obligatorisch Parameter und meldende Inhalte

Vorbelegung Unique Neu + sichern

66

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Sichern + Testscript ausfhren

Startmodus whlen wie oben und F8

Korrekter Ablauf

67

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Testkonfiguration anlegen

Konfiguration whlen

68

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Varianten whlen

Varianten Herunterladen

69

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Save (ohne Referenzierung)

Anpassung

Hochladen + sichern

70

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

====== Report anlegen ====================


report zecatt.
data: tdc_ref type ref to cl_apl_ecatt_tdc_api,
ls_tdc_var_par_content
type etpar_ref.
data e_value_tab type ettdc_refs_tabtype.
data lv_variante type string.
data lv_varname type string.
data lv_varvalue type string.
field-symbols:
<ls_tdc_var_par_content_data> type any,
<lv_key>
type /bobf/conf_key.
field-symbols: <e_value_tab> type line of ettdc_refs_tabtype.
field-symbols: <etpar_ref_tabtype> type etpar_ref_tabtype.
field-symbols: <etpar_ref_tabtype_line> type line of etpar_ref_tabtype.
call method cl_apl_ecatt_tdc_api=>get_instance
exporting
i_testdatacontainer = 'ZBNKA'
receiving
e_tdc_ref
= tdc_ref.
*try.
e_value_tab = tdc_ref->get_tdc_content( ).
loop at e_value_tab assigning <e_value_tab>.
lv_variante = <e_value_tab>-varname.
case lv_variante.
when '0001'.
assign <e_value_tab>-paramtab to <etpar_ref_tabtype>.
loop at <etpar_ref_tabtype> assigning <etpar_ref_tabtype_line>.
lv_varname = <etpar_ref_tabtype_line>-parname.
case lv_varname.
when 'CARRID'.
assign <etpar_ref_tabtype_line>-value_ref->* to
<ls_tdc_var_par_content_data>.
lv_varvalue = <ls_tdc_var_par_content_data>.
when others.
endcase.
endloop.
when others.
endcase.
endloop.
* catch cx_ecatt_tdc_access .
*endtry.
tdc_ref->get_tdc_attributes( ).

*&---------------------------------------------------------------------*
*& Report ZUEBUNG_6
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

71

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


report zuebung_6.
data: tdc_ref type ref to cl_apl_ecatt_tdc_api,
ls_tdc_var_par_content
type etpar_ref.
data e_value_tab type ettdc_refs_tabtype.
data lv_variante type string.
data lv_varname type string.
data lv_i_banka_003 type bdcdata-fval.
data lv_i_banks_001 type bdcdata-fval.
data lv_i_bankl_002 type bdcdata-fval.
data lt_messtab type table of bdcmsgcoll.
data ls_messtab type bdcmsgcoll.
field-symbols:
<ls_tdc_var_par_content_data> type any,
<lv_key>
type /bobf/conf_key.
field-symbols: <e_value_tab> type line of ettdc_refs_tabtype.
field-symbols: <etpar_ref_tabtype> type etpar_ref_tabtype.
field-symbols: <etpar_ref_tabtype_line> type line of etpar_ref_tabtype.
call method cl_apl_ecatt_tdc_api=>get_instance
exporting
i_testdatacontainer = 'ZFI01_99'
receiving
e_tdc_ref
= tdc_ref.
*try.
e_value_tab = tdc_ref->get_tdc_content( ).
loop at e_value_tab assigning <e_value_tab>.
lv_variante = <e_value_tab>-varname.
case lv_variante.
when 'ECATTDEFAULT1'.
assign <e_value_tab>-paramtab to <etpar_ref_tabtype>.
loop at <etpar_ref_tabtype> assigning <etpar_ref_tabtype_line>.
lv_varname = <etpar_ref_tabtype_line>-parname.
case lv_varname.
when 'I_BANKS_001'.
assign <etpar_ref_tabtype_line>-value_ref->* to <ls_tdc_var_par_content_data>.
lv_i_banks_001 = <ls_tdc_var_par_content_data>.
when 'I_BANKL_002'.
assign <etpar_ref_tabtype_line>-value_ref->* to <ls_tdc_var_par_content_data>.
lv_i_bankl_002 = <ls_tdc_var_par_content_data>.
when 'I_BANKA_003'.
assign <etpar_ref_tabtype_line>-value_ref->* to <ls_tdc_var_par_content_data>.
lv_i_banka_003 = <ls_tdc_var_par_content_data>.
when others.
endcase.
endloop.
when others.
endcase.
endloop.
*DATA CTU
TYPE APQI-PUTACTIVE.
*DATA MODE TYPE APQI-PUTACTIVE.

72

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


*DATA UPDATE TYPE APQI-PUTACTIVE.
*DATA GROUP TYPE APQI-GROUPID.
*DATA USER
TYPE APQI-USERID.
*DATA KEEP TYPE APQI-QERASE.
*DATA HOLDDATE TYPE APQI-STARTDATE.
*DATA NODATA TYPE APQI-PUTACTIVE.
*DATA BANKS_001 TYPE BDCDATA-FVAL.
*DATA BANKL_002 TYPE BDCDATA-FVAL.
*DATA BANKA_003 TYPE BDCDATA-FVAL.
*DATA SUBRC TYPE SYST-SUBRC.
*DATA MESSTAB TYPE STANDARD TABLE OF BDCMSGCOLL.
call function 'ZFUBAU_BLKA_99'
exporting
* CTU
= 'X'
* MODE
= 'N'
* UPDATE = 'L'
* GROUP = GROUP
* USER
= USER
* KEEP = KEEP
* HOLDDATE = HOLDDATE
* NODATA = '/'
banks_001 = lv_i_banks_001
bankl_002 = lv_i_bankl_002
banka_003 = lv_i_banka_003
* IMPORTING
* SUBRC = SUBRC
tables
messtab = lt_messtab.
*----------------------------------------------------------------------*
*
CLASS mytest DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class fubautest definition "#AU Risk_Level Harmless
for testing. "#AU Duration Short
private section.
data: lv_abap_bool type abap_bool.
methods fubautest_m for testing.
methods setup for testing.
endclass.
"mytest DEFINITION
*----------------------------------------------------------------------*
*
CLASS mytest IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class fubautest implementation.
method setup.
call method cl_apl_ecatt_tdc_api=>get_instance
exporting
i_testdatacontainer = 'ZFI01_99'

73

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


receiving
e_tdc_ref

74

= tdc_ref.

*try.
e_value_tab = tdc_ref->get_tdc_content( ).
loop at e_value_tab assigning <e_value_tab>.
lv_variante = <e_value_tab>-varname.
case lv_variante.
when '1'.
assign <e_value_tab>-paramtab to <etpar_ref_tabtype>.
loop at <etpar_ref_tabtype> assigning <etpar_ref_tabtype_line>.
lv_varname = <etpar_ref_tabtype_line>-parname.
case lv_varname.
when 'I_BANKS_001'.
assign <etpar_ref_tabtype_line>-value_ref->* to <ls_tdc_var_par_content_data>.
lv_i_banks_001 = <ls_tdc_var_par_content_data>.
when 'I_BANKL_002'.
assign <etpar_ref_tabtype_line>-value_ref->* to <ls_tdc_var_par_content_data>.
lv_i_bankl_002 = <ls_tdc_var_par_content_data>.
when 'I_BANKA_003'.
assign <etpar_ref_tabtype_line>-value_ref->* to <ls_tdc_var_par_content_data>.
lv_i_banka_003 = <ls_tdc_var_par_content_data>.
when others.
endcase.
endloop.
when others.
endcase.
endloop.
endmethod.
method fubautest_m.
call function 'ZFUBAU_BLKA_99'
exporting
*
CTU
= 'X'
*
MODE
= 'N'
*
UPDATE = 'L'
*
GROUP = GROUP
*
USER
= USER
*
KEEP = KEEP
*
HOLDDATE = HOLDDATE
*
NODATA = '/'
banks_001 = lv_i_banks_001
bankl_002 = lv_i_bankl_002
banka_003 = lv_i_banka_003
* IMPORTING
*
SUBRC = SUBRC
tables
messtab = lt_messtab.
read table lt_messtab into ls_messtab index 1.
cl_aunit_assert=>assert_equals( act = ls_messtab-msgnr
exp = '208'
* TEXT-001 'Wert wurde falsch berechnet'

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

75

msg = 'Satz schon da'


*
* level definiert die Prioritt des Fehlers und kann einen der Werte if_
* aunit_constants=>tolerable, critical oder fatal annehmen. Der Standardwert
* ist critical. Beim Auftreten eines Fehlers spiegelt sich die Prioritt
* in der Ergebnisanzeige wider. Das kann insbesondere bei Massentests
* ntzlich sein, um die Bedeutung eines Fehlers zu beurteilen und fr die Notwendigkeit,
* Folgeaktionen ableiten zu knnen.
*
*
* "! Severity: TOLERABLE / lowest
* constants tolerable type aunit_Level value 0.
* "! Severity: CRITICAL / medium
* constants critical type aunit_Level value 1.
* "! Severity: FATAL / highest
* constants fatal type aunit_Level value 2.
*
===================================================================
===================
level = '2'
quit = '2' ).
endmethod.
"mytest
endclass.
* catch cx_ecatt_tdc_access .
*endtry.
.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Mocking Konzept 1 (Methode als Mock)


Tabelle anlegen
Transaktion SE11

MANDT
MANDT
CLNT 3
0
Mandant
ID
PERSNO
NUMC
8
0
Personalnummer
NAMENAMECHAR 35
0
Nachname eines Mitarbeiters
AGE INT2 INT2 5
0
2 Byte Integer (Signed)
SALARY
CURR 13
2
DEPARTMENT
/BEV1/RPSTORT CHAR 30
0
Standort
WAEHR
WAEHRUNG CUKY 5
0
Whrungskrzel
SALARY
CURR ZEMPLOYEE_DB_TAB
WAEHR

76

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Eintrge pflegen

Sichern
Basisklasse 1 anlegen (zu mocken)
Se80 aufrufen und Programm ZP_EMPLOYEE_DAO anlegen
class lcl_employee_dao definition .
public section.
types:
begin of zemployee_s.
types id type chars.
types name type char128.
types age type i.
types salary type dec10_2.

77

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

78

types department type char20.


types end of zemployee_s .
types:
zemployee_tt type hashed table of zemployee_db_tab with unique key id .
class-methods get_instance
returning
value(ro_employee_dao) type ref to lcl_employee_dao .
class-methods set_instance
importing
!io_employee_dao type ref to lcl_employee_dao .
methods get_employee_by_id
importing
!i_employee_id type zemployee_s-id
returning
value(rs_employee) type zemployee_db_tab .
methods get_employees_from_department
importing
!i_department type zemployee_db_tab-department
returning
value(rt_employees) type zemployee_tt .
methods get_average_age
returning
value(r_average_age) type zemployee_s-age .
protected section.
private section.
class-data mo_employee_dao type ref to lcl_employee_dao .
endclass.

class lcl_employee_dao implementation.


* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_DAO->GET_AVERAGE_AGE
* +-------------------------------------------------------------------------------------------------+
* | [<-()] R_AVERAGE_AGE
TYPE
ZEMPLOYEE_S-AGE
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_average_age.
select avg( age ) from zemployee_db_tab into r_average_age.
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_DAO>GET_EMPLOYEES_FROM_DEPARTMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_DEPARTMENT
TYPE
ZEMPLOYEE_DB_TAB-DEPARTMENT
* | [<-()] RT_EMPLOYEES
TYPE
ZEMPLOYEE_TT
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_employees_from_department.
select * from zemployee_db_tab into corresponding fields of table

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

79

rt_employees where department = i_department.


endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_DAO->GET_EMPLOYEE_BY_ID
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_EMPLOYEE_ID
TYPE
ZEMPLOYEE_S-ID
* | [<-()] RS_EMPLOYEE
TYPE
ZEMPLOYEE_DB_TAB
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_employee_by_id.
select single * from zemployee_db_tab into corresponding fields of
rs_employee where id = i_employee_id.
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Static Public Method ZCL_EMPLOYEE_DAO=>GET_INSTANCE
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RO_EMPLOYEE_DAO
TYPE REF TO ZCL_EMPLOYEE_DAO
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_instance.
if ( mo_employee_dao is initial ).
create object mo_employee_dao.
endif.
ro_employee_dao = mo_employee_dao.
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Static Public Method ZCL_EMPLOYEE_DAO=>SET_INSTANCE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_EMPLOYEE_DAO
TYPE REF TO ZCL_EMPLOYEE_DAO
* +-------------------------------------------------------------------------------------</SIGNATURE>
method set_instance.
mo_employee_dao = io_employee_dao.
endmethod.
endclass.

Setzen Sie die Klasse global um / SE24 aufrufen

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Importieren + sichern

Aktivieren

80

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

Klasse kontrollieren
Testprogramm abwickeln
start-of-selection.
*
*.Reference: 1 .........................................
data: lo_lcl_employee_dao type ref to zcl_employee_dao.
data: lv_result type char30.
data: lo_rs_employee type zemployee_db_tab.
data: lv_id type chars.
*
write: / 'zcl_employee_dao: '.
* calling the method which gets us the instance
* Statement CREATE OBJECT LO_APPLICATION
* would not work as the class LCL_APPLICATION instantiation
* is set to PRIVATE
lo_lcl_employee_dao = zcl_employee_dao=>get_instance( ).
* Set the variable and get it back.
lv_id-charact = '1'.
lo_rs_employee = lo_lcl_employee_dao->get_employee_by_id( lv_id ).
write: / lo_rs_employee-name.
clear lv_result.

Basisklasse 2 anlegen (zu mocken)


Se80 aufrufen und Programm ZP_EMPLOYEE_STATISTICS anlegen
class lcl_employee_statistics definition.
public section.
methods constructor .
methods get_by_id
importing
!i_employee_id type chars
returning
value(rs_employee) type zemployee_db_tab .

81

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

82

methods get_average_age
returning
value(r_average_age) type zemployee_db_tab-age .
methods get_avg_salary_in_department
importing
!i_department type zemployee_db_tab-department
returning
value(r_average_salary) type zemployee_db_tab-salary .
protected section.
private section.
data mo_employee_dao type ref to zcl_employee_dao .
endclass.

class lcl_employee_statistics implementation.


* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_STATISTICS->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* +-------------------------------------------------------------------------------------</SIGNATURE>
method constructor.
mo_employee_dao = zcl_employee_dao=>get_instance( ).
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_STATISTICS->GET_AVERAGE_AGE
* +-------------------------------------------------------------------------------------------------+
* | [<-()] R_AVERAGE_AGE
TYPE
ZEMPLOYEE_DB_TAB-AGE
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_average_age.
r_average_age = mo_employee_dao->get_average_age( ).
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_STATISTICS>GET_AVG_SALARY_IN_DEPARTMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_DEPARTMENT
TYPE
ZEMPLOYEE_DB_TAB-DEPARTMENT
* | [<-()] R_AVERAGE_SALARY
TYPE
ZEMPLOYEE_DB_TAB-SALARY
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_avg_salary_in_department.
data
data
data
data

lt_employees type zemployee_db_tab_tt.


l_employee type zemployee_db_tab.
l_salary_sum type zemployee_db_tab-salary value 0.
l_enployees_count type i value 0.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

83

lt_employees = mo_employee_dao->get_employees_from_department(
i_department ).
loop at lt_employees into l_employee.
add 1 to l_enployees_count.
add l_employee-salary to l_salary_sum.
endloop.
r_average_salary = l_salary_sum / l_enployees_count.
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_EMPLOYEE_STATISTICS->GET_BY_ID
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_EMPLOYEE_ID
TYPE
CHARS
* | [<-()] RS_EMPLOYEE
TYPE
ZEMPLOYEE_DB_TAB
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_by_id.
rs_employee = mo_employee_dao->get_employee_by_id( i_employee_id ).
endmethod.
endclass.
Setzen Sie die Klasse global um / SE24 aufrufen

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

84

Klasse kontrollieren

Mocken der 1.Klasse

*----------------------------------------------------------------------*
*
CLASS lcl_employee_dao_mock DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lcl_employee_dao_mock definition inheriting from zcl_employee_dao.
public section.
methods constructor.
class-methods set_instance_mock
importing
!io_employee_dao_mock type ref to lcl_employee_dao_mock .
class-methods get_instance_mock
returning
value(ro_employee_dao_mock) type ref to lcl_employee_dao_mock .
methods get_employee_by_id final redefinition.
methods get_employees_from_department final redefinition.
methods get_average_age final redefinition.
private section.
class-data mo_employee_dao_mock type ref to lcl_employee_dao_mock .
data mt_test_employee_memory_table type zemployee_db_tab_tt.
endclass. "lcl_employee_dao_mock DEFINITION
*----------------------------------------------------------------------*
*
CLASS lcl_employee_dao_mock IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lcl_employee_dao_mock implementation.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Static Public Method ZCL_EMPLOYEE_DAO=>GET_INSTANCE

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

85

* +-------------------------------------------------------------------------------------------------+
* | [<-()] RO_EMPLOYEE_DAO
TYPE REF TO ZCL_EMPLOYEE_DAO
* +-------------------------------------------------------------------------------------</SIGNATURE>
method get_instance_mock.
if ( mo_employee_dao_mock is initial ).
create object mo_employee_dao_mock.
endif.
ro_employee_dao_mock = mo_employee_dao_mock.
endmethod.
* <SIGNATURE>--------------------------------------------------------------------------------------+
* | Static Public Method ZCL_EMPLOYEE_DAO=>SET_INSTANCE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_EMPLOYEE_DAO
TYPE REF TO ZCL_EMPLOYEE_DAO
* +-------------------------------------------------------------------------------------</SIGNATURE>
method set_instance_mock.
mo_employee_dao_mock = io_employee_dao_mock.
endmethod.
method constructor.
super->constructor( ).
data ls_employee type zemployee_db_tab.
" Define table that simulates real zemployee_db_table values, just some
representative rows
ls_employee-id = '00001'.
ls_employee-name = 'Adam Krawczyk'.
ls_employee-age = 29.
ls_employee-department = 'ERP_DEV'.
ls_employee-salary = 10000.
insert ls_employee into table mt_test_employee_memory_table.
ls_employee-id = '00002'.
ls_employee-name = 'Julia Rose'.
ls_employee-age = 35.
ls_employee-department = 'ERP_DEV'.
ls_employee-salary = 15000.
insert ls_employee into table mt_test_employee_memory_table.
ls_employee-id = '00003'.
ls_employee-name = 'Johny Feet'.
ls_employee-age = 44.
ls_employee-department = 'HR'.
ls_employee-salary = 20000.
insert ls_employee into table mt_test_employee_memory_table.
endmethod. "constructor el
method get_employees_from_department. " Implementation of test data with
internal table which simulates database with rows
data ls_employee type zemployee_db_tab.
loop at mt_test_employee_memory_table into ls_employee where department
= i_department.
insert ls_employee into table rt_employees.
endloop.
endmethod. "get_employees_from_department
method get_employee_by_id.
data ls_employee type zemployee_db_tab.
" One way of implementing predefined test data from DAC. - directly in

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

86

method " Each test method that wants to use this for own purpose, may easily
extend new condition for own scenario
if ( i_employee_id = '00001' ).
rs_employee-id = '000001'.
rs_employee-name = 'Adam Krawczyk'.
rs_employee-age = 29.
rs_employee-department = 'ERP_DEV'.
rs_employee-salary = 10000.
elseif ( i_employee_id = '00002' ).
rs_employee-id = '000002'.
rs_employee-name = 'Julia Elbow'.
rs_employee-age = 35.
rs_employee-department = 'ERP_DEV'.
rs_employee-salary = 15000.
endif.
endmethod.
"get_employee_by_id
method get_average_age.
"get_employee_by_id
" the simplest way of test result preparation - just predefine value, assuming
we know expected results
r_average_age = ( 29 + 35 + 44 ) / 3.
endmethod. "get_average_age
endclass. "lcl_employee_dao_mock IMPLEMENTATION

start-of-selection.
*
*.Reference: 1 .........................................
data: lo_lcl_employee_dao type ref to zcl_employee_dao.
data: lv_result type char30.
data: lo_rs_employee type zemployee_db_tab.
data: lv_id type chars.
*
write: / 'zcl_employee_dao: '.
* calling the method which gets us the instance
* Statement CREATE OBJECT LO_APPLICATION
* would not work as the class LCL_APPLICATION instantiation
* is set to PRIVATE
lo_lcl_employee_dao = zcl_employee_dao=>get_instance( ).
* Set the variable and get it back.
lv_id-charact = '1'.
lo_rs_employee = lo_lcl_employee_dao->get_employee_by_id( lv_id ).
write: / lo_rs_employee-name.
clear lv_result.
*&---------------------------------------------------------------------*
*& Report ZTEST_CL_MOCKA_CLASS_GEN
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
* mockA is a mocking framework for ABAP that makes creating mock implementa
tions easier than ever before. It is Open Source.
*
lead developers:
*
Uwe Kunath - kunath.uwe[at]googlemail.com
*
*
Copyright Uwe Kunath
*
mockA can be found at https://github.com/uweku/mockA/

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


*
*
*
*
*
*
*
*
*
*
.
*
*

87

Licensed under the Apache License, Version 2.0 (the "License");


you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
See the License for the specific language governing permissions and
limitations under the License.

REPORT

ztest_cl_mocka_class_gen.

TYPE-POOLS: abap.
*----------------------------------------------------------------------*
*
CLASS lcl_transparent_mocker DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_transparent_mocker DEFINITION INHERITING FROM zcl_mocka_mocker.
PUBLIC SECTION.
CLASS-METHODS mock_by_subclass
IMPORTING
!iv_interface TYPE abap_abstypename
RETURNING
value(ro_mocker) TYPE REF TO zif_mocka_mocker.
METHODS get_current_generated_class
RETURNING
value(rv_name) TYPE abap_abstypename.
ENDCLASS.
"lcl_transparent_mocker DEFINITION
*----------------------------------------------------------------------*
*
CLASS lcl_transparent_mocker IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_transparent_mocker IMPLEMENTATION.
METHOD mock_by_subclass.
*
returns a new mock object instance that provides the root object for re
cording & generating the mock object behaviour
*
for this unit test, an instance of type lcl_transparent_mocker will be
created which gives us access to the protected attribute "mv_generated_clas
s"
DATA lo_mocker TYPE REF TO lcl_transparent_mocker.
DATA lo_typedescr TYPE REF TO cl_abap_typedescr.
DATA lo_cx_root TYPE REF TO cx_root.
DATA lv_message TYPE string.
FIELD-SYMBOLS <ls_method> TYPE abap_methdescr.
DATA lv_interface LIKE iv_interface.
check_unit_test_execution( ).
lv_interface = iv_interface.
TRANSLATE lv_interface TO UPPER CASE.
CREATE OBJECT lo_mocker.
CALL METHOD cl_abap_intfdescr=>describe_by_name
EXPORTING

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

88

p_name
= lv_interface
RECEIVING
p_descr_ref
= lo_typedescr
EXCEPTIONS
type_not_found = 1
OTHERS
= 2.
IF sy-subrc NE 0.
RAISE EXCEPTION TYPE zcx_mocka
EXPORTING
textid
= zcx_mocka=>no_such_interface
interface = iv_interface.
ENDIF.
IF lo_typedescr->type_kind = cl_abap_typedescr=>typekind_class.
lo_mocker->mv_is_interface_mock = abap_false.
ELSE.
lo_mocker->mv_is_interface_mock = abap_true.
ENDIF.
TRY.
ro_mocker = lo_mocker.
lo_mocker->mo_objectdescr ?= lo_typedescr.
lo_mocker->mv_interface = lv_interface.
LOOP AT lo_mocker->mo_objectdescr->methods ASSIGNING <ls_method>.
lo_mocker->resolve_method( <ls_method> ).
ENDLOOP.
DATA ls_generated_class TYPE ty_s_generated_class.
READ TABLE mt_generated_classes INTO ls_generated_class WITH KEY na
me = lv_interface.
IF sy-subrc = 0.
lo_mocker->mv_generated_class = ls_generated_classtechnical_name.
ENDIF.
CATCH cx_root INTO lo_cx_root.
lv_message = lo_cx_root->get_text( ).
RAISE EXCEPTION TYPE zcx_mocka
EXPORTING
textid
= zcx_mocka=>zcx_mocka
generic_text = lv_message.
ENDTRY.
ENDMETHOD.
"mock_by_subclass
METHOD get_current_generated_class.
rv_name = mv_generated_class.
ENDMETHOD.
"get_current_generated_class
ENDCLASS.
"lcl_transparent_mocker IMPLEMENTATION
*----------------------------------------------------------------------*
*
CLASS lcl_test_mocker DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_mocker DEFINITION FOR TESTING.
"#AU Risk_Level Harmless
"#AU Duration Short
PROTECTED SECTION.
PRIVATE SECTION.
METHODS setup.
METHODS teardown.
METHODS do_not_reuse_class_impl FOR TESTING.
METHODS reuse_interface_impl FOR TESTING.
METHODS mock_protected_method FOR TESTING.
ENDCLASS.
"lcl_test_mocker DEFINITION

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

89

*----------------------------------------------------------------------*
*
CLASS lcl_test_mocker IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_mocker IMPLEMENTATION.
METHOD setup.
ENDMETHOD.
"setup
METHOD teardown.
ENDMETHOD.
"teardown
METHOD reuse_interface_impl.
DATA lv_has_exception_been_raised TYPE abap_bool VALUE abap_false.
DATA lo_mocker TYPE REF TO zif_mocka_mocker.
DATA lo_transparent_mocker TYPE REF TO lcl_transparent_mocker.
DATA lv_generated_class1 TYPE abap_abstypename.
DATA lv_generated_class2 TYPE abap_abstypename.
lo_mocker = lcl_transparent_mocker=>mock_by_subclass( iv_interface = 'Z
IF_MOCKA_IS_IN_TIME_INFO' ).
lo_transparent_mocker ?= lo_mocker.
lo_mocker->generate_mockup( ).
lv_generated_class1 = lo_transparent_mocker>get_current_generated_class( ).
lo_mocker = lcl_transparent_mocker=>mock_by_subclass( iv_interface = 'Z
IF_MOCKA_IS_IN_TIME_INFO' ).
lo_transparent_mocker ?= lo_mocker.
lo_mocker->generate_mockup( ).
lv_generated_class2 = lo_transparent_mocker>get_current_generated_class( ).
cl_aunit_assert=>assert_equals(
EXPORTING
exp
= lv_generated_class1
act
= lv_generated_class2
).
ENDMETHOD.
"reuse_interface_implementations
METHOD do_not_reuse_class_impl.
DATA lv_has_exception_been_raised TYPE abap_bool VALUE abap_false.
DATA lo_mocker TYPE REF TO zif_mocka_mocker.
DATA lo_transparent_mocker TYPE REF TO lcl_transparent_mocker.
DATA lv_generated_class1 TYPE abap_abstypename.
DATA lv_generated_class2 TYPE abap_abstypename.
lo_mocker = lcl_transparent_mocker=>mock_by_subclass( iv_interface = 'Z
CL_MOCKA_MOCKER' ).
lo_transparent_mocker ?= lo_mocker.
lo_mocker->generate_mockup( ).
lv_generated_class1 = lo_transparent_mocker>get_current_generated_class( ).
lo_mocker = lcl_transparent_mocker=>mock_by_subclass( iv_interface = 'Z
CL_MOCKA_MOCKER' ).
lo_transparent_mocker ?= lo_mocker.
lo_mocker->generate_mockup( ).
lv_generated_class2 = lo_transparent_mocker>get_current_generated_class( ).
cl_aunit_assert=>assert_differs(
EXPORTING
exp
= lv_generated_class1

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


act
).
ENDMETHOD.

90

= lv_generated_class2
"do_not_reuse_class_impl

METHOD mock_protected_method.
DATA lo_mocker TYPE REF TO zif_mocka_mocker.
DATA lo_mocker_method TYPE REF TO zif_mocka_mocker_method.
lo_mocker = zcl_mocka_mocker=>zif_mocka_mocker~mock( 'ZCL_MOCKA_MOCKER'
).

on

lo_mocker_method = lo_mocker->method( 'CHECK_UNIT_TEST_EXECUTION' ).


lo_mocker_method->returns( abap_false ).
lo_mocker ?= lo_mocker->generate_mockup( )."should not cause an excepti

cl_abap_unit_assert=>assert_not_initial( lo_mocker ).
ENDMETHOD.
"mock_protected_method
ENDCLASS.
"lcl_test_mocker IMPLEMENTATION
*&---------------------------------------------------------------------*
*& Report ZTEST_CL_MOCKA_FLIGHT_OBSERVER
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
* mockA is a mocking framework for ABAP that makes creating mock implementa
tions easier than ever before. It is Open Source.
*
lead developers:
*
Uwe Kunath - kunath.uwe[at]googlemail.com
*
*
Copyright Uwe Kunath
*
mockA can be found at https://github.com/uweku/mockA/
*
*
Licensed under the Apache License, Version 2.0 (the "License");
*
you may not use this file except in compliance with the License.
*
You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
*
Unless required by applicable law or agreed to in writing, software
*
distributed under the License is distributed on an "AS IS" BASIS,
*
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
.
*
See the License for the specific language governing permissions and
*
limitations under the License.
REPORT ztest_cl_mocka_flight_observer.
*==========================================================================
==============================
*a manually implemented mock class might look like this. This demo shows ho
w you can save this effort...
**----------------------------------------------------------------------*
**
CLASS lcl_flight_info DEFINITION
**----------------------------------------------------------------------*
**
**----------------------------------------------------------------------*
*CLASS lcl_flight_info DEFINITION.
* PUBLIC SECTION.
*
INTERFACES ZIF_MOCKA_IS_IN_TIME_INFO.
*ENDCLASS.
"lcl_flight_info DEFINITION
**----------------------------------------------------------------------*

ABAP Unit Workshop fr das BLKA SAP Netweaver 740

91

**
CLASS lcl_flight_info IMPLEMENTATION
**----------------------------------------------------------------------*
**
**----------------------------------------------------------------------*
*CLASS lcl_flight_info IMPLEMENTATION.
* METHOD ZIF_MOCKA_IS_IN_TIME_INFO~get_delay.
*
IF iv_carrid = 'LH' AND iv_connid = 402 AND iv_fldate = '20121109'.
*
rv_delay = 100.
*
ENDIF.
*
IF iv_carrid = 'LH' AND iv_connid = 402 AND iv_fldate = '2012110'.
*
rv_delay = 5.
*
ENDIF.
* ENDMETHOD.
"ZIF_MOCKA_IS_IN_TIME_INFO~get_delay
*ENDCLASS.
"lcl_flight_info IMPLEMENTATION
*
*METHOD setup.
** this call creates the flight information mockup
* CREATE OBJECT mo_is_in_time_access TYPE lcl_flight_info.
** create an empty alert backend (we just need to track the number of metho
d calls)
* CREATE OBJECT mo_alert_processor_mocker TYPE lcl_alert_process.
** create the flight observer which is subject to this test
* CREATE OBJECT mo_system_under_test
*
EXPORTING
*
io_alert_processor = mo_alert_processor
*
io_in_time_access = mo_is_in_time_access.
*ENDMETHOD. "setup
*==========================================================================
==============================
*----------------------------------------------------------------------*
*
CLASS lcl_test_observer DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_observer DEFINITION FOR TESTING.
"#AU Risk_Level Harmless
"#AU Duration Short
PROTECTED SECTION.
DATA
DATA
DATA
DATA

mo_is_in_time_access TYPE REF TO zif_mocka_is_in_time_info .


mo_is_in_time_mocker TYPE REF TO zif_mocka_mocker.
mo_alert_processor TYPE REF TO zif_mocka_flight_alert_process .
mo_alert_processor_mocker TYPE REF TO zif_mocka_mocker.

DATA mo_system_under_test TYPE REF TO zcl_mocka_flight_observer.


PRIVATE SECTION.
METHODS setup.
METHODS teardown.
METHODS test_no_alert FOR TESTING.
METHODS test_with_alert FOR TESTING.
ENDCLASS.
"lcl_test_observer DEFINITION
*----------------------------------------------------------------------*
*
CLASS lcl_test_observer IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_observer IMPLEMENTATION.
METHOD setup.

ABAP Unit Workshop fr das BLKA SAP Netweaver 740


**
*
*

92

Member attributes:
DATA mo_is_in_time_access TYPE REF TO ZIF_MOCKA_IS_IN_TIME_INFO .
DATA mo_is_in_time_mocker TYPE REF TO ZIF_MOCKA_MOCKER.

DATA lo_mocker_method TYPE REF TO zif_mocka_mocker_method.


create the flight information backend
mo_is_in_time_mocker = zcl_mocka_mocker=>zif_mocka_mocker~mock( iv_inte
rface = 'ZIF_MOCKA_IS_IN_TIME_INFO' ).
lo_mocker_method = mo_is_in_time_mocker->method( 'GET_DELAY' ).
lo_mocker_method->with( i_p1 = 'LH' i_p2 = 402 i_p3 = '20121109' ).
lo_mocker_method->returns( 100 ).
lo_mocker_method->with( i_p1 = 'LH' i_p2 = 402 i_p3 = '20121110' ).
lo_mocker_method->returns( 5 ).
*
this call creates the flight information mockup
mo_is_in_time_access ?= mo_is_in_time_mocker->generate_mockup( ).
*

**
*
*

Member attributes
DATA mo_alert_processor TYPE REF TO ZIF_MOCKA_FLIGHT_ALERT_PROCESS .
DATA mo_alert_processor_mocker TYPE REF TO ZIF_MOCKA_MOCKER.

*
create an empty alert backend (we just need to track the number of meth
od calls)
mo_alert_processor_mocker = zcl_mocka_mocker=>zif_mocka_mocker~mock( iv
_interface = 'ZIF_MOCKA_FLIGHT_ALERT_PROCESS' ).
*
this call creates the alert processor mockup
mo_alert_processor ?= mo_alert_processor_mocker->generate_mockup( ).
*

create the flight observer which is subject to this test


CREATE OBJECT mo_system_under_test
EXPORTING
io_alert_processor = mo_alert_processor
io_in_time_access = mo_is_in_time_access.
ENDMETHOD.
"setup
METHOD teardown.
ENDMETHOD.
"teardown
METHOD test_no_alert.
DATA lv_alert TYPE abap_bool.
mo_system_under_test->observe_flight( iv_carrid = 'LH' iv_connid = 402
iv_fldate = '20121110' ).
lv_alert = mo_alert_processor_mocker->has_method_been_called( 'ALERT_DE
LAY' ).
cl_aunit_assert=>assert_initial( lv_alert ).
ENDMETHOD.
"test_no_alert
METHOD test_with_alert.
DATA lv_alert TYPE abap_bool.
mo_system_under_test->observe_flight( iv_carrid = 'LH' iv_connid = 402
iv_fldate = '20121109' ).
lv_alert = mo_alert_processor_mocker->has_method_been_called( 'ALERT_DE
LAY' ).
cl_aunit_assert=>assert_not_initial( lv_alert ).
ENDMETHOD.
"test_with_alert
ENDCLASS.
"lcl_test_observer IMPLEMENTATIO