Юнит-тест это автоматизированный тест изолированного от зависимостей
логического блока кода. Юнит-тест даёт возможность разрабатывать код, который можно легко развивать с течением времени. При использовании unit-тестирования разработчик гарантирует правильность работы кода, упрощает проверку качества и рефакторинг кода.
Unit-test представляет собой специализированный локальный класс, который вызывает методы основного класса, разрабатываемые функциональные модули или подпрограммы программы. Затем в локальны класс анализирует результат работы программы и сравнивает его с эталонным. Таким образом для unit-test разработка представляет собой черный ящик, который должен в зависимости от специально подготовленных исходных данных возвращать ожидаемые от него результаты. Что именно происходит внутри разработки классу тестирование не важно.
Перейдем к практической реализации unit-test.
Сначала напишем программу, которую будем тестировать. Эта программа будет вычислять арифметическое выражение, представленное в виде строки. Для простоты реализуем только сложение и вычитание.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
REPORT ztest1. *----------------------------------------------------------------------* * CLASS lcl_calculator DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_calculator DEFINITION. PUBLIC SECTION. METHODS: calculate IMPORTING iv_eval TYPE string RETURNING VALUE(rv_val) TYPE i. PRIVATE SECTION. METHODS: eval IMPORTING iv_val1 TYPE i iv_val2 TYPE i iv_operator TYPE c RETURNING VALUE(rv_val) TYPE i. ENDCLASS. "lcl_calculator DEFINITION *----------------------------------------------------------------------* * CLASS lcl_calculator IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_calculator IMPLEMENTATION. METHOD calculate. DATA: lv_eval TYPE string, lv_val TYPE string, lv_operator TYPE c VALUE '+', lv_val1 TYPE i VALUE 0, lv_val2 TYPE i. lv_eval = iv_eval. CONDENSE lv_eval NO-GAPS. DATA(lv_len) = strlen( lv_eval ). DATA(lv_pos) = 0. WHILE lv_pos < lv_len. IF lv_eval+lv_pos(1) CO '1234567890'. lv_val &&= lv_eval+lv_pos(1). ELSE. lv_val2 = lv_val. CLEAR lv_val. lv_val1 = eval( iv_val1 = lv_val1 iv_val2 = lv_val2 iv_operator = lv_operator ). lv_operator = lv_eval+lv_pos(1). ENDIF. lv_pos += 1. ENDWHILE. lv_val2 = lv_val. CLEAR lv_val. rv_val = eval( iv_val1 = lv_val1 iv_val2 = lv_val2 iv_operator = lv_operator ). ENDMETHOD. "calculate METHOD eval. CASE iv_operator. WHEN '+'. rv_val = iv_val1 + iv_val2. WHEN '-'. rv_val = iv_val1 - iv_val2. ENDCASE. ENDMETHOD. ENDCLASS. "lcl_calculator IMPLEMENTATION START-OF-SELECTION. WRITE: NEW lcl_calculator( )->calculate( '-1 + 2 + 5 - 1' ). |
Как видно программа представляет собой локальный класс с одним публичным методом calculate и одним приватным методом eval.
В простом случае мы можем сделать тестовый класс, который будет вызывать публичный метод calculate и сделать несколько тестов, которые покроют и приватный класс. В этом случае добавим include с реализацией unit-test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
CLASS lcl_calculator_t DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS . PRIVATE SECTION. CLASS-METHODS: class_setup. CLASS-METHODS: class_teardown. METHODS: setup. METHODS: teardown. METHODS: calculate FOR TESTING. ENDCLASS. CLASS lcl_calculator_t IMPLEMENTATION. METHOD class_setup. ENDMETHOD. METHOD class_teardown. ENDMETHOD. METHOD setup. ENDMETHOD. METHOD teardown. ENDMETHOD. METHOD calculate. DATA(lv_val) = NEW lcl_calculator( )->calculate('-1+2'). cl_abap_unit_assert=>assert_equals( act = lv_val exp = 1 ). ENDMETHOD. ENDCLASS. |
Для запуска unit-test необходимо выбрать пункт меню Программа-Выполнить-Тесты модулей (Ctrl+Shift+F10).
По рекомендации SAP unit-test иметь тесты для каждого метода, включая приватные. Для того, что бы класс unit-test мог вызывать приватный метод рабочего класса необходимо его сделать дружественным.
Тем не менее чаще всего бывает такое, что вызовами публичных методов весь функционал покрывается unit-test-ами.
Измерить процент покрытия можно выбрав пункт меню Программа-Выполнить-Тест модуля с — Измерение покрытия
Кликнув дважды по имени метода можно увидеть, какие строки не покрыты тестом (отмечены красным цветом). В нашем случае код покрыт полностью
Eclipse рассчитывает процент покрытия точнее
В следующий раз приведу примеры unit-test для функциональных модулей и классов.