Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
AlwinPut
Active Participant
The ABAP class CL_ABAP_UNIT_ASSERT is a great class for asserting Actual and Expected data for ABAP unit testing. Asserting equal is comparing the Actual data with the Expected data that it is equal. If it is not equal than a failure will be raised.

The method ASSERT_EQUALS even supports deep structures.

As you can see in my blog ABAP BAPI BO Class Generator in paragraph "Testing the read method" I use deep structures a lot, for example for GET_DATA methods which return all BAPI data in a deep structures returning parameter, so I can use one returning parameter instead of multiple exporting parameters. Example:

This deep structure data can be used in unit testing.

Where the standard SAP ASSERT_EQUALS method a little bit lacks, is on asserting Standard tables.  (CL_ABAP_UNIT_ASSERT version - SAP ABA version: 75D, SP: 2)

For non-ABAP developers: a standard table is a kind of internal memory / parameter table. These Standard tables are very important because almost all BAPIs make use of Standard tables.

I will first explain where it lacks and after that I will show you my solution.

Problem


To show the lacking of asserting Standard tables I created a test program with a deep structure type containing a hashed table, a sorted table and a standard table. And I created a deep structure variable for the Expected data and the Actual data filling these tables all with one line.

The types used in the test program:


The content from Actual (act) and Expected (exp) differ on field "FIELD_2". See picture below:


For all the code of the test program, see "Appendix: ZZUT_ASSERT_EQ_STANDARD_TABLE".

The result of the unit test (Ctrl + Shift + F10) is:


See that component TEST_HASHED_TABLE shows exactly the difference at index 1 in field FIELD_2.

See that component TEST_SORTED_TABLE shows also exactly the difference at index 1 in field FIELD_2.

See that component TEST_STANDARD_TABLE does not show the difference. It shows that the Actual table has a line which is not in the Expected table and visa versa.

By comparing the content of the both tables...

  • [[AAAA|Test value field 1|Test value field 2]]

  • [[AAAA|Test value field 1|Test value field 2 modified.]]


...the field values are separated by a pipe, so we can conclude it must be the 3rd field, which is FIELD_2.

However BAPI tables can contain often much more fields. For example structure BAPI_ALM_ORDER_OPERATION contains 120 fields and than comparing data in this way is not possible anymore.

Solution


I created a new class ZCL_ABAP_UNIT_ASSERT to solve the problem. See "Appendix ZCL_ABAP_UNIT_ASSERT" for the ABAP code.

This class compares standard tables in more detail.

The functionality is:

  • It searches through the data (can be a deep structure) looking for all Standard tables.

  • It first sorts the Actual and Expected table.

  • Than it compares the number of lines. If they differ, than it will be show as an error.

  • Than it checks the Actual content with the Expected content line by line up to a maximum of 10 differences.

  • Than it clears Actual table and Expected table, so these won't be checked anymore by the standard SAP ASSERT_EQUALS.


The result using method ZCL_ABAP_UNIT_ASSERT=>ASSERT_EQUALS is:


The messages for the standard table are not generated in the same failure as the one generated by the standard SAP ASSERT_EQUALS. So, now two failures are generated.

The first failure is for the Standard table by the custom ASSERT_EQUALS method.
The second failure is for the Hashed and Sorted table created by the standard SAP ASSERT_EQUALS method.

Failure 1: Critical Assertion Error: 'Standard table: TEST_STANDARD_TABLE, index: 1, field: FIELD_2'


See that field TEST_STANDARD_TABLE has at row index 1 in field FIELD_2 a difference.

Remark: the row index is based on sorting the Standard table first.

The value difference is shown in the messages part:

Expected [Test value field 2 modified.] Actual [Test value field 2]

Failure 2: Critical Assertion Error: 'Sc001_Test_Assert_Equals: ASSERT_EQUALS'


I selected now the second failure:



You can see that the line related to component TEST_STANDARD_TABLE...

"> Component [TEST_STANDARD_TABLE]: Table Type [S-Table[1x128] of  ... "

...is missing, because the Standard tables are now first checked by the custom ASSERT_EQUALS method and the result of that check is shown in the first failure.

Example of a line count difference.


I added one extra line to the Expected table of the Standard table. Now the test result is:



See failure is "...Table line count of ... are not equal.'.
Expected table contains 2 lines, Actual table contains 1 line.

Example of more than 10 field differences


I added 15 more fields with all values differing from Actual versus Expected.



As you can see, for every differences a new failure is created up to a maximum of 10 differences. I maximized the number of differences to overcome to show too much differences.

On example field difference is FIELD_4. It expected is empty, but it actual contains 4.

Installation



Appendix: ZZUT_ASSERT_EQ_STANDARD_TABLE


REPORT ZZUT_ASSERT_EQ_STANDARD_TABLE.

CLASS unit_test_class DEFINITION FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

PRIVATE SECTION.

METHODS: sc001_test_assert_equals FOR TESTING.
ENDCLASS. "unit_Test_Class


CLASS unit_test_class IMPLEMENTATION.

METHOD sc001_test_assert_equals.

TYPES:
BEGIN OF test_record_type,
key_field TYPE c LENGTH 4,
field_1 TYPE c LENGTH 20,
field_2 TYPE c LENGTH 40,
END OF test_record_type.

TYPES:
BEGIN OF test_data_set_type,
test_hashed_table TYPE HASHED TABLE OF test_record_type
WITH UNIQUE KEY key_field,
test_sorted_table TYPE SORTED TABLE OF test_record_type
WITH UNIQUE KEY key_field,
test_standard_table TYPE STANDARD TABLE OF test_record_type
WITH DEFAULT KEY,
END OF test_data_set_type.

"Fill test data
DATA(act_test_record_1) = VALUE test_record_type(
key_field = 'AAAA'
field_1 = 'Test value field 1'
field_2 = 'Test value field 2'
).

DATA(exp_test_record_1) = VALUE test_record_type(
key_field = act_test_record_1-key_field
field_1 = act_test_record_1-field_1
field_2 = act_test_record_1-field_2 && | modified.|
).

DATA act_test_data_set TYPE test_data_set_type.
DATA exp_test_data_set TYPE test_data_set_type.

INSERT act_test_record_1 INTO TABLE act_test_data_set-test_hashed_table.
INSERT act_test_record_1 INTO TABLE act_test_data_set-test_sorted_table.
APPEND act_test_record_1 TO act_test_data_set-test_standard_table.

INSERT exp_test_record_1 INTO TABLE exp_test_data_set-test_hashed_table.
INSERT exp_test_record_1 INTO TABLE exp_test_data_set-test_sorted_table.
APPEND exp_test_record_1 TO exp_test_data_set-test_standard_table.

cl_abap_unit_assert=>assert_equals(
act = act_test_data_set
exp = exp_test_data_set ).

ENDMETHOD.

ENDCLASS.

4 Comments