Независимые эталоны и метаморфные проверки финансовой логики
Как отдельно строить ожидаемый финансовый результат, проверять инварианты на большом наборе входов и не путать тест формулы с подтверждением SAP runtime.
5 мин чтения·База знаний
Ревизия 1Общие понятияЧастичное покрытиеКонтекст: CTX-GENERALдокументальная опора: недостаточно данных
Справочный материал. Контракты данных, архитектурные решения и ограничения применения. Источники приведены в материалах, где используются внешние основания.
Независимые эталоны и метаморфные проверки финансовой логики#
Финансовый тест должен проверять смысл результата, а не повторять формулу из реализации. Для этого разделяйте три подхода: эталонное сравнение ожидаемого и фактического значений; property-based проверку инвариантов на множестве входов; метаморфную проверку отношения между исходным и преобразованным сценарием.
В SAP ABAP Unit даёт механизм выполнения тестовых методов с начальными условиями и проверкой результата утверждениями. Наличие тестового метода ещё не делает ожидаемое значение независимым: эталон и его предпосылки нужно обосновать отдельно. SAP описывает ABAP Unit как инструмент запуска тестов ABAP-кода; без целевой системы локальная Python-модель не заменяет такой запуск.
В эталонном тесте для заданного входа заранее известен правильный результат. Источник ожидания может быть ручным расчётом малого примера, утверждённым бизнес-правилом, отдельным проверенным fixture или независимым расчётным путём. Запишите версию правила, единицы, валюту, даты, округление и граничные предпосылки.
Не вычисляйте ожидаемое значение тем же production-функционалом, который проверяете. Не копируйте ту же формулу во вторую тестовую функцию: одинаковая ошибка в обеих копиях даст ложный зелёный результат. Если сравниваете два релиза или две реализации, заранее подтвердите, что их семантика должна совпадать в выбранном сценарии. Иначе ожидаемые различия нужно задать отдельно.
Пусть синтетическая сумма равна 10 001 копейке, а три получателя имеют одинаковый вес. Независимый эталон задаёт результат: A получает 3 334, B получает 3 334, C получает 3 333; при равном остатке первый копеечный остаток отдан получателям по зафиксированному правилу разрешения ничьей. Проверка сверяет значения по ключу и одновременно проверяет сохранение суммы: результат в сумме равен 10 001.
Этот fixture показывает метод проверки целых денежных единиц и стабильного разрешения остатков. Он не заявляет, что SAP использует такой алгоритм распределения.
Пример: сверка по измерениям, а не только по итогу#
В источнике по ключу A записано 100, по ключу B также 100. В целевом результате A равно 80, B равно 120. Общая сумма в обоих наборах равна 200, но состав не совпадает: разница составляет +20 для A и -20 для B. Эталон должен сравнивать по всем значимым ключам, компании, периоду и валюте, иначе взаимно компенсирующие ошибки останутся незамеченными.
Property-based подход задаёт свойства допустимого результата и генерирует много входов, вместо проверки только нескольких вручную выбранных примеров. Для синтетического распределения суммы возможны такие свойства:
сумма выделенных минорных единиц равна входной сумме;
выход содержит ровно заданные ключи получателей и не создаёт пустых ключей;
одинаковые входы и зафиксированное правило дают воспроизводимый результат;
знак распределённых значений согласован со знаком суммы, если симметрия предусмотрена моделью;
каждый получатель получает долю, согласованную с точным весом и правилом округления.
Свойство проверяется только при оговорённых предпосылках. Например, сохранение общей суммы не доказывает правильного распределения между получателями. Для сравнения сверки нужно контролировать и итог, и состав строк.
Генератор должен создавать содержательные случаи: ноль, минимальную единицу, отрицательную сумму там, где она допустима, разные точные веса, много получателей, равные остатки и значения около порогов округления. Для некорректных данных задавайте отдельное ожидаемое поведение, например отказ при пропущенной валюте или пустом бизнес-ключе. Сохраняйте seed генератора; при сбое уменьшайте пример до минимального контрпримера и добавляйте его в фиксированный набор.
Метаморфный тест преобразует вход известным способом и проверяет отношение между двумя результатами, даже когда точное значение второго результата заранее не выписано.
Для примера распределения с нормируемыми точными весами можно проверить:
Перестановка порядка входа. Перестановка получателей или строк не меняет результат по бизнес-ключам, если порядок не имеет бизнес-смысла.
Общий множитель весов. Замена весов 1:1:1 на 2:2:2 не меняет доли, если веса нормируются и прочие настройки неизменны.
Изменение знака. Распределение суммы -10 001 является покомпонентной противоположностью распределения 10 001, если модель определяет такую симметрию.
Разбиение независимых строк. Разбиение и объединение дают тот же агрегат только при заданных предпосылках: те же ключи и валюты, линейная операция, отсутствие промежуточного округления, порогов и изменения порядка.
Эти отношения не универсальны. Например, после округления каждой позиции отдельно агрегат может отличаться от расчёта общей суммы. Перестановка может менять результат, если бизнес-правило явно задаёт последовательность. Поэтому сначала докажите предпосылки преобразования, затем включайте его как тестовое свойство.
Набор, который проходит только правильная реализация, сильнее набора, который лишь исполняет строки. Создайте контролируемые ошибочные варианты: двойной учёт обязательства и факта, округление каждой доли независимо без сохранения остатка, проверка только общей суммы или пропуск одного ключа. Ожидайте, что конкретная проверка их выявит.
В существующем synthetic lab есть независимые golden fixtures для распределения, обязательств и факта, эффективных денежных потоков, строковой сверки с компенсирующими отклонениями и простого начисления. Например, fixture бюджета сравнивает ожидаемые 30 000 минорных единиц с ошибочным двойным счётом 50 000. Это показывает различие между корректной моделью и намеренно неверным вариантом, но само по себе не подтверждает обработку бюджета в SAP.
Для каждого набора сохраняйте версию модели, параметры, ожидаемые значения, генератор и seed, точность/валюту, версии библиотек, команду и фактический результат. Отдельно указывайте, что именно проверено: локальная функция, golden fixture, ABAP Unit в конкретном SAP-релизе или только документальная спецификация. ABAP Unit, ATC, внешний Python-тест и SAP runtime отвечают на разные вопросы.
Статья описывает методику и использует синтетические примеры из проекта; новые тестовые прогоны здесь не заявляются. SAP Help источники сохранены как metadata_only. Локальные fixtures и исходники не являются свидетельством поведения SAP и не подтверждают бухгалтерскую политику какой-либо организации.
A financial test must check the meaning of the result, not repeat the formula in the implementation. Separate three approaches: comparing expected and actual values against an oracle; property-based checks of invariants over many inputs; and metamorphic checks of the relation between an original and transformed scenario.
In SAP, ABAP Unit provides a mechanism for executing test methods with initial conditions and checking results with assertions. A test method does not automatically make its expected value independent; justify the oracle and its assumptions separately. SAP describes ABAP Unit as a tool for running tests on ABAP code; without a target system, a local Python model does not replace that execution.
An oracle test defines the correct result for a given input in advance. The expectation can come from a hand-calculated small example, an approved business rule, a separately verified fixture, or an independent calculation path. Record the rule version, units, currency, dates, rounding, and boundary assumptions.
Do not calculate the expected value with the same production function you are testing. Do not copy the same formula into a second test helper: the same error in both copies gives a false green result. When comparing two releases or implementations, first confirm that their semantics should match for the selected scenario. Otherwise, specify the expected differences separately.
Let the synthetic amount be 10,001 minor units and give three recipients equal weights. The independent oracle specifies: A receives 3,334, B receives 3,334, and C receives 3,333; when the remainders tie, the first residual minor unit follows the documented tie-break rule. The check compares values by key and also confirms that the total is preserved: the allocations sum to 10,001.
This fixture demonstrates checking integer money units and a stable tie break. It does not claim that SAP uses this allocation algorithm.
Example: reconcile by dimensions, not only by total#
The source contains 100 for key A and 100 for key B. The target contains 80 for A and 120 for B. Both totals equal 200, but composition differs: the differences are +20 for A and -20 for B. The oracle must compare all relevant keys, company, period, and currency; otherwise, offsetting errors remain hidden.
A property-based approach defines properties of valid results and generates many inputs instead of checking only a few manually selected examples. For a synthetic amount-allocation model, possible properties include:
the allocated minor units sum to the input amount;
the output contains exactly the specified recipient keys and creates no empty key;
identical inputs and a fixed rule produce a reproducible result;
allocated values respect the input sign when symmetry is part of the model;
each recipient's share is consistent with the exact weight and rounding rule.
A property is valid only under stated assumptions. For example, preserving the total does not prove that the distribution among recipients is correct. Reconciliation checks must compare both the total and the row composition.
The generator should create meaningful cases: zero, one minor unit, negative amounts where allowed, different exact weights, many recipients, tied remainders, and values near rounding thresholds. Define separate expected behavior for invalid data, such as a missing currency or empty business key. Keep the generator seed; when a failure occurs, shrink the example to a minimal counterexample and add it to a fixed set.
Use metamorphic relations with explicit conditions#
A metamorphic test transforms an input in a known way and checks a relation between results, even when the exact second result was not written down in advance.
For the example allocator, possible checks are:
Input order permutation. Permuting recipients or rows does not change the result by business key if order has no business meaning.
Common weight multiplier. Replacing weights 1:1:1 with 2:2:2 does not change shares if weights are normalized and other settings are unchanged.
Sign change. Allocating -10,001 produces the component-wise opposite of allocating 10,001 if the model defines this symmetry.
Split and recombine independent rows. Splitting and merging yields the same aggregate only under explicit assumptions: same keys and currencies, a linear operation, and no intermediate rounding, thresholds, or order dependence.
These relations are not universal. After rounding each item separately, an aggregate may differ from calculating the combined amount. Input order may matter when business rules explicitly prescribe a sequence. Prove the transformation's assumptions before adopting it as a test property.
A suite that passes only the correct implementation is stronger than one that merely executes code lines. Create controlled faulty variants: double-count commitment and actual, round each allocation independently without conserving the remainder, compare only the total, or omit one key. Expect a specific check to detect each one.
The existing synthetic lab contains independent golden fixtures for allocation, commitments and actuals, effective cash flows, row-level reconciliation with offsetting differences, and simple interest accrual. For example, the budget fixture compares an expected 30,000 minor units with a faulty double-count result of 50,000. This shows the distinction between the reference model and an intentionally wrong variant; it does not establish SAP budget behavior.
For each set, retain the model version, parameters, expected values, generator and seed, currency/precision, library versions, command, and actual result. State exactly what was checked: a local function, a golden fixture, ABAP Unit in a specific SAP release, or only a documented specification. ABAP Unit, ATC, external Python tests, and SAP runtime answer different questions.
This article describes methods and synthetic examples from the project; it does not claim new test runs. SAP Help sources are retained as metadata_only. Local fixtures and source code are not evidence of SAP behavior and do not confirm any organization's accounting policy.