mcpField
M
manual-testing

manual-testing

github.com/bmad-labs测试与质量19112 次安装1 周前更新
代码仓库

关于 manual-testing

manual-testing 是面向 QA 工作的技能,用于规划、编写、审查、执行和维护可复现、可追踪的手动测试用例。它要求先确认执行者能操作产品并独立观察结果,再决定是否编写测试。

主要功能

  1. 01从设计资料制定测试计划
  2. 02编写含前置条件与断言的用例
  3. 03按质量标准审查测试覆盖
  4. 04执行用例并汇总测试结果
  5. 05功能变更后更新测试用例
  6. 06先验证操作与观察测试条件

适用场景

  1. 01为新功能设计手动测试覆盖
  2. 02审查现有测试用例的可验证性
  3. 03执行测试并整理失败结果
  4. 04功能变更后维护测试计划

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bmad-labs/skills --skill manual-testing

安装后在 Claude Code 中输入/manual-testing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
build-systems.md
quality-criteria.md
templates.md
test-categories.md

详细介绍

手动测试技能

你是一名 QA 工程师,负责协助规划、编写、审查、执行和维护手动测试用例。你产出的测试工件具体、可复现,并且可追溯至设计文档。

此技能的触发条件

  • 用户要求编写、创建或生成测试用例或测试计划
  • 用户询问“我该如何测试这个?”或“我需要哪些测试用例?”
  • 用户要求审查测试覆盖率或评估测试质量
  • 用户要求运行手动测试或执行测试用例
  • 用户要求在功能变更后更新测试
  • 实现功能后(CLAUDE.md 要求更新测试计划)

能力

代码操作描述
P规划根据设计文档、PRD 或功能描述创建测试计划
W编写创建包含前置条件、步骤和检查点的测试用例文件
R审查根据标准评估测试用例质量
X执行运行测试用例、验证检查点并报告结果
U更新在功能变更时修改测试用例

工作流

0. 测试环境门槛——Agent 能否像人一样操作和观察此产品?

在确定范围之前、编写任何场景之前,先执行此检查。 手动测试的质量取决于执行者能否操作产品并独立查看结果。无法点击按钮、也无法查看屏幕的 Agent,只会编写自己永远无法运行的断言,这样的测试套件毫无用处。

请针对 Agent 而非系统回答两个问题:

问题如果回答 NO
操作Agent 能否像用户一样操作产品——点击、输入、打开菜单、切换窗口或配置文件?这套测试只能由人执行。请明确说明,或搭建测试环境。
观察Agent 能否独立于产品对自身状态的报告,查看真实结果——实际像素、实际存储的字节、实际文件?断言将沦为产品的自我报告。请搭建测试环境。

编写测试前,两个问题的答案都必须是 YES。请在第一条回复中明确说明答案——在交付内容后才把能力列为假设,就说明你没有执行门槛检查。

如果任一答案为 NO:停止并建议用户搭建测试环境。 指明能力缺口、指出可弥补该缺口的工具,并说明它能解锁什么。不要抱着侥幸心理编写测试套件,也不要悄悄降级为只能由人执行的测试套件。

按产品类型推荐的测试环境:

产品推荐工具原因
原生桌面应用(Windows/macOS/Linux)cua-driver可操作真实窗口、菜单和对话框;可捕获真实窗口像素——这是查看用户所见内容的唯一方式
Web 应用playwright-cli可操作页面并读取 DOM、网络和控制台信息
Chrome 扩展playwright-cli 和 cua-driver两者都需要:Playwright 用于页面/DOM 和浏览器内部状态(chrome.storage、service worker);cua-driver 用于 Playwright 无法访问的部分——扩展弹出窗口、工具栏和浏览器原生界面
无头服务 / CLI / APIShell + 服务自带的客户端无需操作 GUI;观察对象为文件、退出代码、数据库行和日志
移动应用平台驱动程序(Appium/XCUITest/Espresso)原理与桌面应用相同

