Практика использования утверждений ASSERT

Стыдно признаться, но я не использую (но стремлюсь использовать) такие конструкции:

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), то они будут отражены в журнале или в окне прерывания. Они должны представлять важные переменные, которые уточнят параметры ошибки. Их преимущество в том, что они будут видны без отладчика – пользователь или тестировщик непосредственно сможет передать эту информацию разработчику.

Вот экран управления для примера:

Просмотр группы контрольных точек - SAAB

В качестве резюме:

  1. ASSERT нужен при написании, отладке и доработке кода. В полностью готовом коде ASSERT не должен срабатывать, но остаётся нести декларативную и страхующую роли.
  2. Обработка исключений (RAISE EXCEPTION+TRY) на мой взгляд имеет смысл только при межмодульном взаимодействии.
  3. Поведенческая обработка данных, настроек и действий пользователя нормально реализуется стандартными конструкциями 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, чтобы было куда поставить точку прерывания вручную.

Добавить комментарий

Ваш адрес email не будет опубликован.