Skip to Content
Author's profile photo Timo John

A Sample on improvements on ABAP Unit Tests

During the Former Member course: Writing Testable Code for ABAP by Jürgen Heymann and Thomas Hammer  Alexander Geppart and me started to improve our unit test skills.

 

On request of Enno Wulff we want to share an example here:

SETUP method

1. we cut the data preparation of the SETUP method to place it into the test methods.

2. also database preparation was moved ( and placed in helperMethod – see later )

3. used a special logger to support unit testing

( open image in new tab for better view )

 

Test method

1. implemented database and local data preparation for this special test in the GIVEN part and used a helper method to do the INSERT and COMMIT etc.

2. extracted helper method to run the CUT and select results. This helper also assures that the Select is successful. ( we can reuse this method for some other tests ) For negative tests we need other coding in the test methods to assure sy-subrc = 4 as example.

3. introduced a #Macro to improve readability of assertions.

4. used the #Macro to shortly write the THEN part.
Yes, Methods could do nearly the same …. yes not debugable … but is will debug those calls. In my opinion great blog of Rüdiger Plantiko applies here.

( open image in new tab for better view )

 

Thanks in advance for your comments an feedback

Best Timo

 

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michelle Crapo
      Michelle Crapo

      Thank  you Timo for a nice explanation. I haven't had the time to yet really look at the open.sap course, and that is NOT normal for me.

      A big thank you to Enno Wulfffor suggesting the blog!

      Michelle

      Author's profile photo Enno Wulff
      Enno Wulff

      Thanks for sharing, Timo!

      This makes me aware that I have not only to think about test units but about a complex test unit application that will have to be designed and improved... (If it is so, will you have to write test units for it? :D)

      I like the Idea of the Given-When-Then-areas.

      In your case although you referred to the very useful blog of Rüdiger, I would try to avoid macros here. The simplification can also be reached by a method like:

      "WHEN
      run_cut_and_Expect_results( ).
      
      "THEN
      check_item_updated( so_item_10 ).
      check_item_updated( so_item_20 ).
      
      [...] 
      Method Check_Item_Updated.
      
        cl_abap_unit_assert=>assert_equals( 
           act = get_delivery_item( iv_so_item 
           exp = del_key_new
           msg = 'delivery number not renamed' ).
      
      EndMethod.
      
      Method get_delivery_item.
      
        SELECT delivery INTO @rv_delivery from zt5... 
         WHERE guid = @...guid 
           and so_item = iv_so_item.
        
        cl_abap_unit_assert=>assert_subrc( msg = 'expected delivery of guid/item not found' quit = ... ).
      
      Endmethod.

       

      Author's profile photo Timo John
      Timo John
      Blog Post Author

      Hi Enno,

      the parts in "given, when, then" is a learning from the mentioned @openSAP course.

       

      Of cause you could avoid these macros, sure. Question is what is key here?

      The content of the method / macro is so trivial, that there will be no need to debug. If we call this helper more often, in my opinion the advantages of readability come out stronger.

      "THEN ( classic )
      cl_abap_unit_assert=>assert_equals( act = get_delivery_item( so_item_10 ) 
                                          exp = del_key_new
                                          msg = 'delivery number not renamed' ).
      
      cl_abap_unit_assert=>assert_equals( act = get_delivery_item( so_item_20 ) 
                                          exp = del_key_new
                                          msg = 'delivery number not renamed' ).
      
      cl_abap_unit_assert=>assert_equals( act = get_delivery_item( so_item_30 ) 
                                          exp = del_key_new
                                          msg = 'delivery number not renamed' ).
      
      cl_abap_unit_assert=>assert_equals( act = get_delivery_item( so_item_40 ) 
                                          exp = del_key_new
                                          msg = 'delivery number not renamed' ).
      
      cl_abap_unit_assert=>assert_equals( act = get_delivery_item( so_item_50 ) 
                                          exp = del_key_new
                                          msg = 'delivery number not renamed' ).
      
      
      "THEN ( help method )
      check_item_updated( so_item_10 ).
      check_item_updated( so_item_20 ).
      check_item_updated( so_item_30 ).
      check_item_updated( so_item_40 ).
      check_item_updated( so_item_50 ).
      
      
      "THEN ( macro )
      check_item_updated: so_item_10, so_item_20, so_item_30, so_item_40, so_item_50
      

      In the classic way there is so much noisy code, that make it a big hurdle when you enter these classes at first.

      Regarding the #macros I fully support:

      • no real business logic inside
      • just do it if it is really worth to raise the readability over debugging
      • keep them short / and use comment.

      => but I like macros for getting rid of #codeNoise