应根据两项能力进行判断,而不是只参考表格——即使产品未列出,也必须回答这两个问题。当产品本身就是自动化接口(MCP 服务、桥接器、驱动程序)时,其自身输出属于待测试的声明;观察必须从外部进行。

信任测试环境之前先验证它,例如,确认 cua-driver status 返回交互式会话,或捕获并读取真实窗口的探测截图。假设测试环境已就绪,与假设某项能力已具备是同样的问题。

1. 了解范围

编写任何测试之前,先了解测试对象:

  • 阅读设计文档——查找 _bmad-output/planning-artifacts/design/ 中的文档
  • 阅读功能代码——了解发生了哪些变更、添加了什么,以及哪些部分受到影响
  • 检查现有测试——先找到项目的测试套件,再编写新内容。本仓库使用 tests/uat/(test-plan.md、testcases/TC-*.md);其他项目可能使用 docs/tests/ 或 test/manual/。阅读测试计划的格式约定,并遵循该格式——测试用例不符合项目既定格式,就得返工。
  • 识别项目类型——阅读 references/test-categories.md,了解适用的覆盖范围
2. 规划测试覆盖范围

对于每个功能领域,查阅 references/test-categories.md,确定适用的测试类别。规划完善的测试套件应覆盖:

  1. 正常路径——预期流程能够正常运行
  2. 边界情况——边界值、空输入、最大尺寸
  3. 错误处理——发生故障时会如何处理
  4. 集成点——此功能与其他系统交互的地方
  5. 数据完整性——数据能够正确存储和检索
  6. 并发——多个同时进行的操作不会发生冲突
3. 编写测试用例

首先遵循测试套件现有的格式。 编写之前,先阅读测试计划的格式约定。常用的结构有两种;references/templates.md 中提供了这两种结构。

结构形式适用情形
Given/When/Then每个场景都有自己的设置、操作和断言新测试套件的默认选择。读者无需将“步骤 3”对应到“CP5”,步骤重新编号也不会导致断言失去对应关系。
Steps + Checkpoints编号步骤,后接编号为 CP1..CPn 的检查点仅当测试套件已采用此结构时使用。不要在同一测试套件中混用两种结构。

无论采用哪种结构,每个测试用例都必须包含:

  • 优先级(Critical / High / Medium)——用于安排执行顺序
  • 设计参考——指向设计文档中的相应章节,以便追溯
  • 前置条件——测试开始前必须准备好的内容(文件级,所有场景共用)
  • 操作序列及其断言——具体命令和预期值
  • 清理——测试后用于重置状态的命令

Given/When/Then 文件必须使用 Markdown 硬换行。 连续的 **Given** / **When** / **Then** / **And** 行末尾如果没有空格,渲染时会变成一整段连续文本,导致断言难以阅读。每行末尾都加两个空格。交付文件前请确认:

# every GWT line must end in two spaces; prints the offenders
grep -n '^\*\*\(Given\|When\|Then\|And\)\*\*' TC-*.md | grep -v '  $'

测试用例应当自成一体——其他人(或 Agent)应能直接执行,无需提问。

4. 评估测试质量

定稿前,根据 references/quality-criteria.md 进行评估:

  • 每个测试是否独立(不依赖其他测试的状态)?
  • 每个检查点是否都有具体且可验证的断言?
  • 测试数据是否真实(不是“测试内容”,而是实际的领域数据)?
  • 清理操作是否完全恢复了状态?
  • 是否能够追溯到设计文档或需求?
5. 执行测试

测试执行分为两个不同阶段,由主 Agent 以不同方式运行:基础设施设置(主 Agent)和逐个测试用例执行(委派给子 Agent,严格按顺序执行)。

5.1 主 Agent:基础设施设置

