Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Unit Test Help

Former Member
0 Likes
1,117

Hi,

I want to build unit test for function module,From SE80 I create test class .

i want to use the class cl_aunit_assert and for that i have question.

In the function i import tables and export table e.g. import_itab & export_itab.

How i check the data if the data o.k.?

Any example will help .

Regards

1 ACCEPTED SOLUTION
Read only

uwe_schieferstein
Active Contributor
0 Likes
1,003

Hello Michael

Below I show you the coding of an ABAP Unit test class that I use for testing class methods.


CLASS abap_unit_testclass DEFINITION DEFERRED.
CLASS zcl_edi_uk_svcs_out_wilkinson DEFINITION LOCAL FRIENDS abap_unit_testclass.
* ----------------------------------------------------------------------
CLASS abap_unit_testclass DEFINITION FOR TESTING  "#AU Duration Short
  "#AU Risk_Level Harmless
.
* ----------------------------------------------------------------------
* ===============
  PUBLIC SECTION.
* ===============

* ==================
  PROTECTED SECTION.
* ==================

* ================
  PRIVATE SECTION.
* ================
    DATA:
      ms_interval     TYPE nriv,
      md_number       TYPE edi4refint,
      md_next_number  TYPE edi4refint,
      md_flgn         TYPE edi4refint,
      m_ref TYPE REF TO zcl_edi_uk_svcs_out_wilkinson.      "#EC NOTEXT

    METHODS: setup.
    METHODS: teardown.
    METHODS: _constructor_ FOR TESTING.
    METHODS: generate_fgn FOR TESTING.
**    METHODS: map_icn FOR TESTING.
**    METHODS: postprocessing FOR TESTING.
ENDCLASS.       "Abap_Unit_Testclass
* ----------------------------------------------------------------------
CLASS abap_unit_testclass IMPLEMENTATION.
* ----------------------------------------------------------------------

* ----------------------------------------------------------------------
  METHOD setup.
* ----------------------------------------------------------------------

    CREATE OBJECT m_ref.

    " Check existence of number range
    CALL FUNCTION 'NUMBER_GET_INFO'
      EXPORTING
        nr_range_nr              = m_ref->md_nrnr
        object                   = m_ref->md_nrobj
*       SUBOBJECT                = ' '
*       TOYEAR                   = '0000'
      IMPORTING
        interval                 = ms_interval
      EXCEPTIONS
        interval_not_found       = 1
        object_not_found         = 2
        OTHERS                   = 3.

    cl_aunit_assert=>assert_subrc(
        exp             = 0
        act             = syst-subrc
        msg             = 'Testing existence of Number Range'
       level            = cl_aunit_assert=>fatal ).


    md_next_number = ms_interval-nrlevel+6(14). " current number (20-digits)
    CALL METHOD zcl_edi_uk_counter=>calculate_modulo_n04
      EXPORTING
        id_input  = md_next_number
      RECEIVING
        rd_output = md_next_number.

    md_flgn = md_next_number+10(4).

  ENDMETHOD.       "Setup

* ----------------------------------------------------------------------
  METHOD teardown.
* ----------------------------------------------------------------------


  ENDMETHOD.       "Teardown


* ----------------------------------------------------------------------
  METHOD _constructor_.
* ----------------------------------------------------------------------

    cl_aunit_assert=>assert_equals(
        exp = 'ZCL_EDI_UK_SVCS_OUT_WILKINSON'
        act = m_ref->md_clsname
        msg = 'Testing attribute MD_CLSNAME'
        level = cl_aunit_assert=>tolerable ).

    cl_aunit_assert=>assert_equals(
        exp = zcl_edi_uk_counter=>mc_nrobj_fgn
        act = m_ref->md_nrobj
        msg = 'Testing attribute MD_NROBJ (SNRO Object)'
        level = cl_aunit_assert=>fatal ).

    cl_aunit_assert=>assert_equals(
        exp = zcl_edi_uk_counter=>mc_nrnr_fgn_08_wilkinson
        act = m_ref->md_nrnr
        msg = 'Testing attribute MD_NRNR (Number Range)'
        level = cl_aunit_assert=>fatal ).

  ENDMETHOD.                    "_constructor_


* ----------------------------------------------------------------------
  METHOD generate_fgn.
* ----------------------------------------------------------------------


    m_ref->md_flgn = m_ref->generate_flgn( md_next_number ).

    cl_aunit_assert=>assert_equals(
      act   = m_ref->md_flgn
      exp   = md_flgn          "<--- please adapt expected value
      msg   = 'Testing File Generation Number (FLGN)'
     level = cl_aunit_assert=>fatal ).

  ENDMETHOD.       "Generate_fgn

