Remove test report flow and rename log contract

This commit is contained in:
hy committed 2026-04-10 10:07:29 +08:00
1 parent 117ce68e71
commit 8bafa24ca0
23 files changed
+107 -384

No files matched your search

+1 -1
View File
@@ -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`
+2 -2
View File
@@ -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. 文档目录规则
+1 -1
View File
@@ -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`
+1 -1
View File
@@ -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 设计
+1 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 => {
+1 -1
View File
@@ -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')
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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')
+1 -1
View File
@@ -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'
-23
View File
@@ -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。
View File
Whitespace-only changes.
-141
View File
@@ -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`
View File
Whitespace-only changes.
+1 -2
View File
@@ -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,
+1 -2
View File
@@ -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,
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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'],