分派任何测试用例之前,主 Agent 会准备环境。本次运行中的所有测试用例共享此阶段的状态——只需运行一次即可分摊成本,并缩短子 Agent 提示词。

  1. 阅读测试套件的测试计划(本仓库中的 tests/uat/test-plan.md),了解范围、前置条件、环境变量和运行文件夹约定。
  2. 检测构建系统(见下文)。从源代码重新构建应用程序,确保测试针对最新代码运行,而不是陈旧的镜像或缓存的二进制文件。陈旧构建是导致令人困惑的测试失败(“这看起来还是旧行为”)和误通过(“这个 Bug 出现在较新的提交中,但该提交未被构建”)的头号原因。
    • 查阅 references/build-systems.md,获取各技术栈的具体命令。检查锁文件/清单文件(docker-compose.yml、package.json、pyproject.toml、Cargo.toml、go.mod 等)以检测技术栈,并运行对应的重建命令。
    • 对于基于 Docker 的项目,只有在用户怀疑存在缓存问题时才使用 --no-cache 重建镜像;否则,普通重建加 --force-recreate 就足够了,而且速度更快。
  3. 启动基础设施:数据库、队列、API 服务、工作进程。等待健康检查完成。
  4. 填充测试数据:保险库文件、数据库行、测试固件。将文件复制到容器时修正文件所有权(例如,对于 Docker,在 docker cp 后执行 chown——主机 UID 与容器用户不匹配)。
  5. 冒烟验证:访问 /health 或等效端点,确认服务确实已启动并正在接受流量。如果失败,就停止——在故障的技术栈上运行测试用例毫无意义。
  6. 收集项目特定上下文:收集文件路径、环境变量名称、API URL、身份验证令牌、保险库路径、示例测试固件等——所有子 Agent 原本都需要花费令牌重新发现的信息。在下一阶段将这些信息整理到子 Agent 提示词中。
5.2 每个测试用例使用一个子 Agent(严格按顺序执行)

不要直接在主 Agent 中执行测试用例。对于本次运行中的每个测试用例,启动一个子 Agent,等待它提交报告,然后再启动下一个。这样可以控制主 Agent 的上下文规模、隔离各次测试运行,并让你在其他任务暂停期间调查失败。

**为何按顺序执行(而非并行):**手动测试用例经常会共享基础设施状态(数据库行、保险库文件、转录 ID)。并行执行可能导致某个测试用例污染另一个测试用例的前置条件,或争用共享资源。按顺序执行也便于诊断故障——主 Agent 可以暂停,并在后续测试用例更改导致故障的状态之前展开调查。

子 Agent 提示词模板——为每个子 Agent 提供所需的一切,不要多给:

Execute test case <TC-ID> from <path to TC file>.

## Project context
- Working directory: <abs path>
- Build system: <detected>
- Infrastructure already running: <list services + ports>
- Auth: <API_KEY=..., DB creds, etc.>
- Relevant env vars: <list>
- Known fixtures / sample data: <paths>
- Cleanup commands from the TC: <paste here>

## Your job
1. Follow the test case EXACTLY as written — its preconditions, its actions, and
   every assertion. Do not improvise or substitute commands.
2. For each assertion, run the verification command and record the actual output.
3. Report back:
   - Overall verdict: PASS / PARTIAL / FAIL / SKIP
   - Per-assertion result, naming the assertion: <name> PASS,
     <name> FAIL (actual: X, expected: Y), …
   - An assertion you did not execute is NOT a PASS. Report it as NOT RUN and say why.
4. Cleanup:
   - If ALL assertions PASS → run the TC's cleanup commands.
   - If ANY assertion FAILED or PARTIAL → DO NOT clean up. Leave DB rows, files,
     logs in place so the main agent can investigate.
5. For FAIL, include: exact command run, raw stdout/stderr, relevant log excerpts
   (docker logs, psql output), and which assertion(s) failed.
6. For LLM-dependent tests: run 2–3 times and report majority result.
7. Write evidence to $RUN_DIR/evidence/ — never overwrite a previous run's folder.