ENDCLASS.       "Abap_Unit_Testclass

In the test method you would call your function module with defined input for which you know exactly the expected output.


METHOD my_test_method.

" Build expected result:
  ... lt_result_expected ....
  

  CALL FUCTION 'Z_MY_FUBA'
    IMPORTING
      ...
    EXPORTING
      ...
    TABLES
      ...  = lt_result.

    cl_aunit_assert=>assert_equals(
      act   = lt_result
      exp   = lt_result_expected          "<--- please adapt expected value
      msg   = 'TABLES parameter of fm'
     level = cl_aunit_assert=>fatal ).

ENDMETHOD.

Regards

Uwe

8 REPLIES 8
Read only

Sandra_Rossi
Active Contributor
0 Likes
1,003

Did you search on sdn ??

Search for "cl_aunit_assert"

You will find many introductions, wikis, etc., which will explain you what is "abap unit" for, and how it works.

Read only

uwe_schieferstein
Active Contributor
0 Likes
1,004

Hello Michael

Below I show you the coding of an ABAP Unit test class that I use for testing class methods.


CLASS abap_unit_testclass DEFINITION DEFERRED.
CLASS zcl_edi_uk_svcs_out_wilkinson DEFINITION LOCAL FRIENDS abap_unit_testclass.
* ----------------------------------------------------------------------
CLASS abap_unit_testclass DEFINITION FOR TESTING  "#AU Duration Short
  "#AU Risk_Level Harmless
.
* ----------------------------------------------------------------------
* ===============
  PUBLIC SECTION.
* ===============

* ==================
  PROTECTED SECTION.
* ==================

* ================
  PRIVATE SECTION.
* ================
    DATA:
      ms_interval     TYPE nriv,
      md_number       TYPE edi4refint,
      md_next_number  TYPE edi4refint,
      md_flgn         TYPE edi4refint,
      m_ref TYPE REF TO zcl_edi_uk_svcs_out_wilkinson.      "#EC NOTEXT

    METHODS: setup.
    METHODS: teardown.
    METHODS: _constructor_ FOR TESTING.
    METHODS: generate_fgn FOR TESTING.
**    METHODS: map_icn FOR TESTING.
**    METHODS: postprocessing FOR TESTING.
ENDCLASS.       "Abap_Unit_Testclass
* ----------------------------------------------------------------------
CLASS abap_unit_testclass IMPLEMENTATION.
* ----------------------------------------------------------------------

* ----------------------------------------------------------------------
  METHOD setup.
* ----------------------------------------------------------------------

    CREATE OBJECT m_ref.

    " Check existence of number range
    CALL FUNCTION 'NUMBER_GET_INFO'
      EXPORTING
        nr_range_nr              = m_ref->md_nrnr
        object                   = m_ref->md_nrobj
*       SUBOBJECT                = ' '
*       TOYEAR                   = '0000'
      IMPORTING
        interval                 = ms_interval
      EXCEPTIONS
        interval_not_found       = 1
        object_not_found         = 2
        OTHERS                   = 3.

    cl_aunit_assert=>assert_subrc(
        exp             = 0
        act             = syst-subrc
        msg             = 'Testing existence of Number Range'
       level            = cl_aunit_assert=>fatal ).


    md_next_number = ms_interval-nrlevel+6(14). " current number (20-digits)
    CALL METHOD zcl_edi_uk_counter=>calculate_modulo_n04
      EXPORTING
        id_input  = md_next_number
      RECEIVING
        rd_output = md_next_number.

    md_flgn = md_next_number+10(4).

  ENDMETHOD.       "Setup

* ----------------------------------------------------------------------
  METHOD teardown.
* ----------------------------------------------------------------------


  ENDMETHOD.       "Teardown


* ----------------------------------------------------------------------
  METHOD _constructor_.
* ----------------------------------------------------------------------

    cl_aunit_assert=>assert_equals(
        exp = 'ZCL_EDI_UK_SVCS_OUT_WILKINSON'
        act = m_ref->md_clsname
        msg = 'Testing attribute MD_CLSNAME'
        level = cl_aunit_assert=>tolerable ).

    cl_aunit_assert=>assert_equals(
        exp = zcl_edi_uk_counter=>mc_nrobj_fgn
        act = m_ref->md_nrobj
        msg = 'Testing attribute MD_NROBJ (SNRO Object)'
        level = cl_aunit_assert=>fatal ).

    cl_aunit_assert=>assert_equals(
        exp = zcl_edi_uk_counter=>mc_nrnr_fgn_08_wilkinson
        act = m_ref->md_nrnr
        msg = 'Testing attribute MD_NRNR (Number Range)'
        level = cl_aunit_assert=>fatal ).

  ENDMETHOD.                    "_constructor_


