Personal Insights
Claiming ABAPUnit – Again. A walktrough – Part 1
This is maybe the 3rd time I try to start with using ABAPUnit.
And I’m always running against the same obstacles:
I don’t remember:
– How to create a test class
– how does FRIENDS work?!
– How do I fill a table with test data (something with VALUE ?! )
– etc.
My own blog https://blogs.sap.com/2018/07/25/my-experience-with-real-world-unit-testing-abap-unit/ was somehow helpful, but not in all aspects.
So this time, I’m working though it with a blog, and I walk trough it giving (my) code examples, cause that is what I’m lacking.
-> This is the blog, I wish I had had today! 🙂
OK, so I have a class that selects stuff, and the filters it (deleting un-needed stuff).
I want to make sure, those filters work.
I choose ABAPUnit to help me.
I also try to capture some in-between states of my code, because often, this is what I miss.
I somehow managed to write this:
(You can skip right down to a CLEANner version! )
CLASS ltc_test_stasam_data_filtering DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT
FRIENDS zclewm_stasam_interface.
PRIVATE SECTION.
METHODS: test1_filter_out_QDOCID FOR TESTING.
ENDCLASS.
CLASS ltc_test_stasam_data_filtering IMPLEMENTATION.
METHOD test1_filter_out_QDOCID.
"given
DATA(cut) = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
DATA: lt_stock_mon TYPE /scwm/tt_stock_mon .
"fill with samples
APPEND VALUE #( matnr = '0815'
qdocid = 'hsdfksdhfk' )
TO lt_stock_mon.
*Sample has just 1 line, an that has a QDOCID;
*Filter should delete it:
"when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = lt_stock_mon ).
"then Table should be empty:
cl_abap_unit_assert=>assert_initial( act = lt_stock_mon ).
ENDMETHOD.
ENDCLASS.
Here is the cleaner version (many empty lines removed)
CLASS ltc_test_stasam_data_filtering DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT.
PRIVATE SECTION.
METHODS: test1_filter_out_QDOCID FOR TESTING.
ENDCLASS.
CLASS ltc_test_stasam_data_filtering IMPLEMENTATION.
METHOD test1_filter_out_QDOCID.
"given
DATA(cut) = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
DATA: lt_stock_mon TYPE /scwm/tt_stock_mon .
"fill with samples
APPEND VALUE #( matnr = '0815'
qdocid = 'hsdfksdhfk' ) TO lt_stock_mon.
*Sample has just 1 line, an that has a QDOCID;
*Filter should delete it: "when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = lt_stock_mon ).
"then Table should be empty:
cl_abap_unit_assert=>assert_initial( act = lt_stock_mon ).
ENDMETHOD.
ENDCLASS.
So I have my first test, lets do the 2nd:
METHOD test2_nothing_to_filter_out.
"given
DATA(cut) = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
DATA: lt_stock_mon TYPE /scwm/tt_stock_mon .
"fill with samples
APPEND VALUE #( matnr = '0815'
qdocid = space ) TO lt_stock_mon.
data(lt_copy_to_compare) = lt_stock_mon.
*Filter should keep it - it should not change: "when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = lt_stock_mon ).
"then un-changed Table should be same as the copy we made before:
cl_abap_unit_assert=>assert_equals( act = lt_stock_mon
exp = lt_copy_to_compare ).
ENDMETHOD.
Next is, refactor a bit: (AdT helps a lot with that!)
1. make cut a member (=attribute) of the class.
2. move creation of cut to setup( )
3. Also make lt_stock_mon a member and rename it accordingly: mt_stock_mon
Here is the full class after this:
(Note: I plan not to refactor the first test, but keep it verbose as a refference. This might change in the future, when I am more fluent with unit test.
CLASS ltc_test_stasam_data_filtering DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT.
PRIVATE SECTION.
DATA: cut TYPE REF TO zclewm_stasam_interface,
mt_stock_mon TYPE /scwm/tt_stock_mon .
METHODS:
setup,
test1_filter_out_QDOCID FOR TESTING,
test2_nothing_to_filter_out FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltc_test_stasam_data_filtering IMPLEMENTATION.
METHOD setup. "given
cut = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
ENDMETHOD.
METHOD test1_filter_out_QDOCID.
"given
DATA(cut) = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
DATA: lt_stock_mon TYPE /scwm/tt_stock_mon .
"fill with samples
APPEND VALUE #( matnr = '0815'
qdocid = 'hsdfksdhfk' ) TO lt_stock_mon.
*Sample has just 1 line, an that has a QDOCID;
*Filter should delete it: "when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = lt_stock_mon )
"then Table should be empty:
cl_abap_unit_assert=>assert_initial( act = lt_stock_mon ).
ENDMETHOD.
METHOD test2_nothing_to_filter_out.
"given: cut is in setup( ) now
"fill with samples
APPEND VALUE #( matnr = '0815'
qdocid = space ) TO mt_stock_mon.
DATA(lt_copy_to_compare) = mt_stock_mon.
*Filter should keep it - it should not change: "when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = mt_stock_mon ).
"then un-changed Table should be same as the copy we made before:
cl_abap_unit_assert=>assert_equals( act = mt_stock_mon
exp = lt_copy_to_compare ).
ENDMETHOD.
ENDCLASS.
Next Up:
For now I am leaving it here.
Next test would probably be: have some lines with and some lines without QDOCID set.
After filtering, only those without should still be there.
A strategy might be to have value_lines defined in setup, like so:
METHOD setup. "given
cut = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
line_1_with_qdocid_filled = VALUE #( matnr = '0815' qdocid = '478326423648' ).
line_2_with_emtyp_qdocid = VALUE #( matnr = '0815' qdocid = space ).
ENDMETHOD.
With this, I can again make my 2nd test more compact. Here’s the full class again:
CLASS ltc_test_stasam_data_filtering DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT.
PRIVATE SECTION.
DATA: cut TYPE REF TO zclewm_stasam_interface,
mt_stock_mon TYPE /scwm/tt_stock_mon ,
line_1_with_qdocid_filled type /scwm/s_stock_mon,
line_2_with_emtyp_qdocid type /scwm/s_stock_mon.
METHODS:
setup,
test1_filter_out_QDOCID FOR TESTING,
test2_nothing_to_filter_out FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltc_test_stasam_data_filtering IMPLEMENTATION.
METHOD setup. "given
cut = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
line_1_with_qdocid_filled = VALUE #( matnr = '0815' qdocid = '478326423648' ).
line_2_with_emtyp_qdocid = VALUE #( matnr = '0815' qdocid = space ).
ENDMETHOD.
METHOD test1_filter_out_QDOCID.
"given
DATA(cut) = NEW zclewm_stasam_interface( iv_lgnum = '1020' ).
DATA: lt_stock_mon TYPE /scwm/tt_stock_mon .
"fill with samples
APPEND VALUE #( matnr = '0815'
qdocid = 'hsdfksdhfk' ) TO lt_stock_mon.
*Sample has just 1 line, an that has a QDOCID;
*Filter should delete it: "when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = lt_stock_mon ).
"then Table should be empty:
cl_abap_unit_assert=>assert_initial( act = lt_stock_mon ).
ENDMETHOD.
METHOD test2_nothing_to_filter_out.
append line_2_with_emtyp_qdocid to mt_stock_mon.
DATA(lt_copy_to_compare) = mt_stock_mon.
*Filter should keep it - it should not change: "when
cut->filter_data_rem_picked_stock( CHANGING ct_stock_mon = mt_stock_mon ).
"then un-changed Table should be same as the copy we made before:
cl_abap_unit_assert=>assert_equals( act = mt_stock_mon
exp = lt_copy_to_compare ).
ENDMETHOD.
ENDCLASS.
OK, this is it for today.
This will help me, get started with ABAPUnit again, next time I try.
Hopefully, it helps you also!
best
Joachim