@zhouhao4221/devflow-skills 0.3.6 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/package.json +1 -1
  2. package/plugins/diag/templates/services.yaml.template +31 -0
  3. package/plugins/req/skills/branch/SKILL.md +48 -377
  4. package/plugins/req/skills/dev/SKILL.md +1 -1
  5. package/plugins/req/skills/dev-guide/SKILL.md +74 -399
  6. package/plugins/req/skills/do/SKILL.md +1 -1
  7. package/plugins/req/skills/done/SKILL.md +2 -2
  8. package/plugins/req/skills/edit/SKILL.md +1 -1
  9. package/plugins/req/skills/fix/SKILL.md +1 -1
  10. package/plugins/req/skills/init/SKILL.md +66 -430
  11. package/plugins/req/skills/issue/SKILL.md +1 -1
  12. package/plugins/req/skills/migrate/SKILL.md +1 -1
  13. package/plugins/req/skills/natural-language-dispatcher/SKILL.md +78 -438
  14. package/plugins/req/skills/new/SKILL.md +1 -1
  15. package/plugins/req/skills/pr/SKILL.md +1 -1
  16. package/plugins/req/skills/prd/SKILL.md +1 -1
  17. package/plugins/req/skills/prd-edit/SKILL.md +1 -1
  18. package/plugins/req/skills/release/SKILL.md +1 -1
  19. package/plugins/req/skills/review/SKILL.md +1 -1
  20. package/plugins/req/skills/review-pr/SKILL.md +74 -601
  21. package/plugins/req/skills/test/SKILL.md +41 -355
  22. package/plugins/req/skills/test_new/SKILL.md +36 -356
  23. package/plugins/req/skills/test_regression/SKILL.md +1 -1
  24. package/plugins/req/skills/update-template/SKILL.md +1 -1
  25. package/plugins/req/skills/use/SKILL.md +1 -1
  26. package/plugins/req/templates/claude-md-snippets/frontend-react.md +48 -0
  27. package/plugins/req/templates/claude-md-snippets/generic.md +43 -0
  28. package/plugins/req/templates/claude-md-snippets/go-backend.md +47 -0
  29. package/plugins/req/templates/claude-md-snippets/java-backend.md +46 -0
  30. package/plugins/req/templates/docker-compose.test.yml +84 -0
  31. package/plugins/req/templates/index-template.md +60 -0
  32. package/plugins/req/templates/module-template.md +79 -0
  33. package/plugins/req/templates/prd-template.md +338 -0
  34. package/plugins/req/templates/quick-template.md +71 -0
  35. package/plugins/req/templates/release-prompt-template.md +51 -0
  36. package/plugins/req/templates/requirement-template.md +256 -0
  37. package/plugins/req/templates/scripts/test-env.sh +226 -0
  38. package/plugins/req/templates/tests/e2e/playwright.config.ts +86 -0
  39. package/plugins/uat/templates/flow-template.md +116 -0
  40. package/plugins/uat/templates/testid-convention.md +42 -0