* ----------------------------------------------------------------------
  METHOD generate_fgn.
* ----------------------------------------------------------------------


    m_ref->md_flgn = m_ref->generate_flgn( md_next_number ).

    cl_aunit_assert=>assert_equals(
      act   = m_ref->md_flgn
      exp   = md_flgn          "<--- please adapt expected value
      msg   = 'Testing File Generation Number (FLGN)'
     level = cl_aunit_assert=>fatal ).

  ENDMETHOD.       "Generate_fgn

ENDCLASS.       "Abap_Unit_Testclass

In the test method you would call your function module with defined input for which you know exactly the expected output.


METHOD my_test_method.

" Build expected result:
  ... lt_result_expected ....
  

  CALL FUCTION 'Z_MY_FUBA'
    IMPORTING
      ...
    EXPORTING
      ...
    TABLES
      ...  = lt_result.

    cl_aunit_assert=>assert_equals(
      act   = lt_result
      exp   = lt_result_expected          "<--- please adapt expected value
      msg   = 'TABLES parameter of fm'
     level = cl_aunit_assert=>fatal ).

ENDMETHOD.

Regards

Uwe

Read only

0 Likes
1,003

HI Uwe,

Thanks!

There is a table that i expect to get ,for the comparison, i have to fill it hard coded or there another way?

Like you write : please adapt expected value.

cl_aunit_assert=>assert_equals(
      act   = lt_result
      exp   = lt_result_expected          "<--- please adapt expected value
      msg   = 'TABLES parameter of fm'
     level = cl_aunit_assert=>fatal ).

Best Regards

Read only

0 Likes
1,003

Yes that's abap unit principle !

Read only

0 Likes
1,003

Hello Michael

You can fill the itab with the expected records as you like but the logic MUST BE DIFFERENT from the logic in your fm you want to test. Otherwise you have the trivial case:

lt_result_expected = lt_result_expected

...and you will never detect any error.

In addition, think of all the possible inputs (right and wrong(!)) for your fm, e.g.

- IMPORTING parameter(s) missing

- IMPORTING parameter(s) having wrong contents (e.g. special characters, etc.)

You may define for each of this different test cases a separate test method, e.g.

TEST_FM_INPUT_OK
TEST_FM_MISSING_INPUT
TEST_FM_WRONG_INPUT

And do not forget to clean up your test environment using method TearDown.

Finally, do not miss out the blog series about ABAP Unit by Thomas Weiss:

Regards

Uwe

Read only

0 Likes
1,003

HI Uwe ,

Thanks a lot,

1. From what u say i have to test the input ?,what about the output, i need to declare another 3 methods or more ?

2. I Want to Test FM That have import value like langu (En) and get value in table.

Best Regards

Michael

Read only

0 Likes
1,003

Hello Michael

Normally you would prepare the initial test data in the SetUp method. However, since you have only a single SetUp method per ABAP Unit class available you would need to create three different test classes which means to break a fly on the wheel.

If your fm is expected to retrieve language-dependent contents then I would use a single test method where I would vary the input (EN, DE, FR, etc.), get the expected output (e.g. direct SELECT on the DB tables which I usually never no) and use the CL_AUNIT_ASSERT=>ASSERT_EQUALS method to check the output.

Hopefully your fm raises an exception if the language is unknown (e.g. '?' or 'XY' as input). Here the method of choice would be CL_AUNIT_ASSERT=>ASSERT_SUBRC.

And by the way, do you still use TABLES parameters (hopefully not)? How does the fm behave if the TABLES parameter is already filled (REFRESH at the beginning of the fm, APPEND entries, etc...). Looks like another test case...

Regards

Uwe

Read only

0 Likes
1,003

Hi Uwe,

Thanks for your time.

This is MY Fm .

CALL FUNCTION 'Z_GET_ROLE_INF'
        EXPORTING
          iv_language  = 'EN'
        IMPORTING
          et_role_info = role_info
          et_return    = t_return.

." In t_return i get the error message if language is unknown

p.s.

instead of fill role_info table for comparison hard coded there is a way to build data container?

Best Regards

Michael