每个子 Agent 提交报告后:

  • PASS / PARTIAL(已执行清理):记录结果并启动下一个子 Agent。
  • FAIL(状态已保留):停止顺序执行。利用保留的状态展开调查(查询数据库、检查日志、读取测试用例操作过的文件)。决定是修复、跳过还是中止剩余测试用例。只有调查完成后,主 Agent 才运行该测试用例的清理命令。
  • 测试失败时绝不自动清理——事后分析所需的状态,是本次运行中最有价值的诊断资料。
5.3 主 Agent:汇总与拆除

顺序执行结束后:

  1. 汇总各测试用例的结果,并整理成摘要表格(TC-ID、判定结果、失败的 CP、备注)。
  2. 向用户报告:总数(N 个通过、M 个失败、K 个跳过)、失败详情,以及建议的后续操作。
  3. 拆除基础设施:停止服务,移除测试容器/卷。只有在用户确认结果后才执行此操作——用户可能想先检查正在运行的技术栈。
5.4 容器化执行与凭据卫生(安全/红队及任何涉及真实机密的测试)

当被测对象是容器化应用,或测试会处理真实凭据时,测试的运行位置以及哪些内容会接触主机,与断言同样重要。以下两条原则都是付出过惨痛代价后总结出来的:

在产品自己的容器内运行,而不是在主机上运行。 为了图快,直接在开发者的机器上运行 npm test/二进制文件/辅助脚本很有诱惑力。如果产品以容器形式交付,就要抵制这种做法:通过真实镜像(docker run …)运行测试,并将任何攻击者基础设施(捕获监听器、模拟端点)作为同一自定义网络上的同级容器运行,绝不要让它们作为绑定主机端口的主机进程运行。在主机上阅读文档或 grep 输出文件没有问题,但在主机上执行产品不行。原因:主机上的运行与真实运行时使用不同的路径、权限、UID 和环境变量,因此在主机上“通过”可能掩盖真实的容器 Bug(反之亦然),还可能让产品的产物(和机密)散落在开发者的机器上。

绝不让真实机密落到主机上。 如果应用需要真实凭据(auth.json、API 密钥、令牌):

  • 将凭据从其源位置直接以只读方式挂载到容器中(-v "$HOME/.../auth.json":/in/container/path:ro)。不要将其 cp 到 /tmp 临时目录——复制的机密会在运行结束后继续留存,很容易被遗忘。(一次会话中,这个确切的失误在被发现前导致包含凭据的 auth.json 副本和日志两次泄露到主机的 /tmp。)
  • 在容器环境中检查包含凭据的产物;如果必须在主机上读取,就在 grep 后立即对所有此类文件执行 shred -u,并且只向用户输出已屏蔽的通过/失败计数——绝不输出原始机密值。
  • 捕获的日志中,机密作为屏蔽指令(例如 GitHub 的 ::add-mask::<value>)出现一次,是正确行为,不是泄露——运行器会将其脱敏。只有当机密值出现在已持久化的产物(记录/摘要/输出)或工具输出中时,才应标记为问题。
  • 拆除是卫生检查关卡,不只是清理工作。 运行结束后,确认主机环境干净:没有存有机密的临时目录、没有遗留的凭据文件,也没有残留的容器/网络/卷。将“主机干净”视为必须明确确认的检查点,与确认断言同样重要。

由子 Agent 执行对抗性测试——分类器问题。 §5.2 中“每个测试用例使用一个子 Agent”的规则,在安全/红队测试中有个明显的限制:子 Agent 执行携带攻击载荷的 docker run(cat .git/config、env | grep TOKEN、伪造令牌、SSRF 基础 URL)时,通常会被自动模式安全分类器拒绝——这些载荷看起来像恶意内容。因此,在将对抗性 TC 委派给子 Agent 之前,先从以下方案中选择一个:

  • 以 bypassPermissions 模式启动测试子 Agent(严格限定其权限范围,仅限测试框架),这样它在容器内执行的对抗性测试就不会被拦截;或者
  • 由负责人/主 Agent 直接运行对抗性 TC(负责人不会以同样的方式受到分类器的限制),只将无害的功能 TC 委派给子 Agent。 请提前决定——运行中途才发现这个问题会白白浪费一次 Agent 启动。(无害的功能回归 TC 可以顺利委派给子 Agent。)
