# 历史对账 + 基准差分测试骨架 ## 一句话结论 **这套骨架在测试运行时不需要任何数据库连接。** 唯一触碰数据库的地方是 `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"的顾虑) 1. **先冻后改**:用特征测试把"当前(可能含历史 bug 的)行为"钉死。任何重构只要改变了 金额产出,测试立即变红,**逼你查根因,绝不自动 re-baseline**(避免 `01d7f0c5` 式静默掩盖)。 2. **已知差异显式冻结**:`swapLongShort.js` 的 `SwapMarginAmount` 用裸 `InterestPrincipal` (无符号),而 `unwindSwapTrade.js` 用 `InterestDirection` 求符号——这是真实的代码不一致。 它在 fixture 里以 `knownDiscrepancies.SwapMarginAmount` 记录"差异量",测试只在该**差异量变化** 时报红,既不掩盖也不误报。 3. **独立规格不信任任何既有实现**:`referenceOracle` 是按 `unwindSwapTrade.js:329` 独立重写的 纯函数,作为"应然"基准。若生产代码与独立规格分叉,说明要么生产错了、要么规格写错了——必须人工裁决。 ## 如何扩展到"4 个生产 calcCloseAmount 的差分" 当前骨架用的是**独立重写的规格**,并未直接驱动那 4 个组件里的 `calcCloseAmount`。 原因是这 4 个文件在模块顶层就访问 `window.otcformat` / `model` / `swapPricePrecision` 等全局(见 `unwindSwapTrade.js:1-2`),在 jest 的 `node` 环境下直接 `require` 会在加载期抛错。 要把它们纳入差分,**唯一的代码改动**是"提取纯函数"(行为不变,非统一): ```js // 在组件文件里,把 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_*` 用例校验。 ## 运行 ```bash cd YLErpWeb/fe-tests npm i # 安装 jest / mysql2(可选,仅导出脚本用) npx jest historicalReconciliation.test.js ``` 要注入真实历史(可选,需 DB): ```bash MYSQL_HOST=... MYSQL_USER=... MYSQL_PASS=... MYSQL_DB=... \ node tools/exportHistoricalSwapEvents.js --from 2026-01-01 --limit 200 npx jest historicalReconciliation.test.js # 此时跑的是真实历史对账 ```