General + Comments + Formatting: Clean ABAP
General + Comments + Formatting: Clean ABAP
CHECK or RETURN
METHOD do_it.
CHECK input IS NOT INITIAL.
Methods: Parameter initialization Error handling: Catching
Avoid CHECK in other positions Clear or overwrite EXPORTING Wrap foreign exceptions instead of
LOOP AT itab INTO DATA(row). reference parameters letting them invade your code
CHECK row IS NOT INITIAL. CLEAR et_result. CATCH foreign INTO DATA(error).
RAISE EXCEPTION NEW my( error ).
Don’t clear VALUE parameters RAISE EXCEPTION error.
CLEAR rv_result.
Don’t make copies or write test reports Use test seams as temporary
REPORT zmy_copy. workaround
" for playing around They are not a permanent solution!
Assertions
Test publics, not private internals Use LOCAL FRIENDS to access the
CLASS unit_tests DEFINITION LOCAL FRIENDS
dependency-inverting constructor Few, focused assertions
assert_not_initial( itab ).
Don’t obsess about coverage if it’s hidden away assert_equals( act = itab exp = exp ).
60% -> all done!
Don’t misuse LOCAL FRIENDS to invade Use the right assert type
the tested code assert_equals( act = itab exp = exp ).
CLASS unit_tests LOCAL FRIENDS cut. assert_true( itab = exp ).
cut->db_reader = stub_db_reader
Test classes Assert content, not quantity
Don’t change the productive code to assert_contains_message( key )
Call local test classes by their purpose make the code testable assert_equals( act = lines( messages )
CLASS unit_tests exp = 3 ).
IF in_test_mode = abap_true.
CLASS tests_for_the_class_under_test
Assert quality, not content
Don’t sub-class to mock methods
Put tests in local classes assert_all_lines_shorter_than( … )
Use test seams or OSQL_REPLACE or extract the
REPORT some_tests_for_this
methods to own class Use FAIL to check for expected
Don’t mock stuff that’s not needed exceptions
METHOD throws_on_empty_input.
DATA unused_dependency TRY.
Code under test " when
Don’t build test frameworks cut->do_something( '' ).
Name the code under test setup( test_case_id = '4711' ) cl_abap_unit_assert=>fail( ).
CATCH /clean/some_exception.
meaningfully, or default to CUT " then
DATA switch ENDTRY.
DATA cut ENDMETHOD.
Test Methods
Test interfaces, not classes Forward unexpected exceptions
DATA cut TYPE REF TO some_interface Test methods names: reflect what’s
DATA cut TYPE REF TO some_class instead of catching and failing
given and expected METHODS throws RAISING EXCEPTION bad
Extract the call to the code under test METHODS accepts_emtpy_user_input
METHODS test_1 Write custom asserts to shorten code
to its own method
METHODS map_xml_to_itab and avoid duplication
Use given-when-then assert_table_contains( row )
IMPORTING
given_some_data( ). READ TABLE itab
xml_string TYPE string
do_the_good_thing( ). assert_subrc( )
config TYPE … DEFAULT …
assert_that_it_worked( ).
format TYPE … DEFAULT ….