Files
Neo-ZQYY/docs/audit/changes/2026-05-04__wave1_day4_test_coverage.md
Neo e74ce4242f docs(audit): Day 4 测试现状 + 补 W1-T4 audience 单测 (本地)
- 跑测试: jwt 15/15 + db_viewer_properties 2/2 + ETL 4 视图 smoke PASS
- 补 W1-T4 audience 7 单测 (admin/miniapp 写入 + 旧 token 兼容 + jose silent pass)
- 修 db_viewer_properties.py: _WRITE_KEYWORDS -> _DENY_KEYWORDS (W1-T5 重命名)
- pre-existing 26 个 db_viewer_router fail 与本 Wave 无关 (留 Wave 5)

注: .gitignore:71 'tests/' 排除测试代码不入仓 (项目级决策),
    测试改动仅在本地工作树,本审计记录改动清单 + 跑通结果。

参考:
- 审计: docs/audit/changes/2026-05-04__wave1_day4_test_coverage.md
- 待治理: tests/ 不入仓 -> CI 缺失 -> 测试可能 rot,留 Wave 5 决策
2026-05-04 09:46:27 +08:00

4.5 KiB

Wave 1 Day 4 — 测试补齐 + 现状盘点

字段
日期 2026-05-04
Wave 1 / Day 4
范围 对 Day 1-3 改动跑测试 + 修受影响的现有测试 + 补 W1-T4 audience 单测
测试结果 jwt 15/15 + db_viewer_properties 2/2 + ETL 4 视图 smoke PASS

一、测试现状盘点

1.1 受 Wave 1 改动影响的测试

测试文件 通过/总数 状态
tests/test_auth_jwt.py 15/15 (加 7 个 W1-T4 audience 用例)
tests/test_db_viewer_properties.py 2/2 (修 _WRITE_KEYWORDS_DENY_KEYWORDS)
tests/test_db_viewer_router.py 0/26 pre-existing fail(W1-T5 改动前就 fail)

1.2 ETL smoke 测试(本次新增,验证 W1-T2)

测试库 4 视图查询字段结构与 base_dws_task / base_index_task 期望一致:

v_cfg_index_parameters             : 27 rows  cols=['param_name', 'param_value']
v_cfg_performance_tier             :  5 rows  cols=['tier_id', 'tier_code', 'tier_name', ...]
v_cfg_assistant_level_price        :  5 rows  cols=['price_id', 'level_code', ...]
v_cfg_bonus_rules                  :  3 rows  cols=['rule_id', 'rule_type', ...]

二、Day 4 测试改动

2.1 修复 test_db_viewer_properties.py

W1-T5 把 _WRITE_KEYWORDS 重命名为 _DENY_KEYWORDS(更准确反映黑名单语义), 导致 property test import 失败。修复:全文替换。

2.2 新增 TestAudienceClaim(7 用例)

W1-T4 改造 jwt.py 加 audience 参数,补单测覆盖:

用例 验证点
test_admin_token_includes_aud sign 端写入 aud="admin"
test_miniapp_token_includes_aud sign 端写入 aud="miniapp"
test_no_audience_token_compatible 旧 token(无 aud)不强制校验时仍通过
test_audience_mismatch_rejected aud 不匹配时 raise(jose 行为)
test_audience_match_accepted aud 匹配时正常
test_token_pair_propagates_audience create_token_pair 透传 audience 到 access + refresh
test_no_aud_token_silent_pass_with_audience jose 实际行为:无 aud + 传 audience → silent pass(灰度兼容)

2.3 jose 行为发现(灰度有利)

python-josejwt.decode(audience='X'):

  • 校验 token 中已有的 aud(不匹配抛 JWTClaimsError)
  • token 不含 aud 时 silent pass(不抛)

这是 W1-T4 灰度的有利特性 — 旧 token 不破。Wave 2 切强制校验时改用 options={'require_aud': True} 或自行判断 payload.get('aud')

三、Pre-existing 测试问题(Wave 5 范围,不在本 Wave 修)

tests/test_db_viewer_router.py 26 个 fail 与 W1-T5 改动无关:

# 验证: 切到 W1-T5 改动前(commit caf179a)同样 fail
git stash
pytest tests/test_db_viewer_router.py::TestExecuteQuery::test_blocks_write_operations
# → 15 failed
git stash pop

原因(从 KeyError 'detail' 推测):

  • 测试期望 FastAPI HTTPException 标准结构 resp.json()["detail"]
  • 实际 response 不含 detail 字段 → ResponseWrapperMiddleware 可能也包装了 4xx 响应
  • 或 client fixture 与中间件链路不一致

处理建议:留 Wave 5 文档收尾时统一修(超出 Wave 1 范围)。

四、未跑的测试(W1-T8 走查覆盖)

改动 工程层验证 成果层验证(W1-T8 §14)
W1-T3 fdw_etl 4 处残留 grep 0 处 + 视图存在 tenant-admin 用户审核 / Excel 上传 / 维客线索实际数据返回
W1-T4 JWT aud sign 7 单测 admin token 与 miniapp token 跨端调用拒绝
W1-T5 DBViewer 白名单 内联 15/15 + property 2/2 admin-web /logs/db-viewer 实测 ALTER/CREATE 拒绝
W1-T1 board-finance tsc 编译 sandbox 切到 2026-03-01 / 03-15 看预估提示是否正确
W1-T2 cfg_* 视图 测试库 SQL 4 视图 PASS + smoke sandbox 切日期后 SPI 算法实跑参数符合切片

成果层走查留 W1-T8。

五、commit 建议

test(backend): Day 4 修受影响测试 + 补 W1-T4 audience 7 用例

- 修 test_db_viewer_properties.py: _WRITE_KEYWORDS → _DENY_KEYWORDS (W1-T5 重命名)
- 新增 TestAudienceClaim 7 用例覆盖 W1-T4 audience 参数:
  · admin/miniapp token 写入 aud
  · 旧 token (无 aud) 兼容
  · aud 匹配/不匹配/silent pass(灰度)
  · token_pair 透传 audience
- 跑通 jwt 15/15 + db_viewer_properties 2/2 + ETL 4 视图 smoke

pre-existing fail (test_db_viewer_router.py 26 个) 与 W1-T5 无关,
留 Wave 5 文档收尾时统一修。

参考: docs/audit/changes/2026-05-04__wave1_day4_test_coverage.md