@@ -0,0 +1,256 @@
1
+ # REQ-XXX: 需求标题
2
+
3
+ ## 元信息
4
+
5
+ | 属性 | 值 |
6
+ |-----|-----|
7
+ | 编号 | REQ-XXX |
8
+ | 类型 | 后端 / 前端 / 全栈 |
9
+ | 状态 | 草稿 |
10
+ | 模块 | - |
11
+ | 优先级 | P2 |
12
+ | 创建日期 | YYYY-MM-DD |
13
+ | 负责人 | - |
14
+ | branch | - |
15
+ | issue | - |
16
+
17
+ ## 生命周期
18
+
19
+ <!-- 需求状态流转:草稿 → 待评审 → 评审通过 → 开发中 → 测试中 → 已完成 -->
20
+
21
+ - [ ] 草稿(编写中)
22
+ - [ ] 待评审
23
+ - [ ] 评审通过
24
+ - [ ] 开发中
25
+ - [ ] 测试中
26
+ - [ ] 已完成
27
+
28
+ ---
29
+
30
+ ## 一、需求描述
31
+
32
+ ### 1.1 背景
33
+
34
+ 简要说明需求产生的背景...
35
+
36
+ ### 1.2 目标
37
+
38
+ - **功能目标**:本需求要实现的能力...
39
+ - **效果目标**:上线后的预期效果(尽量量化,如提效 XX%、减少 XX 次人工操作)...
40
+
41
+ ### 1.3 客户场景
42
+
43
+ > 记录客户提出的原始业务场景和诉求
44
+
45
+ - **场景1**:客户描述...
46
+ - **场景2**:客户描述...
47
+
48
+ ### 1.4 价值
49
+
50
+ 实现后带来的业务价值...
51
+
52
+ ### 1.5 范围与边界
53
+
54
+ > 明确本期做什么、不做什么,防止范围蔓延
55
+
56
+ - **本期包含**:...
57
+ - **本期不做**:相关但不纳入当前需求的场景,列出以便对齐预期...
58
+
59
+ ### 1.6 干系人
60
+
61
+ > 除了提出方,还有哪些人会因此变化受影响
62
+
63
+ | 角色 | 关注点 | 备注 |
64
+ |------|-------|------|
65
+ | 提出方 | - | - |
66
+ | - | - | - |
67
+
68
+ ---
69
+
70
+ ## 二、功能清单
71
+
72
+ > 列出所有功能点,开发完成后勾选
73
+
74
+ - [ ] **功能点1**:描述...
75
+ - [ ] **功能点2**:描述...
76
+ - [ ] **功能点3**:描述...
77
+
78
+ ---
79
+
80
+ ## 三、业务规则
81
+
82
+ | 类型 | 规则 | 说明 |
83
+ |------|-----|------|
84
+ | 数据校验 | 规则1 | 详细说明 |
85
+ | 状态转换 | 规则2 | 详细说明 |
86
+ | 权限控制 | 规则3 | 详细说明 |
87
+ | 非功能约束 | 规则4 | 性能 / 安全 / 兼容性等约束说明 |
88
+
89
+ ---
90
+
91
+ ## 四、使用场景
92
+
93
+ ### 场景1:XXX
94
+
95
+ - **角色**:XXX
96
+ - **前置条件**:XXX
97
+ - **基本流程**:
98
+ 1. 用户操作... → 系统响应...
99
+ 2. 用户操作... → 系统响应...
100
+ 3. 用户操作... → 系统响应...
101
+ - **异常流程**:
102
+ - 条件A → 预期结果
103
+ - 条件B → 预期结果
104
+
105
+ ### 场景2:XXX
106
+
107
+ - **角色**:XXX
108
+ - **前置条件**:XXX
109
+ - **基本流程**:
110
+ 1. ...
111
+ - **异常流程**:
112
+ - ...
113
+
114
+ ---
115
+
116
+ ## 五、数据与交互
117
+
118
+ > 根据需求类型填写不同内容:
119
+ > - **后端 / 全栈**:描述需要的接口能力和业务语义,技术方案在 `/req:dev` 阶段生成
120
+ > - **前端**:描述页面交互逻辑,`/req:dev` 阶段自动匹配后端接口
121
+
122
+ ### 后端/全栈:接口需求
123
+
124
+ | 能力 | 输入 | 输出 | 说明 |
125
+ |------|------|------|------|
126
+ | 创建XXX | 业务字段描述 | 创建结果 | 业务语义说明 |
127
+ | 查询XXX | 筛选条件描述 | 列表/详情 | 业务语义说明 |
128
+
129
+ ### 前端:交互逻辑
130
+
131
+ > 按页面/模块描述用户操作和数据流转,不指定具体接口
132
+
133
+ **页面:XXX**
134
+
135
+ | 操作/区域 | 用户行为 | 数据需求 | 交互反馈 |
136
+ |----------|---------|---------|---------|
137
+ | 列表区域 | 进入页面 | 分页数据(字段1、字段2...) | 加载中 → 展示列表 / 空状态 |
138
+ | 搜索 | 输入关键词、选择筛选条件 | 按条件过滤列表 | 实时刷新列表 |
139
+ | 操作按钮 | 点击审核/删除/导出 | 提交操作结果 | 成功提示 / 失败原因 |
140
+
141
+ ---
142
+
143
+ ## 六、测试要点
144
+
145
+ ### 6.1 技术测试
146
+
147
+ - [ ] 测试点1:描述测试场景和预期结果
148
+ - [ ] 测试点2:描述测试场景和预期结果
149
+
150
+ ### 6.2 验收标准
151
+
152
+ > 产品/业务方验收时的确认项,描述可观测的业务结果
153
+
154
+ - [ ] 验收项1:在什么页面/入口,执行什么操作,能看到什么结果
155
+ - [ ] 验收项2:...
156
+
157
+ ### 6.3 手动测试用例
158
+
159
+ > 执行 `/req:test_new REQ-XXX --type=manual` 生成,供测试人员逐条复测
160
+
161
+ _待生成_
162
+
163
+ ---
164
+
165
+ ## 七、图示(可选)
166
+
167
+ > 用 Mermaid 绘制,GitHub/Gitea 原生渲染。主题建议统一用 `neutral`(打印友好、明暗模式兼容)。
168
+ > 无图可删除本节,按需保留下方子节。
169
+
170
+ ### 7.1 流程图(业务流程、用户操作路径)
171
+
172
+ ```mermaid
173
+ %%{init: {'theme':'neutral'}}%%
174
+ flowchart LR
175
+ A[开始] --> B{判断}
176
+ B -->|条件1| C[操作A]
177
+ B -->|条件2| D[操作B]
178
+ C --> E[结束]
179
+ D --> E
180
+ ```
181
+
182
+ ### 7.2 时序图(接口调用链、前后端交互)
183
+
184
+ ```mermaid
185
+ %%{init: {'theme':'neutral'}}%%
186
+ sequenceDiagram
187
+ participant U as 用户
188
+ participant F as 前端
189
+ participant B as 后端
190
+ U->>F: 触发操作
191
+ F->>B: 调用接口
192
+ B-->>F: 返回结果
193
+ F-->>U: 展示
194
+ ```
195
+
196
+ ### 7.3 ER 图 / 状态图(按需)
197
+
198
+ ```mermaid
199
+ %%{init: {'theme':'neutral'}}%%
200
+ stateDiagram-v2
201
+ [*] --> 草稿
202
+ 草稿 --> 待审核: 提交
203
+ 待审核 --> 已通过: 审批
204
+ 待审核 --> 已驳回: 驳回
205
+ 已通过 --> [*]
206
+ ```
207
+
208
+ ---
209
+
210
+ ## 八、评审记录
211
+
212
+ | 日期 | 评审人 | 结论 | 意见 |
213
+ |-----|-------|------|------|
214
+ | - | - | - | - |
215
+
216
+ ---
217
+
218
+ ## 九、变更记录
219
+
220
+ | 日期 | 变更内容 | 影响范围 |
221
+ |-----|---------|---------|
222
+ | YYYY-MM-DD | 初始版本 | - |
223
+
224
+ ---
225
+
226
+ ## 十、关联信息
227
+
228
+ - **关联需求**:REQ-XXX(前端/后端对应需求,dev 阶段自动读取其 API 设计进行接口映射)
229
+ - **相关文档**:链接
230
+ - **假设**:相信为真但未验证的前提,一旦不成立需重新评估方案(如"假设第三方接口可用率 > 99.9%"、"假设用户规模不超过 10 万")
231
+ - **外部依赖**:依赖的第三方接口 / 其他团队交付 / 基础设施等,标注预计就绪时间
232
+ - **风险项**:技术风险(方案不确定)/ 数据风险(存量迁移)/ 时间风险(依赖外部排期)
233
+
234
+ ---
235
+
236
+ ## 十一、实现方案
237
+
238
+ > 本章节在 `/req:dev` 阶段由 AI 分析代码后自动生成,创建需求时无需填写。
239
+
240
+ ### 11.1 数据模型
241
+
242
+ _开发阶段填充_
243
+
244
+ ### 11.2 API 设计
245
+
246
+ > 基于第五章接口需求,结合项目代码和 CLAUDE.md API 风格,生成具体技术方案
247
+
248
+ _开发阶段填充_
249
+
250
+ ### 11.3 文件改动清单
251
+
252
+ _开发阶段填充_
253
+
254
+ ### 11.4 实现步骤
255
+
256
+ _开发阶段填充_
@@ -0,0 +1,226 @@
1
+ #!/bin/bash
2
+
3
+ # 测试环境启动脚本模板
4
+ # 复制到项目 scripts/ 目录并根据需要修改
5
+
6
+ set -e
7
+
8
+ # 颜色定义
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m' # No Color
13
+
14
+ # 配置
15
+ DOCKER_COMPOSE_FILE="docker-compose.test.yml"
16
+ BACKEND_PORT=8080
17
+ FRONTEND_PORT=3000
18
+ MYSQL_PORT=3307
19
+ REDIS_PORT=6380
20
+
21
+ # 日志函数
22
+ log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
23
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
24
+ log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
25
+
26
+ # 等待端口就绪
27
+ wait_for_port() {
28
+ local host=$1
29
+ local port=$2
30
+ local timeout=${3:-30}
31
+ local counter=0
32
+
33
+ while ! nc -z "$host" "$port" 2>/dev/null; do
34
+ counter=$((counter + 1))
35
+ if [ $counter -ge $timeout ]; then
36
+ log_error "等待 $host:$port 超时"
37
+ return 1
38
+ fi
39
+ sleep 1
40
+ done
41
+ return 0
42
+ }
43
+
44
+ # 启动 Docker 容器
45
+ start_docker() {
46
+ log_info "启动 Docker 容器..."
47
+ docker-compose -f "$DOCKER_COMPOSE_FILE" up -d
48
+
49
+ log_info "等待 MySQL 就绪..."
50
+ wait_for_port localhost $MYSQL_PORT 60
51
+ log_info "MySQL 已就绪"
52
+
53
+ log_info "等待 Redis 就绪..."
54
+ wait_for_port localhost $REDIS_PORT 30
55
+ log_info "Redis 已就绪"
56
+ }
57
+
58
+ # 启动后端服务
59
+ start_backend() {
60
+ log_info "启动后端服务..."
61
+
62
+ # 检查是否已运行
63
+ if lsof -i:$BACKEND_PORT > /dev/null 2>&1; then
64
+ log_warn "后端服务已在运行 (端口 $BACKEND_PORT)"
65
+ return 0
66
+ fi
67
+
68
+ # 设置测试环境变量
69
+ export APP_ENV=test
70
+ export DB_HOST=localhost
71
+ export DB_PORT=$MYSQL_PORT
72
+ export DB_NAME=test_db
73
+ export DB_USER=test_user
74
+ export DB_PASSWORD=test123
75
+ export REDIS_HOST=localhost
76
+ export REDIS_PORT=$REDIS_PORT
77
+
78
+ # 启动后端(后台运行)
79
+ go run main.go > /tmp/backend-test.log 2>&1 &
80
+ echo $! > /tmp/backend-test.pid
81
+
82
+ log_info "等待后端服务就绪..."
83
+ wait_for_port localhost $BACKEND_PORT 60
84
+ log_info "后端服务已就绪"
85
+ }
86
+
87
+ # 启动前端服务(E2E 测试需要)
88
+ start_frontend() {
89
+ log_info "启动前端服务..."
90
+
91
+ # 检查是否已运行
92
+ if lsof -i:$FRONTEND_PORT > /dev/null 2>&1; then
93
+ log_warn "前端服务已在运行 (端口 $FRONTEND_PORT)"
94
+ return 0
95
+ fi
96
+
97
+ # 进入前端目录并启动
98
+ if [ -d "frontend" ]; then
99
+ cd frontend
100
+ npm run dev > /tmp/frontend-test.log 2>&1 &
101
+ echo $! > /tmp/frontend-test.pid
102
+ cd ..
103
+
104
+ log_info "等待前端服务就绪..."
105
+ wait_for_port localhost $FRONTEND_PORT 60
106
+ log_info "前端服务已就绪"
107
+ else
108
+ log_warn "未找到 frontend 目录,跳过前端启动"
109
+ fi
110
+ }
111
+
112
+ # 停止所有服务
113
+ stop_all() {
114
+ log_info "停止测试环境..."
115
+
116
+ # 停止后端
117
+ if [ -f /tmp/backend-test.pid ]; then
118
+ kill $(cat /tmp/backend-test.pid) 2>/dev/null || true
119
+ rm /tmp/backend-test.pid
120
+ log_info "后端服务已停止"
121
+ fi
122
+
123
+ # 停止前端
124
+ if [ -f /tmp/frontend-test.pid ]; then
125
+ kill $(cat /tmp/frontend-test.pid) 2>/dev/null || true
126
+ rm /tmp/frontend-test.pid
127
+ log_info "前端服务已停止"
128
+ fi
129
+
130
+ # 停止 Docker
131
+ docker-compose -f "$DOCKER_COMPOSE_FILE" down
132
+ log_info "Docker 容器已停止"
133
+ }
134
+
135
+ # 清理测试数据
136
+ clean_data() {
137
+ log_info "清理测试数据..."
138
+ docker-compose -f "$DOCKER_COMPOSE_FILE" down -v
139
+ log_info "测试数据已清理"
140
+ }
141
+
142
+ # 显示状态
143
+ status() {
144
+ echo ""
145
+ echo "=== 测试环境状态 ==="
146
+ echo ""
147
+
148
+ # Docker 容器
149
+ echo "Docker 容器:"
150
+ docker-compose -f "$DOCKER_COMPOSE_FILE" ps 2>/dev/null || echo " 未启动"
151
+ echo ""
152
+
153
+ # 后端服务
154
+ echo -n "后端服务 (端口 $BACKEND_PORT): "
155
+ if lsof -i:$BACKEND_PORT > /dev/null 2>&1; then
156
+ echo -e "${GREEN}运行中${NC}"
157
+ else
158
+ echo -e "${RED}未运行${NC}"
159
+ fi
160
+
161
+ # 前端服务
162
+ echo -n "前端服务 (端口 $FRONTEND_PORT): "
163
+ if lsof -i:$FRONTEND_PORT > /dev/null 2>&1; then
164
+ echo -e "${GREEN}运行中${NC}"
165
+ else
166
+ echo -e "${RED}未运行${NC}"
167
+ fi
168
+
169
+ echo ""
170
+ }
171
+
172
+ # 使用说明
173
+ usage() {
174
+ echo "测试环境管理脚本"
175
+ echo ""
176
+ echo "用法: $0 <command>"
177
+ echo ""
178
+ echo "命令:"
179
+ echo " start 启动完整测试环境(Docker + 后端 + 前端)"
180
+ echo " start-api 仅启动 API 测试环境(Docker + 后端)"
181
+ echo " stop 停止所有服务"
182
+ echo " clean 停止并清理测试数据"
183
+ echo " status 查看环境状态"
184
+ echo " docker 仅启动 Docker 容器"
185
+ echo " backend 仅启动后端服务"
186
+ echo " frontend 仅启动前端服务"
187
+ echo ""
188
+ }
189
+
190
+ # 主逻辑
191
+ case "${1:-}" in
192
+ start)
193
+ start_docker
194
+ start_backend
195
+ start_frontend
196
+ status
197
+ ;;
198
+ start-api)
199
+ start_docker
200
+ start_backend
201
+ status
202
+ ;;
203
+ stop)
204
+ stop_all
205
+ ;;
206
+ clean)
207
+ stop_all
208
+ clean_data
209
+ ;;
210
+ status)
211
+ status
212
+ ;;
213
+ docker)
214
+ start_docker
215
+ ;;
216
+ backend)
217
+ start_backend
218
+ ;;
219
+ frontend)
220
+ start_frontend
221
+ ;;
222
+ *)
223
+ usage
224
+ exit 1
225
+ ;;
226
+ esac
@@ -0,0 +1,86 @@
1
+ import { defineConfig, devices } from '@playwright/test';
2
+
3
+ /**
4
+ * Playwright 配置模板
5
+ * 复制到项目 tests/e2e/ 目录并根据需要修改
6
+ *
7
+ * 参考文档: https://playwright.dev/docs/test-configuration
8
+ */
9
+ export default defineConfig({
10
+ // 测试目录
11
+ testDir: '.',
12
+
13
+ // 测试文件匹配模式
14
+ testMatch: '**/*.spec.ts',
15
+
16
+ // 完全并行运行测试
17
+ fullyParallel: true,
18
+
19
+ // CI 环境下禁止 test.only
20
+ forbidOnly: !!process.env.CI,
21
+
22
+ // 失败重试次数
23
+ retries: process.env.CI ? 2 : 0,
24
+
25
+ // 并行工作进程数
26
+ workers: process.env.CI ? 1 : undefined,
27
+
28
+ // 报告器配置
29
+ reporter: [
30
+ ['html', { outputFolder: 'playwright-report' }],
31
+ ['list'],
32
+ ],
33
+
34
+ // 全局配置
35
+ use: {
36
+ // 基础 URL
37
+ baseURL: process.env.FRONTEND_URL || 'http://localhost:3000',
38
+
39
+ // 收集失败测试的 trace
40
+ trace: 'on-first-retry',
41
+
42
+ // 失败时截图
43
+ screenshot: 'only-on-failure',
44
+
45
+ // 失败时录制视频
46
+ video: 'on-first-retry',
47
+
48
+ // 超时设置
49
+ actionTimeout: 10000,
50
+ navigationTimeout: 30000,
51
+ },
52
+
53
+ // 全局超时
54
+ timeout: 60000,
55
+
56
+ // 预期超时
57
+ expect: {
58
+ timeout: 10000,
59
+ },
60
+
61
+ // 浏览器配置
62
+ projects: [
63
+ {
64
+ name: 'chromium',
65
+ use: { ...devices['Desktop Chrome'] },
66
+ },
67
+ // 可选:添加更多浏览器
68
+ // {
69
+ // name: 'firefox',
70
+ // use: { ...devices['Desktop Firefox'] },
71
+ // },
72
+ // {
73
+ // name: 'webkit',
74
+ // use: { ...devices['Desktop Safari'] },
75
+ // },
76
+ ],
77
+
78
+ // 本地开发时自动启动前端服务
79
+ // 注意:测试环境脚本会预先启动服务,这里设置 reuseExistingServer: true
80
+ webServer: {
81
+ command: 'npm run dev',
82
+ url: 'http://localhost:3000',
83
+ reuseExistingServer: true,
84
+ timeout: 120000,
85
+ },
86
+ });
@@ -0,0 +1,116 @@
1
+ # <功能名称> 测试流程
2
+
3
+ ## 元信息
4
+
5
+ | 属性 | 值 |
6
+ |------|-----|
7
+ | 模块 | <module> |
8
+ | 平台 | web |
9
+ | 入口 | http://localhost:3000 |
10
+ | 创建日期 | YYYY-MM-DD |
11
+ | 最后执行 | - |
12
+ | 生成方式 | 手动(/uat:new)|
13
+
14
+ > 平台可选值:`web`(浏览器)/ `desktop`(桌面应用)/ `mobile-web`(移动端浏览器)
15
+ > 生成方式可选值:`手动(/uat:new)` / `代码分析(/uat:analyze)` / `手动 + 补充分析`
16
+
17
+ ---
18
+
19
+ ## 测试数据
20
+
21
+ 全局复用的测试数据,场景中直接引用字段名:
22
+
23
+ | 字段 | 值 | 说明 |
24
+ |------|-----|------|
25
+ | 用户名 | test@example.com | 测试账号 |
26
+ | 密码 | test123456 | - |
27
+
28
+ ---
29
+
30
+ ## 已知结论
31
+
32
+ 已验证、本次直接跳过的路径(执行时标记 SKIP,不重复验证):
33
+
34
+ - (示例:`手工新增接口返回 500` — 已知 Bug,跳过 S02 手工新增场景)
35
+
36
+ ---
37
+
38
+ ## S01 <场景名称>
39
+
40
+ **前置条件**:已打开入口页面,用户未登录
41
+
42
+ **数据准备**(可选):
43
+ - 在系统中提前创建所需数据(参见测试数据说明)
44
+
45
+ **数据清理**(新增场景必填):
46
+ - 找到「测试客户」这条记录,点击删除,确认弹窗
47
+
48
+ **步骤**:
49
+ 1. 在客户名称输入框输入「测试客户」
50
+ 2. 点击保存按钮
51
+ 3. 确认列表中出现「测试客户」这条记录
52
+
53
+ > **步骤写法说明**:
54
+ > - 用自然语言描述操作意图,不需要写选择器
55
+ > - 如果知道 `data-testid` 可以写在括号里作为提示,如:点击保存按钮(testid: customer-submit-button)
56
+ > - 下拉/级联选择直接写目标值:「在省市区选择框选择「广东省 → 广州市 → 天河区」」
57
+ > - 预期结果写可观察的状态:文字出现/消失、页面跳转、提示内容
58
+
59
+ **预期结果**:
60
+ - 列表中出现「测试客户」这条记录
61
+ - 页面显示「保存成功」提示
62
+
63
+ ---
64
+
65
+ ## S02 <场景名称>
66
+
67
+ **前置条件**:...
68
+
69
+ **数据准备**(可选):...
70
+
71
+ **步骤**:
72
+ 1. ...
73
+
74
+ **预期结果**:
75
+ - ...
76
+
77
+ ---
78
+
79
+ ## SXX 表单边界 & 字符类型(推荐随业务场景同步补充)
80
+
81
+ > 对每个有「新增 / 编辑」表单的功能,补充此场景。
82
+
83
+ **前置条件**:已打开表单,处于可输入状态
84
+
85
+ **字段清单**(按实际表单填写):
86
+
87
+ | 字段 | 最大长度 | 最小长度 | 类型约束 |
88
+ |------|---------|---------|---------|
89
+ | 客户名称 | 50 | 1 | 中英文数字 |
90
+ | 手机号 | 11 | 11 | 数字 |
91
+
92
+ **测试矩阵**(对每个字段逐一执行):
93
+
94
+ | # | 输入类型 | 示例输入 | 预期结果 |
95
+ |---|---------|---------|---------|
96
+ | B1 | 空值 / 必填 | (清空) | 内联提示「XX 不能为空」,不提交 |
97
+ | B2 | 最大长度 + 1 | 超出 maxLength 1 位的字符串 | 截断输入 或 提示超限,不提交 |
98
+ | B3 | 最小长度 - 1 | 少于 minLength 1 位 | 提示长度不足,不提交 |
99
+ | C1 | 纯中文 | 张三李四 | 正常接受并保存 |
100
+ | C2 | 中英文混合 | abc张三 | 正常接受并保存 |
101
+ | C3 | 特殊字符 | `< > & " '` | 正常保存(展示时转义,不破坏页面) |
102
+ | C4 | 潜在 XSS | `<script>alert(1)</script>` | 正常保存,展示为文本,脚本不执行 |
103
+ | C5 | 首尾空格 | ` 测试 ` | 自动 trim 或原样保留(明确业务规则) |
104
+ | C6 | Emoji | | 正常接受 或 提示不支持(视业务规则) |
105
+ | C7 | 全角字符 | abc123 | 正常接受 或 提示仅支持半角(视业务规则) |
106
+
107
+ > 按需裁剪:不适用的行可删除;字段有特殊约束(仅数字、手机格式等)需额外补充。
108
+
109
+ **步骤**(对每个字段,按测试矩阵逐行执行):
110
+ 1. 清空字段,输入当前测试行的示例值
111
+ 2. 点击提交按钮,等待页面反馈
112
+ 3. 记录实际结果,对比预期
113
+
114
+ **预期结果**:
115
+ - B1-B3(边界):验证失败时表单内联提示,不提交
116
+ - C1-C7(字符):合法字符正常保存;详情页展示不乱码、不执行脚本