init the project
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
testcase-platform/
|
||||
├── .zeekerwatchmen/ # Agent 灵魂:Skill/记忆/人格
|
||||
│ ├── soul/
|
||||
│ │ ├── principles.yaml
|
||||
│ │ └── persona.yaml
|
||||
│ ├── skills/
|
||||
│ │ └── default/ # 内置默认 Skill
|
||||
│ │ ├── skill.yaml
|
||||
│ │ ├── extract_ir_prompt.j2
|
||||
│ │ ├── ir_schema.json
|
||||
│ │ └── gen_cases_prompt.j2
|
||||
│ └── memory/ # 空占位,后续自动生成会话记忆
|
||||
├── server/ # Python FastAPI 后端
|
||||
│ ├── api/
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── routes/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── prd.py # PRD 相关接口
|
||||
│ │ ├── ir.py # IR 相关接口
|
||||
│ │ └── testcase.py # 用例导出接口
|
||||
│ ├── core/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── prompt/
|
||||
│ │ │ └── templates/ # 系统级提示词模板(可被 skill 覆盖)
|
||||
│ │ ├── llm_provider/
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── base.py # 抽象模型客户端
|
||||
│ │ │ ├── router.py # 模型别名路由器
|
||||
│ │ │ └── mock_client.py # Mock 实现
|
||||
│ │ ├── reasoning/
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── graph.py # LangGraph 流程占位
|
||||
│ │ │ └── mock.py
|
||||
│ │ ├── utils/
|
||||
│ │ │ ├── logger.py # 结构化日志
|
||||
│ │ │ ├── diff.py # YAML/JSON 对比
|
||||
│ │ │ └── export_utils.py # 导出格式化
|
||||
│ │ └── personality/
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── loader.py # 从 .zeekerwatchmen 动态加载人格
|
||||
│ ├── services/ # 业务逻辑层
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── prd_manager/
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ └── service.py
|
||||
│ │ ├── ir_engine/
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── generator.py # 调用 LLM 生成 IR(当前 Mock)
|
||||
│ │ │ ├── validator.py # 基于 ir_schema 验证
|
||||
│ │ │ └── diff.py
|
||||
│ │ └── testcase_engine/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── generator.py # 用例生成
|
||||
│ │ └── exporter.py # 导出 YAML/CSV/XMind
|
||||
│ ├── main.py # FastAPI 入口
|
||||
│ ├── config.py # 配置管理(模型列表、路径等)
|
||||
│ └── requirements.txt
|
||||
├── web/ # Next.js 前端
|
||||
│ ├── src/
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── Layout.tsx
|
||||
│ │ │ ├── UploadZone.tsx
|
||||
│ │ │ ├── IrWorkspace.tsx # 双栏 IR 编辑器 + 思维导图预览
|
||||
│ │ │ ├── TestCaseTable.tsx
|
||||
│ │ │ └── ExportPanel.tsx
|
||||
│ │ ├── pages/
|
||||
│ │ │ ├── index.tsx # 主页(上传/选择 skill)
|
||||
│ │ │ ├── ir-confirm.tsx # IR 确认页
|
||||
│ │ │ └── cases.tsx # 用例预览导出页
|
||||
│ │ ├── hooks/ # 自定义 hooks (usePrd, useIr, useTestcases)
|
||||
│ │ └── lib/
|
||||
│ │ ├── api.ts # 后端 API 封装
|
||||
│ │ └── types.ts # 前端类型定义
|
||||
│ ├── package.json
|
||||
│ ├── tsconfig.json
|
||||
│ ├── next.config.js
|
||||
│ └── tailwind.config.js
|
||||
├── docs/ # 文档
|
||||
│ ├── PRD.md
|
||||
│ └── ARCHITECTURE.md
|
||||
└── README.md
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
# 产品需求文档:ZeekerWatchman (测试用例智能管理平台)
|
||||
|
||||
| 文档版本 | 修订日期 | 修订人 | 修订说明 |
|
||||
| -------- | ---------- | ------ | -------------------------------------- |
|
||||
| V0.1 | 2026-05-22 | - | 初稿,整合核心架构与用户流程 |
|
||||
| V0.2 | 2026-05-22 | - | 细化 IR 规范与 Skill 接口,补充非功能需求 |
|
||||
| V1.0 | 2026-05-22 | - | P2-P4 完成,更新实现状态、架构分层、3 阶段流水线、Chat Panel |
|
||||
|
||||
---
|
||||
|
||||
## 1. 产品概述与愿景
|
||||
|
||||
### 1.1 产品愿景
|
||||
将"产品需求文档(PRD)"到"可执行测试用例"的转换过程,从依赖人工经验的黑盒,升级为**可解释、可迭代、可插拔的知识工程系统**。
|
||||
|
||||
### 1.2 核心价值主张
|
||||
- **输入**:非结构化的 PRD 文本(.md, .txt, .docx, .pdf)
|
||||
- **处理**:AI 驱动的 3 阶段流水线:语义索引 → 逐单元 IR 提取 → 合并审计
|
||||
- **输出**:多格式测试用例(YAML / CSV / JSON),含完整审计报告
|
||||
- **差异化**:Agent 人格化、Skill 热插拔、Chat Panel 交互式编辑
|
||||
|
||||
---
|
||||
|
||||
## 2. 用户与核心场景
|
||||
|
||||
### 2.1 目标用户画像
|
||||
- **测试架构师/资深 QA**:定义测试策略,设计 Skill 包,审核 IR 与审计报告
|
||||
- **测试工程师**:上传 PRD,执行生成,通过 Chat Panel 微调并导出用例
|
||||
- **开发工程师**:查看 YAML 格式用例,集成到 CI/CD
|
||||
|
||||
### 2.2 核心用户故事
|
||||
- **作为**测试工程师,**我希望**上传 PRD 后自动生成 IR 并在思维导图中可视化确认
|
||||
- **作为**测试架构师,**我希望**将团队方法论打包成 Skill,一键切换
|
||||
- **作为**测试工程师,**我希望**通过右侧 Chat Panel 用自然语言修改 IR 内容和用例
|
||||
|
||||
---
|
||||
|
||||
## 3. 系统架构总览(实现后)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ .zeekerwatchmen/ (Agent 灵魂) │
|
||||
│ ├── skills/{default,ecommerce}/ (热插拔 Skill) │
|
||||
│ ├── memory/ (会话记忆) │
|
||||
│ └── soul/ (人格/原则) │
|
||||
└──────────────────────────────────────────────────┘
|
||||
↓ 动态注入
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ Core (底座层 — 仅基础设施) │
|
||||
│ ├── llm_provider/ (DeepSeek/Qwen 客户端+路由) │
|
||||
│ ├── prompt/templates/ (宽泛框架级 prompt) │
|
||||
│ ├── personality/ (动态人格装配) │
|
||||
│ ├── reasoning/ (ReAct/LangGraph 编排) │
|
||||
│ └── utils/ (Logger, Diff, Export) │
|
||||
└──────────────────────────────────────────────────┘
|
||||
↓ 能力支撑
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ Services (业务层 — 领域逻辑 + 业务 prompt) │
|
||||
│ ├── prompts/ (ir_step1/2 业务 prompt) │
|
||||
│ ├── prd_manager/ (Word/PDF 解析+图片分析) │
|
||||
│ ├── ir_engine/ (3 阶段流水线+验证+Diff) │
|
||||
│ ├── testcase_engine/ (用例生成+导出) │
|
||||
│ └── skill_manager/ (Skill 扫描+热加载) │
|
||||
└──────────────────────────────────────────────────┘
|
||||
↓ API 服务
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ Web UI (Next.js 左右分栏布局) │
|
||||
│ ┌──────────────────────┬────────────────────┐ │
|
||||
│ │ 左侧:主工作区 │ 右侧:AI Chat │ │
|
||||
│ │ 上传→IR可视化→用例 │ 自然语言交互 │ │
|
||||
│ │ 思维导图+审计报告 │ 操作左侧内容 │ │
|
||||
│ └──────────────────────┴────────────────────┘ │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.1 分层原则
|
||||
- **core/**(底座层):只有基础设施,不含业务逻辑。更新底座只改 core,不改 services
|
||||
- **services/prompts/**(业务 prompt):所有领域相关的 prompt 模板放在此处
|
||||
- **services/**(业务层):领域逻辑调用 core 的 LLM 接口,引用自己的 prompt
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心功能详述(已实现)
|
||||
|
||||
### 4.1 Skill 热插拔体系 (`.zeekerwatchmen`)
|
||||
- `soul/principles.yaml`:5 条不可违背准则
|
||||
- `soul/persona.yaml`:Agent 人格定义("Zeeker")
|
||||
- `skills/{name}/`:每个 Skill 独立目录,含 skill.yaml + ir_schema.json + extract/gen_cases_prompt.j2
|
||||
- `skills/default/`:通用测试设计
|
||||
- `skills/ecommerce/`:电商后台(含 business_rules、data_consistency 等电商特有字段)
|
||||
- `GET /api/skills` 自动扫描,`POST /api/skills/reload` 热重载
|
||||
|
||||
### 4.2 PRD 解析 (`prd_manager`)
|
||||
- **WordParser**(`services/prd_manager/word_parser.py`):直接遍历 document.body XML
|
||||
- 类型化 blocks:`{type: "para"|"table", index, text/headers/rows}`
|
||||
- 表格列结构:`columns[{name, row, col, text}]`
|
||||
- 表头检测启发式:首行所有单元格 < 20 字符则视为表头
|
||||
- `[[IMAGE:rid]]` 标记嵌入文本
|
||||
- image_sources 含精确定位:`{section, table, row, column, name}`
|
||||
- **ImageParser**(`services/prd_manager/image_parser.py`):Qwen VL 分析图片(类型+描述)
|
||||
- 支持格式:.md / .txt / .docx / .pdf
|
||||
- Markdown 解析:`#` 标题 → sections,`|` 表格 → table blocks
|
||||
|
||||
### 4.3 3 阶段 IR 生成流水线 (核心升级)
|
||||
|
||||
```
|
||||
PRD parsed JSON ──→ Stage 1 ──→ Stage 2 ──→ Stage 3 ──→ ir_final.json
|
||||
语义索引 逐单元提取 合并审计 + audit_report.md
|
||||
```
|
||||
|
||||
#### Stage 1:宏观语义索引
|
||||
- 输入:完整 parsed PRD JSON(sections + image_analysis)
|
||||
- ``format_document_for_prompt()``:渲染为 sections/blocks/tables/images 可读文本
|
||||
- Prompt 模板:`services/prompts/ir_step1_semantic_index.txt`
|
||||
- 输出:`{feature_name, concepts[], function_units[{unit_id, name, description, sources[]}]}`
|
||||
- System prompt: "精确的 JSON 输出引擎" + 健壮 `extract_json_from_response()` + 3 次重试
|
||||
- 失败降级:`_fallback_semantic_index()` 从段落/表格自动提取
|
||||
|
||||
#### Stage 2:逐功能单元 IR 提取
|
||||
- 输入:semantic_index + parsed PRD
|
||||
- `build_context_package()`:为每个 function_unit 构建精准上下文包(texts + tables + images + conflicts)
|
||||
- Prompt 模板:`services/prompts/ir_step2_extraction.txt`
|
||||
- IR Schema:``trigger{operator, conditions[{signal,operator,value,unit}]}`` + ``actions[{type,description,content}]`` + ``precondition``
|
||||
- `ThreadPoolExecutor(max_workers=3)` 并行调用
|
||||
- 输出:`[{unit_id, rules[{description, trigger, actions, sources, priority}]}]`
|
||||
|
||||
#### Stage 3:确定性合并与审计
|
||||
- ``rule_signature(rule)``:SHA256(trigger.conditions + actions) 去重
|
||||
- ``merge_rules()``:去重,合并 sources
|
||||
- ``assign_rule_ids()``:格式 `{FEATURE}-{TYPE}-FG-{NN}`(SYS/UI/SDK)
|
||||
- **_generate_audit()**:章节覆盖、图片引用覆盖、优先级分布
|
||||
- **_format_audit_report()**:Markdown 格式审计报告
|
||||
|
||||
### 4.4 Chat Panel 交互式编辑
|
||||
- 布局:左侧 380px 固定宽度 ChatPanel + 右侧 flex-1 主内容
|
||||
- 状态桥:Zustand store (`web/src/lib/store.ts`) 在页面和 ChatPanel 间共享 PRD/IR/Testcases
|
||||
- 后端 API:`POST /api/chat` — 接收 context + history,返回 reply + actions
|
||||
- Action 机制:
|
||||
- `{"action": "update_ir", "content": "..."}` — 更新左侧 IR 编辑器
|
||||
- `{"action": "generate_cases", "ir_id": "..."}` — 跳转生成用例
|
||||
- `{"action": "navigate", "page": "..."}` — 页面跳转
|
||||
|
||||
### 4.5 思维导图可视化 (`web/src/components/MindMap.tsx`)
|
||||
- 双格式兼容:YAML IR(features 树)和 JSON pipeline IR(rules 树)
|
||||
- SVG 递归渲染:节点矩形 + 贝塞尔曲线连接 + 优先级颜色标签
|
||||
- Hover 提示:鼠标悬停显示完整文本
|
||||
|
||||
### 4.6 测试用例生成与导出
|
||||
- **规则→用例转换**(`_rules_to_cases()`):trigger.conditions → Given 子句,actions → Then 子句
|
||||
- 导出格式:YAML / CSV / JSON,`GET /api/testcase/export/{format}`
|
||||
|
||||
### 4.7 LLM 模型配置
|
||||
- 文本模型:DeepSeek (`deepseek-chat` / `deepseek-v4-pro`),base_url: `https://api.deepseek.com`
|
||||
- 图片模型:Qwen VL (`qwen3-vl-plus`),base_url: `https://dashscope.aliyuncs.com/compatible-mode/v1`
|
||||
- 无 API Key 时自动降级为 Mock 模式
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术栈
|
||||
|
||||
| 层 | 技术 |
|
||||
|---|------|
|
||||
| 后端框架 | Python FastAPI + Uvicorn |
|
||||
| LLM 客户端 | OpenAI SDK(兼容 DeepSeek + Qwen DashScope) |
|
||||
| LLM 模型 | DeepSeek (文本) + Qwen VL (图片) |
|
||||
| 前端框架 | Next.js 15 + React 19 (Pages Router) |
|
||||
| 样式 | Tailwind CSS 3.4 |
|
||||
| 编辑器 | Monaco Editor (`@monaco-editor/react`) |
|
||||
| 状态管理 | Zustand 5 |
|
||||
| 文档解析 | python-docx + PyPDF2 |
|
||||
| 提示模板 | Jinja2 |
|
||||
| 校验 | jsonschema + PyYAML |
|
||||
|
||||
---
|
||||
|
||||
## 6. 里程碑与推进路径
|
||||
|
||||
| 阶段 | 核心任务 | 状态 |
|
||||
| ---- | -------- | ---- |
|
||||
| P1 | PRD 定稿与架构评审 | ✅ 完成 |
|
||||
| P2 | 代码框架搭建(脚手架、空壳运行、接口占位) | ✅ 完成 |
|
||||
| P3 | 核心链条实现(DeepSeek+Qwen,PRD→IR→用例全流程) | ✅ 完成 |
|
||||
| P4 | 热插拔改造(Skill 扫描/加载,电商 Skill 验证,左右分栏 Chat Panel) | ✅ 完成 |
|
||||
| P5 | 体验打磨(动画、错误处理、性能优化、更多 Skill) | 进行中 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 项目结构(实现后)
|
||||
|
||||
```
|
||||
zeekerWatchmen/
|
||||
├── .zeekerwatchmen/ # Agent 灵魂:Skill/记忆/人格
|
||||
│ ├── soul/ # principles.yaml + persona.yaml
|
||||
│ ├── skills/ # default/ + ecommerce/
|
||||
│ └── memory/ # 会话记忆
|
||||
├── server/ # Python FastAPI 后端
|
||||
│ ├── api/routes/ # prd.py, ir.py, testcase.py, skills.py, chat.py
|
||||
│ ├── core/ # 底座层(仅基础设施)
|
||||
│ │ ├── llm_provider/ # base.py, router.py, mock_client.py
|
||||
│ │ ├── prompt/templates/ # 宽泛框架级 prompt
|
||||
│ │ ├── personality/ # loader.py (动态人格装配)
|
||||
│ │ ├── reasoning/ # graph.py (LangGraph 占位)
|
||||
│ │ └── utils/ # logger.py, diff.py, export_utils.py
|
||||
│ ├── services/ # 业务层
|
||||
│ │ ├── prompts/ # 业务 prompt 模板
|
||||
│ │ │ ├── ir_step1_semantic_index.txt
|
||||
│ │ │ └── ir_step2_extraction.txt
|
||||
│ │ ├── prd_manager/ # WordParser + ImageParser + service
|
||||
│ │ ├── ir_engine/ # pipeline.py + generator + validator + diff
|
||||
│ │ ├── testcase_engine/ # generator.py + exporter.py
|
||||
│ │ └── skill_manager/ # service.py (Skill 扫描/热加载)
|
||||
│ ├── main.py # FastAPI 入口
|
||||
│ ├── config.py # 配置管理 (pydantic-settings + .env)
|
||||
│ └── requirements.txt
|
||||
├── web/ # Next.js 前端
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # Layout, UploadZone, IrWorkspace, MindMap,
|
||||
│ │ │ # TestCaseTable, ExportPanel, ChatPanel
|
||||
│ │ ├── pages/ # index.tsx, ir-confirm.tsx, cases.tsx
|
||||
│ │ ├── hooks/ # usePrd.ts, useIr.ts, useTestcases.ts
|
||||
│ │ ├── lib/ # api.ts, types.ts, store.ts
|
||||
│ │ └── styles/ # globals.css
|
||||
│ ├── package.json, tsconfig.json, next.config.js, tailwind.config.js
|
||||
├── docs/ # PRD.md, ARCHITECTURE.md
|
||||
├── start.sh # 一键启动脚本
|
||||
├── .env # 环境变量 (API Keys, 端口, 模型配置)
|
||||
├── .gitignore
|
||||
└── README.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 一键启动
|
||||
|
||||
```bash
|
||||
# Linux/WSL:
|
||||
chmod +x start.sh && ./start.sh
|
||||
|
||||
# 访问 http://localhost:3000
|
||||
```
|
||||
|
||||
start.sh 自动完成:依赖安装检查 → 后端启动 (8765) → 前端启动 (3000) → 输出访问地址。
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://zeekerwatchman/schemas/ir.json",
|
||||
"title": "IR (Intermediate Representation) Schema",
|
||||
"description": "3-stage pipeline output: feature analysis rules with trigger/action semantics",
|
||||
|
||||
"type": "object",
|
||||
"required": ["feature", "feature_id", "rules"],
|
||||
"properties": {
|
||||
"feature": {
|
||||
"type": "string",
|
||||
"description": "功能名称,从 PRD 中提取"
|
||||
},
|
||||
"feature_id": {
|
||||
"type": "string",
|
||||
"description": "功能缩写,用于生成 rule_id 前缀,如 PRD, AUTH, ORDER",
|
||||
"pattern": "^[A-Z]{2,8}$"
|
||||
},
|
||||
"rule_count": {
|
||||
"type": "integer",
|
||||
"description": "规则总数"
|
||||
},
|
||||
"generated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"rules": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/definitions/IRRule"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"definitions": {
|
||||
"IRRule": {
|
||||
"type": "object",
|
||||
"required": ["rule_id", "description", "priority"],
|
||||
"properties": {
|
||||
"rule_id": {
|
||||
"type": "string",
|
||||
"description": "唯一标识。格式: IR-{feature_id}-{section}-{seq},如 IR-PRD-4.2.1-001",
|
||||
"pattern": "^IR-[A-Z]{2,8}-[0-9.]+-[0-9]{3}$",
|
||||
"examples": ["IR-PRD-4.2.1-001", "IR-AUTH-2.1-001"]
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "完整的中文自然语言描述,包含前置条件、触发条件和所有动作",
|
||||
"minLength": 10
|
||||
},
|
||||
"priority": {
|
||||
"type": "string",
|
||||
"enum": ["P0", "P1", "P2"],
|
||||
"description": "P0=核心安全规则, P1=重要规则, P2=边界情况"
|
||||
},
|
||||
"sources": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/Source" },
|
||||
"description": "规则的数据来源锚点"
|
||||
},
|
||||
"precondition": {
|
||||
"type": "object",
|
||||
"description": "规则生效的前置状态条件。可以是空对象",
|
||||
"properties": {
|
||||
"switch": { "type": "string" },
|
||||
"app_type": { "type": "string", "description": "如: 系统限制, SDK限制, 其他应用" },
|
||||
"app_state": { "type": "string", "description": "如: 前台, 后台" }
|
||||
}
|
||||
},
|
||||
"trigger": {
|
||||
"type": "object",
|
||||
"required": ["operator", "conditions"],
|
||||
"properties": {
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"enum": ["AND", "OR"],
|
||||
"description": "多个条件的组合方式"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#/definitions/TriggerCondition" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#/definitions/Action" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"TriggerCondition": {
|
||||
"type": "object",
|
||||
"required": ["signal", "operator", "value"],
|
||||
"properties": {
|
||||
"signal": {
|
||||
"type": "string",
|
||||
"description": "触发信号名,如 车速, 档位, 文件格式",
|
||||
"examples": ["车速", "文件大小", "应用请求启动"]
|
||||
},
|
||||
"operator": {
|
||||
"type": "string",
|
||||
"enum": [">=", ">", "<=", "<", "==", "!=", "in", "not_in", "exists"],
|
||||
"description": "比较运算符"
|
||||
},
|
||||
"value": {
|
||||
"description": "比较值,可以是数字、字符串或数组"
|
||||
},
|
||||
"unit": {
|
||||
"type": "string",
|
||||
"description": "数值单位,如 km/h, 秒, MB",
|
||||
"examples": ["km/h", "秒", "MB"]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"Action": {
|
||||
"type": "object",
|
||||
"required": ["type", "description"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["system", "user_interaction"],
|
||||
"description": "system=系统自动行为, user_interaction=用户可见交互"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "动作描述"
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"description": "用户可见内容(仅 user_interaction 类型需要),如 Toast 文案"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"Source": {
|
||||
"type": "object",
|
||||
"required": ["type"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["para", "table", "image", "logic_tree"],
|
||||
"description": "来源类型"
|
||||
},
|
||||
"section": { "type": "string", "description": "章节号" },
|
||||
"row": { "type": "integer", "description": "表格行号" },
|
||||
"text_snippet": { "type": "string", "description": "前200字关键文字" },
|
||||
"image_id": { "type": "string", "description": "图片 rId" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://zeekerwatchman/schemas/testcase.json",
|
||||
"title": "Test Case Schema",
|
||||
"description": "从 IR 规则生成的测试用例格式",
|
||||
|
||||
"type": "object",
|
||||
"required": ["testcases"],
|
||||
"properties": {
|
||||
"testcases": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#/definitions/TestCase" }
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total": { "type": "integer" },
|
||||
"ir_id": { "type": "string", "description": "来源 IR ID" },
|
||||
"generated_at": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"definitions": {
|
||||
"TestCase": {
|
||||
"type": "object",
|
||||
"required": ["id", "module", "case_title", "steps", "expected_result", "priority"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "唯一标识。格式: TC-{feature_id}-{seq},如 TC-PRD-001",
|
||||
"pattern": "^TC-[A-Z]{2,8}-[0-9]{3}$",
|
||||
"examples": ["TC-PRD-001", "TC-AUTH-002"]
|
||||
},
|
||||
"module": {
|
||||
"type": "string",
|
||||
"description": "所属模块名"
|
||||
},
|
||||
"feature": {
|
||||
"type": "string",
|
||||
"description": "功能点名称"
|
||||
},
|
||||
"case_title": {
|
||||
"type": "string",
|
||||
"description": "用例标题,格式: 正向/异常/边界-简短描述",
|
||||
"examples": ["正向-上传md格式PRD成功", "异常-上传不支持的文件格式"]
|
||||
},
|
||||
"preconditions": {
|
||||
"type": "string",
|
||||
"description": "前置条件"
|
||||
},
|
||||
"steps": {
|
||||
"type": "string",
|
||||
"description": "测试步骤,Given-When-Then 格式,换行分隔",
|
||||
"examples": ["Given 用户已登录\nWhen 上传.md文件\nThen 成功解析"]
|
||||
},
|
||||
"expected_result": {
|
||||
"type": "string",
|
||||
"description": "预期结果,必须量化可验证"
|
||||
},
|
||||
"priority": {
|
||||
"type": "string",
|
||||
"enum": ["P0", "P1", "P2"],
|
||||
"description": "P0=冒烟/核心, P1=重要, P2=补充"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "标签: 正向, 异常, 边界, 并发, 安全 等",
|
||||
"examples": [["正向", "冒烟"], ["异常", "安全"]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user