Remove test report flow and rename log contract
This commit is contained in:
1 parent
117ce68e71
commit
8bafa24ca0
23 files changed
+107
-384
No files matched your search
@@ -19,7 +19,7 @@
|
||||
- 当涉及 human live 的 docx / KB 混合场景测试设计时,必须阅读 `doc/test-plan/ai-test.md`
|
||||
- 当涉及 Workbench 测试时,必须阅读 `doc/test-plan/workbench-test.md`
|
||||
- 当涉及 Settings 测试时,必须阅读 `doc/test-plan/settings-test.md`
|
||||
- 当涉及测试用例编写,测试规范时,必须阅读 `doc/test.md`
|
||||
- 当涉及测试用例编写、runner、raw logs 或日志分析时,必须阅读 `doc/test.md`
|
||||
|
||||
### 1.4 prd产品文档相关
|
||||
- 当涉及 Workbench 的产品需求、交互、工作区资料范围或验收标准时,必须阅读 `doc/prd/workbench.md`
|
||||
|
||||
@@ -73,14 +73,14 @@ tests/ # 自动化测试
|
||||
|
||||
## 6. 测试目录规则
|
||||
|
||||
- `tests/harness/**` 只放可复用的测试基础设施,不承载旧 suite 治理逻辑或旧 report 契约。
|
||||
- `tests/harness/**` 只放可复用的测试基础设施,不承载旧 suite 治理逻辑或旧分析文档契约。
|
||||
- `tests/fixtures/**` 只放长期复用的输入样本,不混入运行产物。
|
||||
- `tests/ai/**` 只放 AI formal tests。
|
||||
- `tests/unit/**` 放长期保留、但不进入 formal test-plan 的 unit / helper / schema / prompt 类测试。
|
||||
- `tests/workbench/**` 按 workbench PRD 模块组织正式测试。
|
||||
- `tests/settings/**` 按 settings PRD 模块组织正式测试。
|
||||
- `tests/kb-search/**` 预留给检索链路测试;`tests/temp/**` 仅放按需临时排查用例。
|
||||
- `tests/logs/**` 只放每次运行的原始日志;`tests/report/**` 只放按 domain 维护的正式分析文档。
|
||||
- `tests/logs/**` 只放每次运行的原始日志;raw logs 之外不再维护测试专用正式分析目录。
|
||||
- 测试目录统一使用 kebab-case,运行产物不得反向成为测试发现入口。
|
||||
|
||||
## 7. 文档目录规则
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## 1. 总体目标
|
||||
|
||||
- 本计划用于定义 AI 域正式测试的范围与领域特有规则。
|
||||
- 正式 / temp 准入、runner、raw logs、report 与正式 case 共享字段,统一遵循 `doc/test.md`。
|
||||
- 正式 / temp 准入、runner、raw logs 与正式 case 共享字段,统一遵循 `doc/test.md`。
|
||||
- AI 正式测试只围绕两类稳定对象治理:
|
||||
1. `tool`
|
||||
2. `human`
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
Settings 正式测试统一对齐 [settings.md](/Users/test/work-space/NCurator-Desktop/doc/prd/settings.md),新增、调整或验收结论都应引用对应的 `SET-*` 需求编号与验收编号。
|
||||
|
||||
正式 / temp 准入、runner、raw logs、report 与正式 case 共享字段,统一遵循 `doc/test.md`。
|
||||
正式 / temp 准入、runner、raw logs 与正式 case 共享字段,统一遵循 `doc/test.md`。
|
||||
|
||||
## 2. Suite 设计
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
workbench 正式测试统一对齐 [workbench.md](/Users/test/work-space/NCurator-Desktop/doc/prd/workbench.md),新增、调整或验收结论都应引用对应的 `WB-*` 需求编号与验收编号。
|
||||
|
||||
正式 / temp 准入、runner、raw logs、report 与正式 case 共享字段,统一遵循 `doc/test.md`。
|
||||
正式 / temp 准入、runner、raw logs 与正式 case 共享字段,统一遵循 `doc/test.md`。
|
||||
|
||||
## 2. Suite 设计
|
||||
|
||||
|
||||
+14
-191
@@ -3,15 +3,14 @@
|
||||
## 1. 文档定位
|
||||
|
||||
- 本文是 NCurator-Desktop 的唯一测试总规范。
|
||||
- 本文负责定义测试体系总览、正式 case 准入、正式测试闭环、runner、raw logs 与 report 契约。
|
||||
- 本文负责定义测试体系总览、正式 case 准入、正式测试闭环、runner 与 raw logs 契约。
|
||||
- 各业务域的 suite 列表、正式 case 定义与领域特有规则,只在对应 `doc/test-plan/**` 中维护,本文不重复登记 case 清单。
|
||||
- 如果 case 覆盖的是用户可见功能,还必须先对齐对应 `doc/prd/**`。
|
||||
- 如果只记一件事:写测试前先判断这是正式长期回归 case,还是一次性临时排查 case。
|
||||
|
||||
正式测试体系只沉淀两层长期产物:
|
||||
正式测试体系只沉淀一层长期产物:
|
||||
|
||||
- 原始日志:`tests/logs/**`
|
||||
- 正式分析文档:`tests/report/<domain>/report.md`
|
||||
|
||||
正式测试样例只记录事实,不直接写失败原因分析、优化建议或能力判断。
|
||||
|
||||
@@ -20,7 +19,7 @@
|
||||
### 2.1 正式 case 与临时 case
|
||||
|
||||
- 正式长期回归 case
|
||||
- 用于长期维护、参与 gating、进入正式 report。
|
||||
- 用于长期维护、参与 gating。
|
||||
- 必须进入正式测试闭环。
|
||||
- 临时排查 case
|
||||
- 只用于一次性排查、验证猜想、临时复现或补上下文。
|
||||
@@ -28,7 +27,7 @@
|
||||
- 默认策略
|
||||
- 用户没有明确要求“补正式长期 case”时,默认先写 `tests/temp/**`。
|
||||
- 只要还在排查、验证猜想、试运行 fixture 或尚未确定要长期维护,一律先放 `tests/temp/**`。
|
||||
- 只有确认要长期维护、参与 gating 或进入正式 report 的 case,才进入正式测试目录。
|
||||
- 只有确认要长期维护、参与 gating 的 case,才进入正式测试目录。
|
||||
|
||||
### 2.2 目录结构
|
||||
|
||||
@@ -43,13 +42,6 @@ tests/
|
||||
kb-search/
|
||||
temp/
|
||||
logs/
|
||||
report/
|
||||
ai/
|
||||
report.md
|
||||
workbench/
|
||||
report.md
|
||||
settings/
|
||||
report.md
|
||||
```
|
||||
|
||||
规则:
|
||||
@@ -61,7 +53,7 @@ tests/
|
||||
- 各 domain 的 `suite` 列表与归属,只在对应 `doc/test-plan/**` 中定义。
|
||||
- 当某个 `suite` 不需要继续细分时,正式 case 可以直接放在该 `suite` 目录下。
|
||||
- `tests/unit/**` 用于长期保留、但不进入 `doc/test-plan/**` 正式治理的 unit / helper / schema / prompt 类测试。
|
||||
- `tests/temp/**` 默认不参与 gating,也不参与正式 report 汇总。
|
||||
- `tests/temp/**` 默认不参与 gating,也不沉淀正式长期产物。
|
||||
- 除 `tests/temp/**` 外,`tests/**` 中的正式测试目录只允许放已在 `doc/test-plan/**` 登记的 case。
|
||||
|
||||
### 2.3 稳定映射模型
|
||||
@@ -75,7 +67,7 @@ tests/
|
||||
- `suite` 下可选子目录。
|
||||
- 只有同一 `suite` 内确实需要继续分层时才创建。
|
||||
- `case`
|
||||
- 最终测试文件,对应唯一 `caseId`、唯一日志目录和唯一 report 归属。
|
||||
- 最终测试文件,对应唯一 `caseId` 与唯一日志目录。
|
||||
- `type`
|
||||
- 测试类型只通过文件名体现。
|
||||
- 普通测试默认视为 `backend`;文件名包含 `.e2e.test.ts` 时视为 `e2e`。
|
||||
@@ -91,7 +83,7 @@ tests/
|
||||
- 如果 case 覆盖的是用户可见功能,`How / Oracle` 必须映射到对应 `doc/prd/**` 的需求编号与验收编号。
|
||||
- 如果 PRD 的功能入口、交互流程、状态反馈或验收口径发生变化,必须先更新对应 `doc/prd/**`,再更新 `doc/test-plan/**` 与测试代码。
|
||||
- 如果实现行为变更导致正式 case 预期变化,必须先更新对应 `doc/test-plan/**`,再修改测试代码。
|
||||
- 每个正式 `caseId` 都必须稳定映射到唯一测试文件、唯一日志目录和唯一 report 归属。
|
||||
- 每个正式 `caseId` 都必须稳定映射到唯一测试文件与唯一日志目录。
|
||||
|
||||
### 3.2 正式 case 共享字段
|
||||
|
||||
@@ -161,7 +153,7 @@ tests/
|
||||
4. 再写或调整 `tests/**` 中的正式测试代码。
|
||||
5. 通过 `scripts/test-workflow.mjs` 执行并产生日志。
|
||||
6. 先看 `timeline.jsonl`,不足时再看 `runtime-events.jsonl`、`meta.json` 与 `artifacts.json`。
|
||||
7. 最后基于 `tests/logs/<domain>/**` 更新 `tests/report/<domain>/report.md`。
|
||||
7. 最后基于 raw logs 回流结论,决定是否需要更新 `doc/test-plan/**` 或实现代码。
|
||||
|
||||
### 4.2 runner 与常用命令
|
||||
|
||||
@@ -178,7 +170,6 @@ runner 不负责:
|
||||
- 写事实汇总稿。
|
||||
- 写失败原因分析。
|
||||
- 写优化建议。
|
||||
- 更新正式 `report.md`。
|
||||
|
||||
当前常用命令按域收口如下:
|
||||
|
||||
@@ -223,17 +214,11 @@ runner 支持的过滤参数:
|
||||
- 必要时回看 `meta.json` 与 `artifacts.json`,确认 run 摘要、统计值和附件索引。
|
||||
- 所有分析结论都必须可回溯到 raw logs 与 artifacts,不得脱离证据做推断。
|
||||
|
||||
### 4.4 更新正式 report
|
||||
|
||||
- 正式 report 固定更新 `tests/report/<domain>/report.md`。
|
||||
- report 只能基于 `tests/logs/<domain>/**` 及其附件生成;`tests/temp/**` 不进入正式 report。
|
||||
- report 负责沉淀当前现状分析、失败模式和下一步建议,但不能替代 raw logs 本身。
|
||||
|
||||
### 4.5 结论回流
|
||||
### 4.4 结论回流
|
||||
|
||||
- 如果问题出在 case 定义、验收口径或阶段边界,必须先改 `doc/test-plan/**`,再改测试代码。
|
||||
- 如果只是实现缺陷或回归问题,可在保持 case 规格不变的前提下修实现并重跑。
|
||||
- report 中已有结论若被新 run 推翻,应以最新 raw logs 重新分析并更新,不保留无证据的旧判断。
|
||||
- 任何分析结论若被新 run 推翻,都应以最新 raw logs 重新分析,不保留无证据的旧判断。
|
||||
|
||||
## 5. runner 与原始产物契约
|
||||
|
||||
@@ -356,7 +341,7 @@ tests/logs/<domain>/<suite>/<groups...>/<caseId>/<runId>/
|
||||
- 范围固定为完整 runtime 原始事件流。
|
||||
- 普通测试与 e2e 的采集路径可以不同,但最终落盘契约必须一致。
|
||||
- `runtime-events.jsonl` 始终写出;如果本次 run 没有 runtime 事件,则写空文件。
|
||||
- 当 `Oracle`、断言 `data`、`timeline.jsonl` 或 report 仍不足以解释失败原因时,必须继续回看 `runtime-events.jsonl`。
|
||||
- 当 `Oracle`、断言 `data` 或 `timeline.jsonl` 仍不足以解释失败原因时,必须继续回看 `runtime-events.jsonl`。
|
||||
|
||||
### 5.5 `artifacts.json`
|
||||
|
||||
@@ -410,179 +395,17 @@ tests/logs/<domain>/<suite>/<groups...>/<caseId>/<runId>/
|
||||
- 生成位于 `artifacts/playwright/report/index.html` 的 HTML 诊断页。
|
||||
- 默认不保留 video。
|
||||
|
||||
## 6. 正式 report 契约
|
||||
|
||||
### 6.1 位置与作用
|
||||
|
||||
- `report` 是正式测试闭环中的最终分析产物;前提是对应 domain 已先生成可回看的 raw logs。
|
||||
- 当前正式分析文档固定放在:
|
||||
|
||||
```text
|
||||
tests/report/<domain>/
|
||||
report.md
|
||||
```
|
||||
|
||||
- `report.md` 是当前业务域唯一正式分析报告。
|
||||
- `report.md` 只基于 `tests/logs/<domain>/**` 与 artifacts 写出当前现状分析。
|
||||
|
||||
### 6.2 `report.md` 建议结构
|
||||
|
||||
- 顶层先写 `总览`
|
||||
- `总览` 至少包含:
|
||||
- `分析范围`
|
||||
- `总体结论`
|
||||
- `下一阶段建议`
|
||||
- `总览` 之后按 suite / groups 展开
|
||||
- 每个实际分析节点至少包含:
|
||||
- `证据`
|
||||
- `通过率`
|
||||
- `失败分析`
|
||||
- `当前评估`
|
||||
- `下一步建议`
|
||||
|
||||
### 6.3 `report.md` 格式约束
|
||||
|
||||
- 顶层标题使用 `# <Domain> 域测试报告`。
|
||||
- 顶层必须先有 `## 总览`。
|
||||
- `总览` 下固定小节顺序:
|
||||
- `### 分析范围`
|
||||
- `### 总体结论`
|
||||
- `### 下一阶段建议`
|
||||
- `总体结论` 中的统计口径固定拆成两类:
|
||||
- `历史总数据`
|
||||
- `最新总数据`
|
||||
- `历史总数据` 基于当前 analysis window 内全部 raw runs 统计。
|
||||
- `最新总数据` 每个 case 只看最新一轮 run 的修复后统计。
|
||||
- suite 之下按目录树继续展开:
|
||||
- suite 使用 `##`
|
||||
- suite 下第一层 group 使用 `###`
|
||||
- 更深层 group 继续按 Markdown 标题层级递增
|
||||
- 每个实际分析节点都必须包含以下固定小节,顺序保持一致:
|
||||
- `证据`
|
||||
- `通过率`
|
||||
- `失败分析`
|
||||
- `当前评估`
|
||||
- `下一步建议`
|
||||
- `证据` 默认只列出能定位该条证据的最小信息,例如 `caseId`、`runId`、`status`。
|
||||
- 不要在 report 正文里机械展开 `meta.json`、`timeline.jsonl`、`runtime-events.jsonl`、`artifacts.json` 这些文件名。
|
||||
- 只有当失败分析或结论明确依赖某个关键附件时,才额外补充附件名称或用途说明。
|
||||
- `通过率` 只写当前节点覆盖范围内的统计,不混入其他节点数据。
|
||||
- `通过率` 固定拆成两组:
|
||||
- `历史总数据`:`totalRuns`、`passedRuns`、`failedRuns`、`historicalSuccessRate`
|
||||
- `最新总数据`:`latestCaseCount`、`latestPassedCases`、`latestFailedCases`、`latestSuccessRate`
|
||||
- `历史总数据` 与 `最新总数据` 不得混写成同一个 successRate 口径。
|
||||
- `失败分析` 在没有 failed run 时应明确写“当前没有 failed run,因此无法给出失败模式结论”。
|
||||
- `当前评估` 负责总结当前状态和主要不足。
|
||||
- `下一步建议` 只写基于现有证据能支撑的下一步建议。
|
||||
|
||||
### 6.4 `report.md` 最小示例
|
||||
|
||||
```md
|
||||
# Workbench 域测试报告
|
||||
|
||||
## 总览
|
||||
|
||||
### 分析范围
|
||||
|
||||
- raw logs 范围: 当前仓库内 `tests/logs/workbench/**`
|
||||
- 已分析 scope: `workbench/<suite-a>`、`workbench/<suite-b>`
|
||||
|
||||
### 总体结论
|
||||
|
||||
- 历史总数据: `2` 次 raw runs,其中 `2` 次 passed、`0` 次 failed,historicalSuccessRate=`100.0%`
|
||||
- 最新总数据: `2 / 2` 个 case 的最新一轮 run 为 passed,latestSuccessRate=`100.0%`
|
||||
- 当前结论: 当前已覆盖一个普通样例和一个 e2e smoke,但剩余 suite 仍待补齐。
|
||||
|
||||
### 下一阶段建议
|
||||
|
||||
- 先补 `suite-a` 的边界收敛
|
||||
- 再补 `suite-b` 的主线闭环
|
||||
|
||||
## <suite-a>
|
||||
|
||||
### 证据
|
||||
|
||||
- `workbench-suite-a-basic` | type=`backend` | run=`20260315-101530-112` | status=`passed`
|
||||
|
||||
### 通过率
|
||||
|
||||
- 历史总数据:
|
||||
- totalRuns: 1
|
||||
- passedRuns: 1
|
||||
- failedRuns: 0
|
||||
- historicalSuccessRate: 100.0%
|
||||
- 最新总数据:
|
||||
- latestCaseCount: 1
|
||||
- latestPassedCases: 1
|
||||
- latestFailedCases: 0
|
||||
- latestSuccessRate: 100.0%
|
||||
|
||||
### 失败分析
|
||||
|
||||
- 当前没有 failed run,因此无法给出失败模式结论。
|
||||
|
||||
### 当前评估
|
||||
|
||||
- suite-a 的基础路径已稳定产出 raw logs。
|
||||
- 当前不足是边界场景覆盖仍不足。
|
||||
|
||||
### 下一步建议
|
||||
|
||||
- 增加 `workbench-suite-a-edge-1`
|
||||
- 增加 `workbench-suite-a-edge-2`
|
||||
|
||||
## <suite-b>
|
||||
|
||||
### 证据
|
||||
|
||||
- `workbench-suite-b-smoke.e2e` | type=`e2e` | run=`20260315-103002-008` | status=`passed`
|
||||
- 关键附件: playwright trace
|
||||
|
||||
### 通过率
|
||||
|
||||
- 历史总数据:
|
||||
- totalRuns: 1
|
||||
- passedRuns: 1
|
||||
- failedRuns: 0
|
||||
- historicalSuccessRate: 100.0%
|
||||
- 最新总数据:
|
||||
- latestCaseCount: 1
|
||||
- latestPassedCases: 1
|
||||
- latestFailedCases: 0
|
||||
- latestSuccessRate: 100.0%
|
||||
|
||||
### 失败分析
|
||||
|
||||
- 当前没有 failed run,因此无法给出失败模式结论。
|
||||
|
||||
### 当前评估
|
||||
|
||||
- suite-b 的 e2e smoke 主链路已可用。
|
||||
- 当前不足是剩余验收分支仍未纳入。
|
||||
|
||||
### 下一步建议
|
||||
|
||||
- 补充 `suite-b` 的验收分支 1
|
||||
- 补充 `suite-b` 的验收分支 2
|
||||
```
|
||||
|
||||
约束:
|
||||
|
||||
- report 只引用 raw logs 与 artifacts 作为证据来源。
|
||||
- report 可以做分析与建议,但不得写入没有日志依据的推断。
|
||||
|
||||
## 7. 明确禁止与常见误区
|
||||
## 6. 明确禁止与常见误区
|
||||
|
||||
明确禁止:
|
||||
|
||||
- 测试样例直接输出失败原因分析。
|
||||
- runner 自动调用测试所用 AI 模型生成 report。
|
||||
- report 写入没有日志依据的推断。
|
||||
- 脱离 raw logs 与 artifacts 写入没有证据依据的分析结论。
|
||||
- 为单个 runner 或单种工具单独再设计一套平行 raw log 契约。
|
||||
|
||||
常见误区:
|
||||
|
||||
- 把 `tests/unit/**` 当成 formal domain case 管理。
|
||||
- 把 `tests/temp/**` 的结果直接写进正式 report。
|
||||
- 把 `tests/temp/**` 的结果直接当成正式长期结论。
|
||||
- 在 `timeline.jsonl` 中倾倒底层噪音,而不是保留高价值语义事件。
|
||||
- 在没有更新 `doc/test-plan/**` 的情况下直接修改正式 case 预期。
|
||||
@@ -8,7 +8,36 @@ import {
|
||||
seedRiskReportKb,
|
||||
seedRiskReportWorkspace
|
||||
} from '../../../harness/backend/aiLiveTestData'
|
||||
import { filterAiRunEventsByType } from '../testUtils'
|
||||
import { filterAiRunEventsByType, hasKbToolCall } from '../testUtils'
|
||||
|
||||
type DocxApplyOpsResult = {
|
||||
changedBlocks?: Array<{
|
||||
blockId?: string
|
||||
beforeText?: string
|
||||
afterText?: string
|
||||
}>
|
||||
}
|
||||
|
||||
const mentionsPreviewReady = (text: string): boolean => /(可预览|预览|preview)/i.test(text)
|
||||
|
||||
const mentionsOriginalPreserved = (text: string): boolean =>
|
||||
/(未|不会|没有).{0,10}(覆盖|改写|修改).{0,10}(原(文件|模板)|原始模板|模板文件|源文件)/.test(text) ||
|
||||
/(保留|保持).{0,10}(原(文件|模板)|原始模板|模板文件|源文件).{0,6}(不动|不变)/.test(text)
|
||||
|
||||
const hasExpectedRiskReportChanges = (changedBlocks: readonly DocxApplyOpsResult['changedBlocks'][number][]) =>
|
||||
changedBlocks.length === 2 &&
|
||||
changedBlocks.some(
|
||||
(block) =>
|
||||
block.blockId === 'b:1' &&
|
||||
/风险结论/.test(block.beforeText || '') &&
|
||||
/待跟进/.test(block.afterText || '')
|
||||
) &&
|
||||
changedBlocks.some(
|
||||
(block) =>
|
||||
block.blockId === 'b:2' &&
|
||||
/负责人说明/.test(block.beforeText || '') &&
|
||||
/Alice/.test(block.afterText || '')
|
||||
)
|
||||
|
||||
describe('ai human live backend', () => {
|
||||
it('human-risk-report-draft-live', async () => {
|
||||
@@ -61,6 +90,11 @@ describe('ai human live backend', () => {
|
||||
|
||||
const toolResults = filterAiRunEventsByType(result.events, 'tool_call_result')
|
||||
const toolNames = toolResults.map((event) => event.toolName)
|
||||
const latestDocxApplyOpsEvent = toolResults
|
||||
.filter((event) => event.toolName === 'docx_apply_ops')
|
||||
.at(-1)
|
||||
const docxApplyOps = (latestDocxApplyOpsEvent?.result?.data as DocxApplyOpsResult | undefined) || {}
|
||||
const changedBlocks = docxApplyOps.changedBlocks || []
|
||||
const docxArtifacts =
|
||||
result.output?.artifacts?.filter(
|
||||
(artifact) =>
|
||||
@@ -77,23 +111,55 @@ describe('ai human live backend', () => {
|
||||
runtime.assertThat(
|
||||
result.output?.status === 'completed' &&
|
||||
toolNames.includes('terminal_run_command') &&
|
||||
toolNames.some((toolName) => toolName.startsWith('kb_')) &&
|
||||
hasKbToolCall(result.events) &&
|
||||
toolNames.includes('docx_open') &&
|
||||
toolNames.includes('docx_apply_ops') &&
|
||||
toolNames.includes('docx_render_preview') &&
|
||||
docxArtifacts.length > 0 &&
|
||||
templateUnchanged &&
|
||||
toolNames.includes('docx_render_preview'),
|
||||
{
|
||||
name: 'human-live-risk-report-runs-required-tool-chain',
|
||||
message: 'live human complex case 应通过 terminal、KB 与 docx 真实工具链完成周报草稿任务。',
|
||||
data: {
|
||||
toolNames,
|
||||
summary: result.output?.summary,
|
||||
deliveryMarkdown: result.output?.deliveryMarkdown,
|
||||
artifacts: result.output?.artifacts
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
runtime.assertThat(docxArtifacts.length > 0 && templateUnchanged, {
|
||||
name: 'human-live-risk-report-produces-preview-without-overwriting-template',
|
||||
message: 'live human complex case 应生成 preview/draft artifact,且原模板文件不能被覆盖。',
|
||||
data: {
|
||||
toolNames,
|
||||
templatePath: result.workspaceSeed.templatePath,
|
||||
artifacts: result.output?.artifacts
|
||||
}
|
||||
})
|
||||
|
||||
runtime.assertThat(hasExpectedRiskReportChanges(changedBlocks), {
|
||||
name: 'human-live-risk-report-updates-risk-and-owner-placeholders',
|
||||
message: 'live human complex case 应把模板中的风险结论和负责人说明两处占位符替换为实际内容。',
|
||||
data: {
|
||||
changedBlocks,
|
||||
toolNames
|
||||
}
|
||||
})
|
||||
|
||||
runtime.assertThat(
|
||||
/weekly-risk-report-template\.docx/.test(deliveryText) &&
|
||||
/风险结论/.test(deliveryText) &&
|
||||
/负责人(说明)?/.test(deliveryText) &&
|
||||
/Weekly Risk Summary\.md/.test(deliveryText) &&
|
||||
/Owner Note\.md/.test(deliveryText) &&
|
||||
/(预览|preview)/i.test(deliveryText) &&
|
||||
/(未覆盖原文件|原文件未被覆盖|未覆盖原件)/.test(deliveryText),
|
||||
mentionsPreviewReady(deliveryText) &&
|
||||
mentionsOriginalPreserved(deliveryText),
|
||||
{
|
||||
name: 'human-live-completes-risk-report-draft-through-real-tool-chain',
|
||||
message: 'live human complex case 应通过 terminal、KB 与 docx 真实工具链完成周报草稿任务。',
|
||||
name: 'human-live-risk-report-delivery-explains-user-facing-outcome',
|
||||
message: 'live human complex case 的最终交付应从用户视角说明模板、两处修改、依据来源、预览产物和未覆盖原文件。',
|
||||
data: {
|
||||
toolNames,
|
||||
changedBlocks,
|
||||
summary: result.output?.summary,
|
||||
deliveryMarkdown: result.output?.deliveryMarkdown,
|
||||
artifacts: result.output?.artifacts
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import { resolveRunLogDir } from '../../harness/backend/write-run-log'
|
||||
import type { TestArtifactsIndex, TestRunMeta } from '../../harness/core/report-contract'
|
||||
import type { TestArtifactsIndex, TestRunMeta } from '../../harness/core/run-log-contract'
|
||||
|
||||
export const readCapturedRunLog = async (input: {
|
||||
scope: string
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cp, mkdir } from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import type { AiRunEvent } from '../../../src/shared/types'
|
||||
import type { TestArtifact } from '../core/report-contract'
|
||||
import type { TestArtifact } from '../core/run-log-contract'
|
||||
import { resolveRunArtifactsDir } from './write-run-log'
|
||||
|
||||
const sanitizeFileName = (value: string): string => {
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
type TestLogEvent,
|
||||
type TestRunMeta,
|
||||
type TestRunStatus
|
||||
} from '../core/report-contract'
|
||||
} from '../core/run-log-contract'
|
||||
|
||||
const fixturesRoot = path.resolve(process.cwd(), 'tests', 'fixtures')
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
SeedKbDocumentInput,
|
||||
SeedWorkspaceFileRecord
|
||||
} from './test-types'
|
||||
import type { TestArtifact } from '../core/report-contract'
|
||||
import type { TestArtifact } from '../core/run-log-contract'
|
||||
import { resolveRunArtifactsDir } from '../core/write-run-log'
|
||||
|
||||
export const BACKEND_SEED_MANIFEST_SCHEMA_VERSION = 1 as const
|
||||
|
||||
@@ -27,9 +27,9 @@ import type {
|
||||
TestType,
|
||||
TestLogEvent,
|
||||
TestRunMeta
|
||||
} from '../core/report-contract'
|
||||
} from '../core/run-log-contract'
|
||||
|
||||
export type { TestDomain, TestType, TestLogEvent, TestRunMeta } from '../core/report-contract'
|
||||
export type { TestDomain, TestType, TestLogEvent, TestRunMeta } from '../core/run-log-contract'
|
||||
|
||||
export type ApprovalPolicy = 'auto-approve' | 'deny-medium-high' | 'deny-all'
|
||||
|
||||
|
||||
File renamed without changes.
@@ -7,7 +7,7 @@ import {
|
||||
type TestArtifact,
|
||||
type TestLogEvent,
|
||||
type TestRunMeta
|
||||
} from './report-contract'
|
||||
} from './run-log-contract'
|
||||
import type { PersistedSeedManifest } from '../backend/seedManifest'
|
||||
|
||||
const pad2 = (value: number): string => String(value).padStart(2, '0')
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
type TestLogStatus,
|
||||
type TestRunMeta,
|
||||
type TestRunStatus
|
||||
} from '../core/report-contract'
|
||||
} from '../core/run-log-contract'
|
||||
import { createRunId, resolveRunArtifactsDir, writeRunLog } from '../core/write-run-log'
|
||||
import { launchElectronApp, type E2ERuntimeSignals } from './electronApp'
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# AI 域测试报告
|
||||
|
||||
## 总览
|
||||
|
||||
- raw logs 范围:当前仓库内 `tests/logs/ai/**`
|
||||
- 本次纳入分析的 suite:`tool`、`human`
|
||||
- 当前未纳入分析的范围:`human/live`
|
||||
|
||||
### 总体结论
|
||||
|
||||
- 当前正式 AI 基线已经收敛到 `tool + human` 两类 suite。
|
||||
- `tool` 继续提供 docx、kb、terminal、hand 的稳定底座。
|
||||
- `human/mock-llm` 继续作为 human-only runtime 的正式回归基线。
|
||||
|
||||
## tool
|
||||
|
||||
- 当前 `tool` suite 仍作为 AI 域稳定正式基线。
|
||||
- 后续继续围绕真实工具、真实 artifact、真实审批边界维护。
|
||||
|
||||
## human
|
||||
|
||||
- 当前 `human/mock-llm` 是 AI 主链的正式回归入口。
|
||||
- 后续优先补充和维护 `AiRunService -> human` 直达入口 case 与 `human/live` 复杂任务 case。
|
||||
Whitespace-only changes.
@@ -1,141 +0,0 @@
|
||||
# Settings 域测试报告
|
||||
|
||||
## 总览
|
||||
|
||||
### 分析范围
|
||||
|
||||
- raw logs 范围:当前仓库内 `tests/logs/settings/**`
|
||||
- 本次分析窗口:当前仓库内 Settings 域全部 raw runs
|
||||
- 本次纳入分析的 suite:`model`、`workspace`、`web`
|
||||
- 当前未纳入 raw logs 的计划 suite:`vector`
|
||||
|
||||
### 总体结论
|
||||
|
||||
- 历史总数据:`totalRuns=95`、`passedRuns=68`、`failedRuns=27`、`historicalSuccessRate=71.6%`
|
||||
- 最新总数据:`latestCaseCount=17`、`latestPassedCases=17`、`latestFailedCases=0`、`latestSuccessRate=100.0%`
|
||||
- 当前结论:本轮新增并收敛了 `model-page-load-active-config`、`model-delete-config-feedback`、`workspace-page-load-default-selection`、`workspace-add-selection-flow`、`workspace-empty-tree-legacy-hints`、`web-refresh-one-source` 六条正式 case。当前进入 raw logs 的 17 条 Settings 正式 case 在 latest 口径下已全部为 `passed`,覆盖 `model`、`workspace`、`web` 三个 suite 的首批核心用户链路;`vector` suite 仍然没有正式 raw logs,尚未进入当前 report 覆盖面。
|
||||
|
||||
### 下一阶段建议
|
||||
|
||||
- 继续补齐 `model` 中围绕配置列表契约与 `check-llm-config` 变更事件的 backend case
|
||||
- 继续补齐 `workspace` 中围绕扫描契约、加载模式契约、打开路径契约和移除后数据源收敛的 backend case
|
||||
- 继续补齐 `web` 中围绕当前可见列表批量抓取范围和外链打开契约的 backend case
|
||||
- 启动 `vector` suite 的正式 case 实现与 raw logs 闭环
|
||||
|
||||
## model
|
||||
|
||||
### 证据
|
||||
|
||||
- `model-create-edit-form` | `20260327-185017-046` | `passed`
|
||||
- `model-delete-config-feedback` | `20260327-185014-125` | `passed`
|
||||
- `model-enable-switch-current` | `20260327-185021-550` | `passed`
|
||||
- `model-first-config-auto-activate` | `20260327-185019-432` | `passed`
|
||||
- `model-page-load-active-config` | `20260327-185023-169` | `passed`
|
||||
|
||||
### 通过率
|
||||
|
||||
- 历史总数据:`totalRuns=37`、`passedRuns=27`、`failedRuns=10`、`historicalSuccessRate=73.0%`
|
||||
- 最新总数据:`latestCaseCount=5`、`latestPassedCases=5`、`latestFailedCases=0`、`latestSuccessRate=100.0%`
|
||||
|
||||
### 失败分析
|
||||
|
||||
- 历史 failed run 共 `10` 次:
|
||||
- `model-create-edit-form` | `20260327-175759-024` | `failed`
|
||||
- `model-create-edit-form` | `20260327-180058-496` | `failed`
|
||||
- `model-create-edit-form` | `20260327-180335-189` | `failed`
|
||||
- `model-delete-config-feedback` | `20260327-184218-120` | `failed`
|
||||
- `model-delete-config-feedback` | `20260327-184522-625` | `failed`
|
||||
- `model-delete-config-feedback` | `20260327-184705-691` | `failed`
|
||||
- `model-delete-config-feedback` | `20260327-184819-583` | `failed`
|
||||
- `model-enable-switch-current` | `20260327-175834-037` | `failed`
|
||||
- `model-first-config-auto-activate` | `20260327-175906-781` | `failed`
|
||||
- `model-first-config-auto-activate` | `20260327-180132-257` | `failed`
|
||||
- 上述存在历史失败的 4 条 case,其最新 run 均已转为 `passed`,因此当前 suite 没有 latest failed case。
|
||||
|
||||
### 当前评估
|
||||
|
||||
- `model` suite 已覆盖页面首屏初始化、新增/编辑表单、首条配置自动激活、手动切换当前模型、删除成功与删除失败反馈五条核心链路。
|
||||
- 从 latest 口径看,当前 raw logs 已经支持 `SET-MODEL-001`、`SET-MODEL-002`、`SET-MODEL-003`、`SET-MODEL-005` 的首批正式验收闭环。
|
||||
|
||||
### 下一步建议
|
||||
|
||||
- 补齐 `model-config-list-contract`
|
||||
- 补齐 `model-active-config-change-event`
|
||||
|
||||
## workspace
|
||||
|
||||
### 证据
|
||||
|
||||
- `workspace-add-selection-flow` | `20260327-184821-653` | `passed`
|
||||
- `workspace-detail-status-and-error` | `20260327-184848-985` | `passed`
|
||||
- `workspace-empty-tree-legacy-hints` | `20260327-184826-801` | `passed`
|
||||
- `workspace-load-by-mode` | `20260327-184838-245` | `passed`
|
||||
- `workspace-page-load-default-selection` | `20260327-184819-579` | `passed`
|
||||
- `workspace-remove-from-list` | `20260327-184843-817` | `passed`
|
||||
- `workspace-scan-progress-refresh` | `20260327-184831-859` | `passed`
|
||||
|
||||
### 通过率
|
||||
|
||||
- 历史总数据:`totalRuns=36`、`passedRuns=26`、`failedRuns=10`、`historicalSuccessRate=72.2%`
|
||||
- 最新总数据:`latestCaseCount=7`、`latestPassedCases=7`、`latestFailedCases=0`、`latestSuccessRate=100.0%`
|
||||
|
||||
### 失败分析
|
||||
|
||||
- 历史 failed run 共 `10` 次:
|
||||
- `workspace-add-selection-flow` | `20260327-184320-168` | `failed`
|
||||
- `workspace-add-selection-flow` | `20260327-184523-503` | `failed`
|
||||
- `workspace-add-selection-flow` | `20260327-184701-806` | `failed`
|
||||
- `workspace-empty-tree-legacy-hints` | `20260327-184248-489` | `failed`
|
||||
- `workspace-empty-tree-legacy-hints` | `20260327-184703-790` | `failed`
|
||||
- `workspace-load-by-mode` | `20260327-180703-475` | `failed`
|
||||
- `workspace-page-load-default-selection` | `20260327-184212-690` | `failed`
|
||||
- `workspace-page-load-default-selection` | `20260327-184518-328` | `failed`
|
||||
- `workspace-remove-from-list` | `20260327-180743-654` | `failed`
|
||||
- `workspace-scan-progress-refresh` | `20260327-180706-984` | `failed`
|
||||
- 上述存在历史失败的 5 条 case,其最新 run 均已转为 `passed`,因此当前 suite 没有 latest failed case。
|
||||
|
||||
### 当前评估
|
||||
|
||||
- `workspace` suite 已覆盖首屏默认选中、添加选择目录、扫描进度刷新、按模式加载、错误与摘要展示、移除后列表收敛、无文件/旧数据提示七条核心用户链路。
|
||||
- 从 latest 口径看,当前 raw logs 已经支持 `SET-WORKSPACE-001`、`SET-WORKSPACE-002`、`SET-WORKSPACE-003`、`SET-WORKSPACE-004`、`SET-WORKSPACE-005`、`SET-WORKSPACE-006`、`SET-WORKSPACE-007` 的首批正式验收闭环。
|
||||
|
||||
### 下一步建议
|
||||
|
||||
- 补齐 `workspace-scan-contract`、`workspace-load-mode-contract`、`workspace-open-path-contract`、`workspace-remove-source-contract`
|
||||
|
||||
## web
|
||||
|
||||
### 证据
|
||||
|
||||
- `web-add-sources-dialog` | `20260327-184518-331` | `passed`
|
||||
- `web-detail-and-delete` | `20260327-184535-264` | `passed`
|
||||
- `web-page-load-filter-selection` | `20260327-184521-416` | `passed`
|
||||
- `web-refresh-all-summary` | `20260327-184529-702` | `passed`
|
||||
- `web-refresh-one-source` | `20260327-184523-091` | `passed`
|
||||
|
||||
### 通过率
|
||||
|
||||
- 历史总数据:`totalRuns=22`、`passedRuns=15`、`failedRuns=7`、`historicalSuccessRate=68.2%`
|
||||
- 最新总数据:`latestCaseCount=5`、`latestPassedCases=5`、`latestFailedCases=0`、`latestSuccessRate=100.0%`
|
||||
|
||||
### 失败分析
|
||||
|
||||
- 历史 failed run 共 `7` 次:
|
||||
- `web-page-load-filter-selection` | `20260327-181604-617` | `failed`
|
||||
- `web-page-load-filter-selection` | `20260327-181836-057` | `failed`
|
||||
- `web-add-sources-dialog` | `20260327-181608-566` | `failed`
|
||||
- `web-add-sources-dialog` | `20260327-181839-692` | `failed`
|
||||
- `web-refresh-all-summary` | `20260327-181643-331` | `failed`
|
||||
- `web-refresh-all-summary` | `20260327-181913-148` | `failed`
|
||||
- `web-refresh-one-source` | `20260327-184231-184` | `failed`
|
||||
- 上述存在历史失败的 4 条 case,其最新 run 均已转为 `passed`;`web-detail-and-delete` 的全部 raw runs 目前均为 `passed`,因此当前 suite 没有 latest failed case。
|
||||
|
||||
### 当前评估
|
||||
|
||||
- `web` suite 已覆盖首屏与筛选、批量添加入口、单条重新抓取、全部抓取汇总反馈、详情与删除收敛五条主链路。
|
||||
- 从 latest 口径看,当前 raw logs 已经支持 `SET-WEB-001`、`SET-WEB-002`、`SET-WEB-003`、`SET-WEB-004`、`SET-WEB-005` 的首批正式验收闭环。
|
||||
|
||||
### 下一步建议
|
||||
|
||||
- 补齐 `web-refresh-visible-list-contract`
|
||||
- 补齐 `web-open-url-contract`
|
||||
Whitespace-only changes.
@@ -7,8 +7,7 @@ export default defineConfig({
|
||||
'tests/**/*.e2e.test.ts',
|
||||
'tests/harness/**',
|
||||
'tests/fixtures/**',
|
||||
'tests/logs/**',
|
||||
'tests/report/**'
|
||||
'tests/logs/**'
|
||||
],
|
||||
environment: 'node',
|
||||
globals: true,
|
||||
|
||||
@@ -7,8 +7,7 @@ export default defineConfig({
|
||||
'tests/**/*.e2e.test.ts',
|
||||
'tests/harness/**',
|
||||
'tests/fixtures/**',
|
||||
'tests/logs/**',
|
||||
'tests/report/**'
|
||||
'tests/logs/**'
|
||||
],
|
||||
environment: 'node',
|
||||
globals: true,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { defineConfig } from 'vitest/config'
|
||||
export default defineConfig({
|
||||
test: {
|
||||
include: ['tests/**/*.e2e.test.ts', 'tests/**/*.e2e.test.tsx'],
|
||||
exclude: ['tests/harness/**', 'tests/fixtures/**', 'tests/logs/**', 'tests/report/**'],
|
||||
exclude: ['tests/harness/**', 'tests/fixtures/**', 'tests/logs/**'],
|
||||
environment: 'node',
|
||||
globals: true,
|
||||
fileParallelism: false,
|
||||
|
||||
@@ -11,7 +11,7 @@ export default defineConfig({
|
||||
},
|
||||
test: {
|
||||
include: ['tests/renderer/**/*.test.ts', 'tests/renderer/**/*.test.tsx'],
|
||||
exclude: ['tests/harness/**', 'tests/fixtures/**', 'tests/logs/**', 'tests/report/**'],
|
||||
exclude: ['tests/harness/**', 'tests/fixtures/**', 'tests/logs/**'],
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
setupFiles: ['tests/harness/renderer/setup.ts'],
|
||||
|
||||
Reference in new issue
Block a user