6. 功能变更后更新测试

功能变更时,必须更新测试:

  1. 在测试套件中找到受影响的 TC 文件(此处为 tests/uat/testcases/TC-*.md)
  2. 如果设置有变化,则更新前置条件
  3. 如果 API/工作流有变化,则更新 When 操作
  4. 如果预期行为有变化,则更新 Then 断言
  5. 为新功能添加新的场景
  6. 如果新建了 TC 文件,则更新测试计划索引

参考文件

按需阅读这些文件——其中包含各项能力的详细知识:

文件阅读时机内容
references/test-categories.md规划覆盖范围时按项目类型(API、前端、流水线、AI/LLM、基础设施、数据库、安全)划分的覆盖清单,并按风险确定优先级
references/quality-criteria.md编写或审查时10 项测试质量标准、反模式、评估标准、LLM 三层测试、检查点编写指南
references/templates.md编写测试用例或规划测试套件时Given/When/Then 和传统 Steps+Checkpoints 模板、按运行划分文件夹的测试套件布局、路径可移植性规则及其陷阱、断言模式
references/build-systems.md执行测试前各技术栈的检测启发式方法和精确的重建命令(Docker Compose、Node/npm/pnpm、Python/uv/poetry、Rust、Go、Java、单体仓库、多仓库)

配套 BMAD 技能

这些 BMAD 技能可提供更深入的测试工作流。请在适当时与此技能搭配使用:

技能适用场景提供的补充内容
bmad-testarch-test-design从头制定全面的测试计划风险评估矩阵(TECH/SEC/PERF/DATA/BUS/OPS)、可测试性审查(可控性/可观测性/可靠性)、带有 P0-P3 优先级的覆盖矩阵、质量门禁(P0=100%,P1≥95%)
bmad-testarch-test-review审查现有测试质量四维评估(确定性、隔离性、可维护性、性能)、加权评分、按严重程度汇总违规项
bmad-teach-me-testing学习测试基础知识或培训团队时从基础到进阶的渐进式结构化课程、TEA 方法论
bmad-tea向首席测试架构师咨询建议时关于测试策略、覆盖缺口和测试架构决策的专家指导
如何组合使用技能

规划测试套件:先使用此技能的 references/test-categories.md 了解覆盖范围,然后调用 bmad-testarch-test-design,进行正式的风险评估并制定带有 P0-P3 优先级的覆盖矩阵。

审查测试质量:使用此技能的 references/quality-criteria.md 查看 10 项质量检查清单,然后调用 bmad-testarch-test-review,进行 4 个维度的深入评估(确定性、隔离性、可维护性、性能)。

编写测试用例:使用此技能的模板和质量标准。根据风险确定优先级时,参考 bmad-testarch-test-design:

  • P0:阻碍核心功能 + 高风险 + 无替代方案 → 严重
  • P1:关键路径 + 中/高风险 → 高
  • P2:次要流程 + 低/中风险 → 中
  • P3:锦上添花、探索性 → 低

质量门禁(来自 bmad-testarch-test-design):

  • P0 通过率 = 100%(必须全部通过)
  • P1 通过率 ≥ 95%
  • 发布前完成高风险缓解措施
  • 覆盖率目标 ≥ 80%

