Skip to content

How we do multicase tests

atsy edited this page Jul 6, 2016 · 3 revisions

This how-to describes our approach in doing multi-case unit tests with help of Abap mockup loader.

Let's suppose we have a method which is designed to identify quality of a product. We input a table of quality inspection parameters and expect some quality class assessment, in the example "A" or "B". Certain parameters are compulsory and must not be skipped during quality inspection. Thus, if they are missing the method raises an exception.

You want to arrange the test infrastructure so that it is easy to add new tests (in particular, no coding required). Here is how we do it.

Data

Let's say we prepared a unit test table with 3 cases, one of which has a missing parameter.

DOCNO   PARAM     VALUE
10      QUANTITY  99
10      MOISTURE  12,6
20      WEIGHT    14,89
20      QUANTITY  103
20      MOISTURE  11,9
30      WEIGHT    14,89
30      QUANTITY          <<< Missing quantity
30      MOISTURE  12,10  

Another table is the index of test cases. Each refers to a DOCNO, describes expected result and describes the case in a human-readable form. TYPE field describes if the case is positive or negative.

TESTID  TYPE   DOCNO  EXPECT  MSG
1       +      10     A       Case with quality A
2       +      11     B       Case with quality B
3       -      12             Case with a missing Param

Here is the code implementing the above

  1. Define the test case index structure (in the test class)
  public section.
    types:
        begin of ty_test_case,
          testid    type i,
          type      type char2,
          docno     type char10,
          expect    type char1,
          msg       type string,
        end of ty_test_case.

    data at_cases type table of ty_test_case.
    data o_ml     type ref to zcl_mockup_loader.
    data o        type ref to zcl_class_under_test.
  1. In setup() method acquire a mockup loader instance and load index (see How to load mockups for class_setup() tips)
  method setup.
    data lo_ex type ref to cx_static_check.

    create object o importing ... " << Object under test initialization

    try.
      o_ml = zcl_mockup_loader=>get_instance( ).

      o_ml->load_data(
        exporting i_obj       = 'TEST1/index' " << we placed here index file
        importing e_container = me->at_cases ).

    catch cx_static_check into lo_ex.  
      fail( lo_ex->get_text( ) ).  " << we inherit test classes from cl_aunit_assert 
    endtry.

  endmethod.
  1. And here is main test cycle
  method test_assess_quality.
    data l_case  type ty_test_case.
    data lo_ex   type cx_root.
    data lt_insp type zcl_class_under_test=>ty_inspections. " Whatever your type is
    data l_act   type zcl_class_under_test=>ty_quality.     " Whatever your type is

    loop at at_cases into l_case. " Loop through test cases
      clear lo_ex.

      try.
        o_ml->load_data( 
          exporting i_obj       = 'TEST1/inspections'         " Ispections data file
                    i_where     = 'DOCNO = ' && l_case-testid " Filter relevant lines
          importing e_container = lt_insp ).

        l_act = o->assess_quality( lt_insp ).

      catch cx_static_check into lo_ex. 
        fail( lo_ex->get_text( ) ). " Mockup load error handling just in case
      catch cx_root into lo_ex.
        " do nothing - this is the expected exception for negative tests
        " better use specific exeption classes of course
      endtry.

      if l_case-type = '+'. " Positive test
        " msg indicates the failed test id and it's description
        assert_initial( act = lo_ex msg = |[{ l_case-testid }] { l_case-msg }| ).
        assert_equals( act = l_act
                       exp = l_case-expect
                       msg = |[{ l_case-testid }] { l_case-msg }| ).
      else. " '-'           " Negative test
        assert_not_initial( act = lo_ex msg = |[{ l_case-testid }] { l_case-msg }| ).
        " Potentially more specific error check code should follow
      endif.

    endloop.
  endmethod.      
  1. That's all ! :)

Now you've got an easy extendable test infrustructure. New test cases of the same instance can be added without extra coding. See also How to simplify test data creation with Excel and EXCEL2TXT vbscript on how to make test preparation more convenient.