Стыдно признаться, но я не использую (но стремлюсь использовать) такие конструкции:
ASSERT [ [ID group [SUBKEY sub]] [FIELDS dobj1 dobj2 …] CONDITION ] log_exp.
Вот пример простого использования:
assert i_debet = i_kredit.
Смысл очень простой: если условие не срабатывает, то программа сразу выпадает в осадок – прерывание.
Во-первых, такие утверждения декларируют гарантированные предпосылки, иногда не совсем ясные из предшествующего кода. Можно сказать, что это часть документирования кода. Можно Assert, а можно просто комментарием обойтись.
Во-вторых, это худо бедно избавляет от глупых условных конструкций типа:
select * from BSIK … where …
if sy-subrc = 0. “Оправдана обработка
select * from LFA1 … where …lifnr = BSIK-LIFNR …
if sy-subrc = 0. “Уже глупо, так как невероятно
select * from BKPF … where … belnr = BSIK-BELNR …
if sy-subrc = 0. “Тоже глупо
Тем более, что управление через условия в данном случае уменьшает читабельность кода, особенно если учитывать докуда протянется блок (endif). Assert – это только один оператор, а не блок.
А с другой стороны практика обработки ошибок так или иначе должна присутствовать. Оператор CHECK в данном случае не несёт функций предупреждения.
Особенно это критично, если при этом “вдруг” поведение программы может стать непредсказуемым и/или незаметным с первого взгляда, но влияющим.
В-третьих, провал ASSERT начинает явно сигнализировать о проблемах в самом коде (а не в настройках или в поведении пользователя) – это необходимо именно для разработчиков. Проверка синтаксиса не не гарантирует хороший код.
А вот примеры более сложного использования:
ASSERT ID zfi CONDITION i_debet = i_kredit.
ASSERT ID zfi FIELDS gs_zfi_bsegx-blart gt_bseg-belnr gt_bseg-gjahr CONDITION i_debet = i_kredit.
Управление группами ID делается в транзакции SAAB.
Дополнение ID в отличие от простого вызова дает более гибкое управление поведением при обломе assert:
- зависимость от пользователя, системы
- вход в отладку
- прерывание
- журналирование
- неактивность
Если были указаны дополнительные поля (FIELDS), то они будут отражены в журнале или в окне прерывания. Они должны представлять важные переменные, которые уточнят параметры ошибки. Их преимущество в том, что они будут видны без отладчика – пользователь или тестировщик непосредственно сможет передать эту информацию разработчику.
Вот экран управления для примера:
В качестве резюме:
- ASSERT нужен при написании, отладке и доработке кода. В полностью готовом коде ASSERT не должен срабатывать, но остаётся нести декларативную и страхующую роли.
- Обработка исключений (RAISE EXCEPTION+TRY) на мой взгляд имеет смысл только при межмодульном взаимодействии.
- Поведенческая обработка данных, настроек и действий пользователя нормально реализуется стандартными конструкциями IF и CHECK.
А кроме этого ASSERT есть ещё и похожие операторы, но безусловные и более узко-направленные.
BREAK-POINT { [ID group] | [log_text] }.
LOG-POINT ID group [SUBKEY sub] [FIELDS dobj1 dobj2 …].
BREAK-POINT без приставки ID я переодически использую в тестовых программах.
Во-первых, это прямой вход в отладку в далёких и не нужных никому в данный момент юзер-экзитах, чтоб не расставлять по мандантам точки прерывания.
Особенно это спасает при работе на ненадёжных каналах. А также помогает, когда разделены манданты тестирования и разработки.
А во-вторых, я использую прямой BREAK-POINT в тестовых программа, когда выборка и обработка данных уже сделана, а вывод на экран очень лениво писать.
Как вариант всплыла давняя идея, что можно в пустых юзерэкзитах при отладке системы или прочих исследованиях вставлять код BREAK-POINT ID ZFIXXX, а я обычно пишу вроде CHECK 1 = 1, чтобы было куда поставить точку прерывания вручную.