3.9 KiB
3.9 KiB
历史对账 + 基准差分测试骨架
一句话结论
这套骨架在测试运行时不需要任何数据库连接。 唯一触碰数据库的地方是
tools/exportHistoricalSwapEvents.js——一个开发期一次性导出脚本(把真实
swap_event.data 灌进 fixture),它文件名非 *.test.js,jest 不会执行它,
因此 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"的顾虑)
- 先冻后改:用特征测试把"当前(可能含历史 bug 的)行为"钉死。任何重构只要改变了
金额产出,测试立即变红,逼你查根因,绝不自动 re-baseline(避免
01d7f0c5式静默掩盖)。 - 已知差异显式冻结:
swapLongShort.js的SwapMarginAmount用裸InterestPrincipal(无符号),而unwindSwapTrade.js用InterestDirection求符号——这是真实的代码不一致。 它在 fixture 里以knownDiscrepancies.SwapMarginAmount记录"差异量",测试只在该差异量变化 时报红,既不掩盖也不误报。 - 独立规格不信任任何既有实现:
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.js的FC_*用例校验。
运行
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 # 此时跑的是真实历史对账