Skip to Content
Personal Insights
Author's profile photo Joachim Rees

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

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.