<Feature> Test Plan
2026-09-06 18:08:20作者:袁立春Spencer
Application Overview
Test Scenarios
1.
Seed: tests/seed.spec.ts
1.1.
File: tests/<group>/<kebab-case-scenario-name>.spec.ts
Steps:
- expect: <observable outcome>
- expect: <another observable outcome>
- expect: <outcome>
1.2.
...
2.
Seed: tests/seed.spec.ts
...
编写规范:
- 每个场景相互独立,都从 seed 的干净状态出发 —— **绝不串联场景**;
- 场景名使用 kebab-case,且与测试文件名一致(`should-add-single-todo` → `should-add-single-todo.spec.ts`);
- 覆盖 happy path、边界、校验、负向流程与持久化;
- 步骤写在**用户层面**(如 "Type 'Buy milk' into the input"),不要写 API 层面(如 "call `fill`");
- 可观测结果放进 `- expect:` 列表项 —— 生成阶段每条 expect 都会变成一条断言。
## 2. Generate:把 spec 变成测试
**目标**:读取 spec 文件,产出 Playwright 测试文件;若 spec 与实际应用已有漂移,可选择同步更新 spec。
### 2.1 输入
- **Spec 文件**,例如 `specs/basic-operations.plan.md`;
- **目标范围**:单条场景(如 `1.2`)、整个分组(`1`)或全部;
- **Seed 文件**:从场景所属分组的 `**Seed:**` 行读取。
### 2.2 生成单条场景
对每个目标场景**依序**逐个生成(**绝不并行** —— 场景共享同一个 seed 会话):
```bash
PLAYWRIGHT_HTML_OPEN=never npx playwright test <seed-file> --debug=cli # background
playwright-cli attach tw-XXXX
# resume
同样地,不要直接用 playwright-cli 打开应用 URL,始终经过测试以捕获自定义初始化。
接下来逐条走 spec 的 Steps:,把 spec 当作计划、把活的应用当作事实来源。如果某一步含糊("click the button"——哪个 button?)、指向的元素已不存在、或与应用实际行为矛盾,应运用判断力:先把 spec 改成应用真实的样子,再继续走。在生成中途编辑 spec 是预期内行为。
每条动作都会打印等价的 Playwright TypeScript(机制见第 0 节):
playwright-cli snapshot # find refs
playwright-cli fill e3 "John Doe" # -> page.getByRole('textbox', {...}).fill(...)
playwright-cli press Enter
playwright-cli click e7
对 spec 里每条 - expect: 列表项,都要添加显式断言。随后把生成的代码收集起来,写到 spec 指定路径的测试文件:
// spec: specs/basic-operations.plan.md
// seed: tests/seed.spec.ts
import { test, expect } from './fixtures'; // or '@playwright/test' if no fixtures file
test.describe('Signing in and out', () => {
test('should sign in', async ({ page }) => {
// 1. Navigate to the application
// (handled by the seed fixture)
// 2. Type 'John Doe' into the username field
await page.getByRole('textbox', { name: 'username' }).fill('John Doe');
// 3. Type password
await page.getByRole('textbox', { name: 'password' }).fill('TestPassword');
// 4. Press Enter to submit
await page.getByRole('textbox', { name: 'password' }).press('Enter');
await expect(page.getByRole('heading')).toContainText('Welcome, John Doe!');
});
});
生成规则:
- 一个测试一个文件。文件路径、describe 名与 test 名均照抄 spec(去掉序号前缀);
- 每个带编号的步骤,在其动作前加一行
// N. <step text>注释; - describe 分组名照抄 spec 中的分组名(不加
1.序号); - 项目有 fixtures 文件就
import ... from './fixtures',否则从'@playwright/test'导入; - 重要:进入下一个场景前,先关闭 CLI 会话并停止后台测试。
2.3 生成多条场景
循环执行 2.2,一次处理一个目标场景,并在每个场景之间重启 seed,保证每个测试都从干净的页面开始。由于每次生成的会话名唯一(tw-XXXX),这条流程可以安全并行——但务必保证每个测试运行都被停止。
2.4 运行生成的测试
生成完毕后,把新测试跑一遍:
PLAYWRIGHT_HTML_OPEN=never npx playwright test tests/<group>/<scenario>.spec.ts
任何失败都会进入第 3 节处理。
3. Heal:诊断、修复、对账
目标:修复失败的测试;如果应用的预期行为本身发生了变化,同步更新 spec。
3.1 找出失败用例
PLAYWRIGHT_HTML_OPEN=never npx playwright test
记录失败的 <file>:<line> 清单,一次只处理一个。不要尝试并行修复——共享状态与单一 CLI 会话使并行非常脆弱。
3.2 调试单个失败
在后台以 debug 模式运行单个失败测试,再 attach:
PLAYWRIGHT_HTML_OPEN=never npx playwright test tests/<group>/<scenario>.spec.ts:<line> --debug=cli
# wait for "Debugging Instructions" and the tw-XXXX session name
playwright-cli attach tw-XXXX
测试在起点暂停。逐步执行或运行到失败动作 / 断言的前一刻,然后开始诊断:
playwright-cli snapshot # did the element change / move / rename?
playwright-cli console # app-side errors?
playwright-cli requests # failed request? wrong payload?
playwright-cli show --annotate # ask the user to point somewhere
登录后查看全文
热门项目推荐
相关项目推荐
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
最新内容推荐
impeccable `/harden` 全解析:为 AI 生成的界面加上错误处理、i18n、边界用例与溢出防护,交付生产级 UInushell inc 版本递增插件详解:安装、注册与 semver 使用实战深度解析 Cypress v8-snapshot Express 示例工程:从快照生成到运行时加载的完整链路如何用 prompts.chat npm 包的 quality 模块在本地校验提示词质量并获取改进建议?使用 ColossalAI 混合并行插件训练 GPT-2:从插件配置、Booster 增强到流水线调度全解析《Web-Dev-For-Beginners》实战:为银行应用实现「添加交易」对话框并接入既有状态管理系统Milvus Segcore 时间旅行(Time Travel)实现解析:Growing Segment 的 vec_count 截断与 Sealed Segment 的 Bitmask 过滤GAN Harness 规划者 Agent(gan-planner):如何把一行需求展开成可执行的产品规格RuView Graph-ANN 检索基线与 SymphonyQG 假设的实测检验 —— 解读 ADR-261 中 RuVector 的纯 Rust HNSW 实现与量化遍历变体DeepSpeed 实战:BingBertSQuAD 微调指南——将 SQuAD 问答微调无缝接入 DeepSpeed 并启用 Transformer Kernel 加速
项目优选
收起
deepin linux kernel
C
33
18
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
暂无描述
Markdown
897
5.81 K
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389