# 测试与基准 本文档覆盖当前代码中的测试工具和基准脚本。 ## 单元测试 位置:`backend/tests/test_layout_constraints.py` 运行方式: ```bash cd backend python -m pytest tests/test_layout_constraints.py -v ``` 测试矩阵(基于 `unittest`,不依赖外部服务): | 测试 | 目的 | |------|------| | `test_size_ratio_one_keeps_every_equal_weight_size_identical` | `SIZE_RATIO=1` 时所有同权重词字号完全相同 | | `test_explicit_equal_min_max_is_exact` | `USER_MIN=USER_MAX=12` 时所有词精确为 `12px` | | `test_same_weight_groups_receive_the_same_size` | 相同权重组内字号一致;权重组间字号递增 | | `test_stroke_weight_is_applied_when_excel_weights_are_flat` | Excel 权重全为 `1` 时,笔画权重仍能产生区分度 | | `test_largest_empty_square_ignores_space_outside_mask` | 最大空洞算法只计算掩膜内区域 | | `test_conflicting_explicit_font_bounds_fail` | `MIN > MAX` 时报错而非静默回退 | | `test_explicit_max_overrides_automatic_readability_floor` | 用户覆盖最大字号时,自动可读性下限让位于用户输入 | | `test_base_class_never_uses_a_private_fallback_size` | 基类布局不使用隐藏回退字号 | | `test_rendered_ink_stays_inside_mask_and_does_not_overlap` | 工作网格上:墨迹不超出掩膜、不重叠 | | `test_hd_rendered_ink_does_not_overlap_after_scaling` | 高清放大后:零重叠像素、零碰撞边距 | 固定种子(`SEED=LAYOUT_SEED=20260718`)确保可复现。 ## 基准测试 位置:`backend/tools/benchmark_layout.py` 运行方式: ```bash cd backend python tools/benchmark_layout.py --counts 80 800 --canvas 2000 --assert-targets ``` 参数: | 参数 | 说明 | |------|------| | `--counts COUNT [COUNT ...]` | 测试名单数量,默认 `80 800` | | `--canvas CANVAS` | 画布尺寸,默认 `2000` | | `--max-growth-rounds N` | 最大画布扩展轮数,默认 `1` | | `--assert-targets` | 启用门禁检查 | | `--output-dir PATH` | 输出目录,默认 `backend/benchmark_outputs/` | ### 门禁检查项(`--assert-targets`) | 指标 | 阈值 | 含义 | |------|------|------| | `completeness` | `= 1.0` | 名单必须全部放入 | | `equal_weight_font_consistent` | `True` | 等权重时字号一致 | | `hd_overlap_pixels` | `= 0` | 高清渲染后零重叠 | | `contour_grid_coverage` | `≥ 0.80` | 轮廓网格覆盖率(避免大块空洞) | | `hd_true_density` | `≥ 0.10` | 真实笔画密度 | | `total_seconds` | `< 1.0s` (count<100) / `< 5.0s` (count<1000) | 性能门槛 | ### 输出指标 | 指标 | 说明 | |------|------| | `count` | 名单数量 | | `canvas` | 最终画布尺寸 | | `canvas_growth_rounds` | 画布扩展轮数 | | `placed` | 实际放置词数 | | `completeness` | 完整率 | | `layout_seconds` / `render_seconds` / `total_seconds` | 各阶段耗时 | | `work_fill_ratio` | 工作网格填充率 | | `font_size_min` / `font_size_max` | 字号范围 | | `equal_weight_font_consistent` | 等权重字号一致性 | | `collision_margin` | 碰撞边距 | | `hd_clearance_shifted_words` | 高清精修时位移词数 | | `hd_clearance_max_shift` | 最大位移像素 | | `hd_clearance_px` | 隔离带宽度 | | `hd_clearance_priority_restarts` | 优先级回溯次数 | | `hd_overlap_pixels` | 高清重叠像素(双重检查) | | `largest_empty_square_work_px` | 工作网格最大空洞(像素) | | `largest_empty_square_font_ratio` | 空洞相对字号比例 | | `hd_true_density` | 高清真实笔画密度 | | `ink_bbox_coverage` | 墨迹包围盒覆盖率 | | `contour_grid_coverage` | 轮廓网格覆盖率 | 基准结果保存为 JSON:`backend/benchmark_outputs/benchmark.json` ## 扩展基准 基准脚本使用 `run_generation_pass()` 直接调用核心管线,绕过 HTTP 服务和文件 IO。 - 生成数据:`make_names()` 使用中文姓氏库和双字名库组合出不重复姓名 - 掩膜:`make_round_mask()` 生成圆形掩膜 - 固定种子:`SEED=LAYOUT_SEED=20260718` - 固定配置:`SIZE_RATIO=1.0, N_REPETITIONS=1, WORK_SCALE=0.18, TARGET_FILL_RATIO=0.45` ## CI 建议 ```bash cd backend python -m pytest tests/test_layout_constraints.py -v python tools/benchmark_layout.py --counts 80 800 --canvas 2000 --assert-targets ``` 两次运行均应在数秒内完成。