Skip to Content

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 Former Member applies here.

( open image in new tab for better view )

 

Thanks in advance for your comments an feedback

Best Timo

 

To report this post you need to login first.

3 Comments

You must be Logged on to comment or reply to a post.

  1. 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

    (0) 
  2. 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.

     

    (1) 
    1. Timo John 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

       

       

       

      (2) 

Leave a Reply