Files
zszq-trs/YLErpWeb/fe-tests/HISTORICAL_RECONCILIATION.md
T

3.9 KiB
Raw Blame History

历史对账 + 基准差分测试骨架

一句话结论

这套骨架在测试运行时不需要任何数据库连接。 唯一触碰数据库的地方是 tools/exportHistoricalSwapEvents.js——一个开发期一次性导出脚本(把真实 swap_event.data 灌进 fixture),它文件名非 *.test.jsjest 不会执行它 因此 CI 跑 npm test 时零 DB 依赖。

文件清单

文件 运行时是否要 DB 说明
historicalReconciliation.test.js 离线对账:独立规格 vs fixture 中记录的落库值
fixtures/historical_swap_events.json 历史数据夹具(当前为手搓代表性样本,可由导出脚本替换为真实数据)
swapCalc.test.js(既有) swapCalc.js 参考实现 vs C# 金标准 FC_001~009 差分
tools/exportHistoricalSwapEvents.js 是(仅此一处,开发期) 一次性导出真实历史,不属于测试路径

设计原则(回应"重构怕引入新 Bug"的顾虑)

  1. 先冻后改:用特征测试把"当前(可能含历史 bug 的)行为"钉死。任何重构只要改变了 金额产出,测试立即变红,逼你查根因,绝不自动 re-baseline(避免 01d7f0c5 式静默掩盖)。
  2. 已知差异显式冻结swapLongShort.jsSwapMarginAmount 用裸 InterestPrincipal (无符号),而 unwindSwapTrade.jsInterestDirection 求符号——这是真实的代码不一致。 它在 fixture 里以 knownDiscrepancies.SwapMarginAmount 记录"差异量",测试只在该差异量变化 时报红,既不掩盖也不误报。
  3. 独立规格不信任任何既有实现referenceOracle 是按 unwindSwapTrade.js:329 独立重写的 纯函数,作为"应然"基准。若生产代码与独立规格分叉,说明要么生产错了、要么规格写错了——必须人工裁决。

如何扩展到"4 个生产 calcCloseAmount 的差分"

当前骨架用的是独立重写的规格,并未直接驱动那 4 个组件里的 calcCloseAmount。 原因是这 4 个文件在模块顶层就访问 window.otcformat / model / swapPricePrecision 等全局(见 unwindSwapTrade.js:1-2),在 jest 的 node 环境下直接 require 会在加载期抛错。

要把它们纳入差分,唯一的代码改动是"提取纯函数"(行为不变,非统一):

// 在组件文件里,把 calcCloseAmount 的金额聚合核心抽成导出纯函数
function calcUnwindCloseAmountCore(deal, floatPosition, interestList, marginList) {
  // ...原 :329-367 的金额聚合逻辑搬过来,去掉 this / formatSwapAmount 展示归一...
}
// 原方法改为 2 行包装,保持行为完全一致:
calcCloseAmount() {
  const r = calcUnwindCloseAmountCore(this.deal, this.floatPosition, this.interestList, this.marginList);
  Object.assign(this.deal, r);
}
module.exports = { calcUnwindCloseAmountCore }; // 仅新增导出,不改逻辑

提取后 jest 即可 require 并差分,且不连 DB、不碰业务逻辑。这一步务必配合一条 "提取前后产出一致"的快照测试,确保提取本身没改行为。

注意:swapCalc.js 目前未接入生产(其 calcUnwind/calcIncome 注释明写"未接入"), 且它不计算 SwapMarginAmount(利息腿 InterestPrincipal 那一项),因此不能直接拿它 替换 4 个生产函数。它目前只作为"参考金标准"被 swapCalc.test.jsFC_* 用例校验。

运行

cd YLErpWeb/fe-tests
npm i            # 安装 jest / mysql2(可选,仅导出脚本用)
npx jest historicalReconciliation.test.js

要注入真实历史(可选,需 DB):

MYSQL_HOST=... MYSQL_USER=... MYSQL_PASS=... MYSQL_DB=... \
  node tools/exportHistoricalSwapEvents.js --from 2026-01-01 --limit 200
npx jest historicalReconciliation.test.js   # 此时跑的是真实历史对账