deerflow-code/frontend-web/docs/测试-chouqu.md
2026-09-07 18:24:55 +08:00

7.4 KiB
Raw Blame History

定时任务 — 模板填充「源数据抽取」手工测试清单

覆盖功能:定时任务「模板数据转换器」内置 agent —— 把用户传入的源数据转换成 HTML 模板的 DATA 结构并填充生成可预览页面。重点测「源数据抽取」:源可能是 ① 纯 JSON、② 含 JSON 的文本、③ 纯文本,三种形态都要正确处理。

测试环境:后端 http://localhost:8001(make dev),前端 http://localhost:5174(pnpm dev)。 相关代码:deerflow/runtime/scheduler/template_fill.py(extract_embedded_json)、 service.py(_run_template_fill_attempt / _build_conversion_prompt)、 pages/ScheduledTasksPage.tsx。


前置 — 进入表单

# 步骤 预期结果
0.1 任务管理 → 新建定时任务 弹出「新建定时任务」对话框
0.2 「执行智能体」下拉选择 模板数据转换器 表单出现「HTML 模板」下拉;「必须生成 HTML/Markdown」两个开关隐藏
0.3 「HTML 模板」下拉选择 no.1 下方出现「上传 .json」按钮 + 源数据文本框;说明含「未提供源 JSON 时,将直接展示该模板的默认数据」

T1 — 源形态①:纯 JSON

# 步骤 / 输入 预期结果
1.1 在源数据框粘贴纯 JSON(示例见下「样例 A」) 文本框正常接收,无报错
1.2 保存任务 → 「立即执行」 执行记录新增一条,状态最终 succeeded
1.3 打开执行记录 → HTML 预览 渲染出 no.1 大屏,总览指标/各列表数据来自粘贴的 JSON(而非模板默认值)
1.4 执行记录正文 文案为「已根据源数据填充模板「no.1」生成页面」

T2 — 源形态②:含 JSON 的文本(抽取重点)

# 步骤 / 输入 预期结果
2.1 粘贴「样例 B」(前后是中文说明,中间夹一段 JSON) 文本框正常接收
2.2 保存 → 立即执行 → 查看 HTML 页面数据以夹带的 JSON 为准填充;正文里的补充说明(如「重点突出 X」)被一并参考
2.3 验证抽取正确性:JSON 字符串值里含 }(如 "备注": "进度 80%}尚未完成") 不会被误判为 JSON 块提前结束,整段 JSON 被完整抽取

T3 — 源形态③:纯文本(无 JSON)

# 步骤 / 输入 预期结果
3.1 粘贴「样例 C」(一段纯中文描述,无任何 JSON) 文本框正常接收
3.2 保存 → 立即执行 → 查看 HTML 智能体理解文本语义后据实填充模板,产出完整可预览页面(数据可能较稀疏但结构完整)
3.3 不应报「未返回 JSON」类硬失败(除非模型彻底失败重试耗尽) 状态 succeeded

T4 — 空源 → 模板默认数据

# 步骤 预期结果
4.1 源数据框留空,保存 → 立即执行 不调用模型,直接用 no.1 模板自带的默认数据生成
4.2 执行记录正文 「未提供源数据,已用模板「no.1」的默认数据生成页面」
4.3 HTML 预览 展示模板内置的默认大屏

T5 — 上传 .json 文件

# 步骤 预期结果
5.1 点击「上传 .json 文件」,选一个合法 .json 文件内容被读入源数据文本框
5.2 上传一个非法 JSON 内容的文件 toast 提示「文件不是合法 JSON,已填入文本框请检查」,内容仍填入(可手改)
5.3 连续上传同一个文件两次 第二次仍能触发读取(input 已被重置 value)

T6 — no.2(只展示模板)

# 步骤 预期结果
6.1 「HTML 模板」下拉选 no.2 隐藏上传按钮与源数据文本框;显示「该模板暂为直接展示已有数据,无需填写」
6.2 即使之前填过源数据,保存 → 立即执行 忽略源数据,原样输出 no.2 现有页面
6.3 执行记录正文 「已展示模板「no.2」的现有数据」

T7 — 编辑回显

# 步骤 预期结果
7.1 对已保存的模板任务点「编辑」 「执行智能体」「HTML 模板」「源数据」均正确回显
7.2 把模板从 no.1 改成 no.2 再保存 切到 no.2 时源数据区即时隐藏;保存后执行走只展示分支

样例数据(可直接复制粘贴到源数据框)

样例 A — 纯 JSON

{
  "overview": {
    "核心指标": [
      { "名称": "综合区域", "数值": 7, "单位": "区", "说明": "测试数据" },
      { "名称": "组织与单位", "数值": 188, "单位": "个", "说明": "测试数据" }
    ]
  },
  "regions": [
    { "name": "测试区域甲", "scope": "本岛西岸" }
  ],
  "equipment": [
    { "name_zh": "测试装备X", "category": "无人系统", "status": "列装" }
  ]
}

预期:总览第一项「综合区域」显示 7,「组织与单位」显示 188,区域/装备出现「测试区域甲」「测试装备X」。

样例 B — 含 JSON 的文本

这是本月台海态势数据,请据此填充大屏,重点突出离岛防卫:

{"overview": {"核心指标": [{"名称": "综合区域", "数值": 9, "单位": "区", "说明": "含离岛"}]}, "regions": [{"name": "离岛防区", "scope": "外岛", "备注": "进度 80%}尚未完成"}]}

以上数据来自 6 月例会,务必准确,不要臆造未提供的字段。

预期:① 数据以中间 JSON 为准(综合区域=9、出现「离岛防区」);② 字符串里的 }(进度 80%})不破坏抽取;③ 前后的「重点突出离岛防卫」「务必准确」作为补充说明被模型参考。

样例 C — 纯文本

请整理一份台湾滨海防卫概览:覆盖本岛沿岸 9 个综合区域,组织与单位约 280 个,
装备条目近百项(含无人系统、防空、海军平台等类别),并列出若干关键节点与近期演习。
数据以离线知识为准,没有的字段留空即可。

预期:智能体理解语义后据实填充,产出结构完整的页面(具体数值取决于模型,可较稀疏),不报硬失败。


后端单元测试(自动化补充)

# 在 offline-backend-20260512/backend/ 下运行
PYTHONPATH=. uv run --no-sync pytest tests/test_template_fill.py -v          # 引擎:抽取/校验/填充/注册表
PYTHONPATH=. uv run --no-sync pytest tests/test_template_fill_attempt.py -v   # 调度器执行分支:三形态/默认/只展示/重试
PYTHONPATH=. uv run --no-sync pytest tests/test_template_builder_seed.py -v   # 内置 agent 种子

抽取相关关键用例:

  • test_extract_embedded_json_pure_object / _pure_array —— 纯 JSON。
  • test_extract_embedded_json_text_with_json / _fenced —— 含 JSON 的文本 / ```json 围栏。
  • test_extract_embedded_json_plain_text_returns_none —— 纯文本返回 None。
  • test_extract_embedded_json_ignores_braces_in_strings —— 引号内 } 不误判。
  • test_text_with_embedded_json_surfaced_in_prompt —— 转换 prompt 单独标注「识别到的结构化数据」。
  • test_plain_text_source_converts —— 纯文本仍照常转换。
  • test_empty_source_uses_template_default —— 空源用模板默认数据。
  • test_display_only_template_renders_as_is —— no.2 原样输出。

三个文件应全部通过(0 failed)。