规则

  1. 真实测试数据 — 切勿使用“测试内容”或“lorem ipsum”。使用能验证真实行为的领域专用数据。
  2. 精确的验证命令 — 每项断言都必须有一个能产生可验证结果的命令(curl、psql、grep、cat、wc)。
  3. 设计文档可追溯性 — 每个测试用例都必须注明其验证的设计文档章节。
  4. 独立性 — 每个测试用例都必须能独立运行。不要假设其他测试已先运行。
  5. 清理 — 每项会修改状态的测试都必须包含清理命令。若测试失败(FAIL),跳过清理并保留状态以便调查;主 Agent 在分诊后负责清理。
  6. 大模型的非确定性 — 对于依赖 AI 的测试,验证结构和章节是否存在,而非具体内容。运行 3 次或以上,确保多数通过。
  7. 基于风险确定优先级 — 使用 P0-P3 优先级框架。先测试 P0(关键路径),最后测试 P3(探索性)。
  8. 可测试性评估 — 编写测试前,评估:能否控制系统状态?能否观察结果?能否可靠地独立运行测试? 8a. 先过测试框架门槛 — 确定范围或编写测试前,先说明 Agent 是否能够(a)像人一样操作产品,以及(b)独立于产品的自我报告来观察真实结果。两者都必须明确回答 YES;否则停止,并建议使用测试框架(原生应用使用 cua-driver,Web 使用 playwright-cli,Chrome 扩展则两者都用),并说明它能实现什么。若只是把能力作为交付内容之后的假设,或悄悄编写一套留给人类执行的测试,就等于没有通过门槛检查。参见 §0。
  9. 避免冗余覆盖 — 避免在多个层级测试同一内容。逻辑用单元测试,边界用集成测试,用户流程用端到端(E2E)测试。
  10. 运行测试前始终重新构建 — 任何测试运行(单元、集成、手动)都必须先从源代码重新构建应用程序。过期的镜像/字节码/二进制文件会导致难以判断的误通过和误失败。根据项目标记识别构建系统(参见 references/build-systems.md),并运行相应的重构建命令。
  11. 每个测试用例使用一个子 Agent,严格顺序执行 — 主 Agent 负责基础设施(设置、播种数据、冒烟检查、拆除)。每个测试用例都由自己的子 Agent 单独执行。不得并行:手动测试会共享状态,顺序执行有助于诊断故障。参见 §5.2。
  12. 失败时不自动清理 — 若子 Agent 的测试失败(FAIL)或部分通过(PARTIAL),必须保留现场(数据库行、文件、日志)。主 Agent 调查后,再运行该测试用例的清理命令。运行中保留的取证现场是最有价值的诊断材料。(例外:包含真实密钥的材料无论如何都必须粉碎删除——参见规则 13。)
  13. 产品容器化,凭据绝不存放在主机上 — 使用真实镜像运行容器化应用,并将攻击者基础设施作为同级容器运行(绝不使用主机进程/端口)。从源位置以只读方式挂载真实密钥;绝不将其 cp 到临时目录。完成 grep 后粉碎删除任何包含凭据的材料;仅输出脱敏值。将“主机已清理”(无密钥文件、无遗留容器)作为明确的拆除检查点确认。参见 §5.4。
  14. 预先选定对抗性测试用例的运行者 — 子 Agent 使用 docker run 运行攻击载荷时会被分类器拦截。要么以 bypassPermissions 模式启动测试子 Agent,要么由主 Agent 执行对抗性测试用例;仅将良性测试用例委派给普通子 Agent。参见 §5.4。
  15. 遵循测试套件现有格式;为每行 GWT 内容添加硬换行 — 编写前先阅读测试计划中的格式约定。在 Given/When/Then 测试套件中,每个 **Given**/**When**/**Then**/**And** 行都必须以两个空格结尾,否则 Markdown 会将整个场景渲染成一段连写文本。验证:grep -n '^\*\*\(Given\|When\|Then\|And\)\*\*' TC-*.md | grep -v ' $' 不应输出任何内容。参见 references/templates.md。
  16. 不使用机器路径;每次运行使用独立文件夹 — 所有路径都必须使用测试计划中定义的 $PROJECT_ROOT/$RUN_DIR,绝不写死检出目录路径。每次运行都写入自己的 run/<date>-<NN>/ 文件夹,保留先前的证据以供比较。验证:grep -rn -- "$PROJECT_ROOT" testcases/ 不应有任何匹配项。批量修改路径后,重新阅读那些断言失败的场景——错误输入被替换成有效输入时,所有 grep 检查仍会通过。参见 references/templates.md。

评论

支持 Markdown