关于 Ai 測試大師 / Mcp Test Runner
MK QA Master 是一个 MCP 服务,用于统一运行 pytest、Jest、Cypress、Go、Maestro 等测试框架,覆盖 Web、移动端与 API 测试。它面向使用 AI 客户端进行 QA 工作的团队,并在每次运行后生成优先级行动计划。
主要功能
- 01统一的多框架测试运行入口
- 02Web、移动端与 API 测试支持
- 03失败截图、视频与 trace 收集
- 04运行历史与 HTML 趋势报告
- 05analyze_url 页面分析与 generate_test 用例生成
- 06输出 JUnit XML 供 CI 使用
适用场景
- 01通过 MCP 客户端运行 pytest 或 Jest 测试套件并查看失败详情
- 02基于 OpenAPI 或 Postman 集合执行 API 测试
- 03在 iOS 模拟器或 Android 模拟器上运行 Maestro 流程
MCP 相关
该项目是一个 MCP 服务,向 Claude Desktop、Cursor 等 MCP 客户端暴露运行测试、分析页面、生成用例及查看报告等工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
MK QA Master
AI 測試大師 — 从分析到建议,打造你的 AI QA 循环。
English · 繁體中文
通用 MCP 服务,可跨 pytest / Jest / Cypress / Go 运行测试, 内置 DOM 分析器、运行历史记录和自我改进教练。 自 v1.0.0 起稳定(2026-06-02) — 请参阅下文的 稳定性承诺。
一个 Model Context Protocol 服务,让 Claude Desktop / Cursor / 任意 MCP 客户端端到端驱动测试套件:运行测试、检查故障(截图 + 视频 + 跟踪记录)、 分析实时 URL 以起草测试用例,并在每次运行后生成按优先级排序的行动计划,明确指出 下一步要修复或编写什么。
QA_RUNNER | 框架 | 语言 | 目标 |
|---|---|---|---|
pytest / pytest-playwright / playwright | pytest + Playwright | Python | Web |
jest | Jest | JavaScript | Web |
cypress | Cypress | JavaScript | Web |
go / go-test | go test | Go | 后端 |
maestro / mobile | Maestro | YAML | iOS + Android |
schemathesis / api | Schemathesis | OpenAPI 3.x / Swagger 2.0 | API(自 v0.6.0 起) |
newman / postman | Newman | Postman collection v2.x | API(自 v0.6.1 起) |
完整设计说明:docs/framework.md。
包含内容
-
运行测试:通过统一的 MCP 接口,跨多个框架(Web + 移动端 + API)运行测试
-
通过 Maestro 进行移动端测试(自 v0.3.0 起):使用相同的 MCP 工具,支持 iOS Simulator / Android Emulator / 真实设备;采用 YAML 流程;跨平台使用,无需重写
-
原生 API 测试——两种运行器(自 v0.6.0 / v0.6.1 起):两个同级运行器 现在共用 API 测试入口,各自使用团队已经维护的工件。
- Schemathesis(
QA_RUNNER=schemathesis,自 v0.6.0 起):指定 OpenAPI 3.x / Swagger 2.0 URL 或file://架构,即可运行基于属性的模糊测试,覆盖状态码、响应架构、内容类型以及 模糊测试触发的5xx违规。 - Newman(
QA_RUNNER=newman,自 v0.6.1 起):指定导出的 Postman 2.x 集合(以及可选的环境 / 全局变量文件),Newman 会重放每个请求、 运行嵌入的pm.test(...)断言,并为每个断言返回一个 mk-qa-master nodeid。Newman 是系统前置条件(npm install -g newman)——它是 npm 包,而非 pip 包,因此不会作为 Python 扩展一同安装。
两者都使用与 Web / 移动端运行器相同的 MCP 工具接口,并接入相同的
report.json/ 历史记录 / 不稳定测试 / 优化流水线。现有的 API 测试如果使用 pytest+httpx、Jest+supertest、Cypresscy.request()或 Gonet/http/httptest编写,仍可继续使用各自现有的 运行器,无需迁移。Pact 提供方验证仍列在 v0.7.0 的条件性路线图中。 - Schemathesis(
-
失败工件:截图(内嵌 base64)、视频、Playwright trace.zip / Maestro 录制文件
-
运行历史:每次运行都会生成快照;HTML 报告会显示迷你趋势图
-
DOM / 屏幕分析器——Web 端使用
analyze_url(表单 / 导航 / 对话框 / CTA + 页面访问的 API 端点),移动端使用analyze_screen(maestro hierarchy→ 表单 / CTA / 标签栏模块) -
智能测试生成(
generate_test):传入分析器模块,即可生成可运行的 Playwright.py或 Maestro.yaml,包含具体的 选择器,而非# TODO占位代码 -
自动重试不稳定测试——pytest 端通过
pytest-rerunfailures;Maestro 端通过自定义重试封装(不支持原生--reruns);不稳定测试会与真正的失败测试分开显示 -
自我改进辅导工具(
get_optimization_plan):运行后从三个角度进行分析——测试套件质量、MCP 易用性、AI 生成效果 -
JUnit XML 输出,用于 CI 集成(GitHub Actions / Jenkins / GitLab)
安装
两种方式——根据使用场景选择。
A. 通过 uvx 运行(无需安装,推荐终端用户使用)
无需全局安装,即可将 mk-qa-master 添加到客户端配置中;uv 会在每次会话中从临时环境获取并运行它:
{
"mcpServers": {
"mk-qa-master": {
"command": "uvx",
"args": ["mk-qa-master"],
"env": { "QA_RUNNER": "pytest", "QA_PROJECT_ROOT": "/path/to/your-test-project" }
}
}
}
设置就这么简单。首次调用时会下载软件包;后续调用会使用缓存。切换版本:uvx [email protected] ...。
B. 安装到项目 venv 中(供贡献者 / 开发者使用)
pip install mk-qa-master # or: pip install -e . from a clone
playwright install # only if you use pytest-playwright
pip install pytest-rerunfailures # optional, enables auto-retry
然后将客户端配置指向同一个 Python 解释器:
"command": "/path/to/.venv/bin/python",
"args": ["-m", "mk_qa_master.server"]
验证安装(v1.4+)
mk-qa-master doctor # human-readable check report
mk-qa-master doctor --json # for CI gates / host-LLM consumption
检查 Python 版本、PATH 中的 ffmpeg + mediamtx、核心依赖、[edge] 扩展、运行器注册表和 MCP 工具接口。没有关键项缺失时返回 0(未使用功能的警告不会导致失败);mk-qa-master 无法正常运行时返回 1。可在全新安装后,或 MCP 工具返回 missing_extras 时运行。
Runner 特定前置条件
QA_RUNNER | 还需要 |
|---|---|
pytest / pytest-playwright | pip install pytest-playwright + playwright install chromium |
jest | 安装了 jest 的 Node 项目(npm i -D jest) |
cypress | 安装了 cypress 的 Node 项目(npm i -D cypress) |
go | PATH 中有 Go 工具链 |
maestro | Maestro CLI + 已启动的模拟器 / 仿真器 / 设备(或可通过 adb connect 访问的 BlueStacks) |
schemathesis / api | pip install 'mk-qa-master[api]'(会安装 schemathesis>=3.0,<4) |
newman / postman | npm install -g newman(Newman 是 npm 包,不是 pip 包——无需安装额外依赖) |
API 测试(QA_RUNNER=schemathesis)
将 Runner 指向任意 OpenAPI 3.x / Swagger 2.0 schema,Schemathesis
会为每个操作生成基于属性的测试用例,涵盖响应
schema 一致性、状态码一致性、内容类型检查,以及
模糊测试中的 5xx。结果会像 UI 测试一样,流经相同的
report.json / 历史记录 /
flaky / 优化器流水线。
端到端操作指南见 docs/walkthrough-api.md;
独立的 3 端点示例见
examples/sample_api_project/。
5 行配置
"env": {
"QA_RUNNER": "schemathesis",
"QA_OPENAPI_URL": "https://api.example.com/openapi.json"
}
环境变量
| 变量 | 必需 | 默认值 | 作用 |
|---|---|---|---|
QA_OPENAPI_URL | 是 | — | OpenAPI URL。在线 schema 使用 http(s)://...,本地文件使用 file://...。不接受普通文件系统路径——必须添加 file:// 前缀。 |
QA_SCHEMATHESIS_CHECKS | 否 | all | 逗号分隔的检查子集:response_schema_conformance,status_code_conformance,not_a_server_error,content_type_conformance,response_headers_conformance。 |
QA_SCHEMATHESIS_AUTH | 否 | — | Authorization 标头值。将以 -H "Authorization: <value>" 发送。绝不会记录;归档报告中会做脱敏处理。 |
QA_SCHEMATHESIS_MAX_EXAMPLES | 否 | 20 | 每个操作的 Hypothesis 示例数。值越高 = 模糊测试越深入,运行越慢。 |
QA_SCHEMATHESIS_DRY_RUN | 否 | 0 | 设为 1 可在不发送 HTTP 请求的情况下规划——适用于生产环境安全预览,或针对仅含 schema 的制品进行 CI 冒烟测试。 |
QA_NO_REDACT | 否 | 0 | 禁用归档报告中的机密脱敏。默认会对 Authorization: Bearer …、"password": …、"token" / "api_key" / "secret" / "access_token" / "refresh_token": … 进行脱敏。 |
标准的 QA_TIMEOUT_SECONDS 仍然适用(默认 600s)。
API 测试(QA_RUNNER=newman)
将 Runner 指向任意导出的 Postman 2.x collection,Newman 6.x
会重放每个请求,运行内嵌的 pm.test(...) 断言,并
为每个断言返回一个 mk-qa-master“测试”。结果会像
Schemathesis 和 UI Runner 一样,流经相同的
report.json / 历史记录 / flaky / 优化器流水线。
系统前置条件:Newman 通过 npm 而非 pip 发布。安装一次即可:
npm install -g newman
没有 pip install 'mk-qa-master[postman]' 这个额外依赖——Runner
只会调用 PATH 中的 newman 二进制文件。如果找不到该文件,
Runner 会抛出清晰的 ImportError,并指向 npm 安装命令。
OpenAPI 示例所用的同一个 3 端点 Library API,
也提供了 Postman collection:
examples/sample_api_project/postman-collection.json——
可搭配 prism mock examples/sample_api_project/openapi.yaml,构建完全自包含的开发循环;也可以指向你自己的预发布服务器。
5 行配置
"env": {
"QA_RUNNER": "newman",
"QA_POSTMAN_COLLECTION": "/absolute/path/to/your-collection.json"
}
环境变量
| 变量 | 必需 | 默认值 | 用途 |
|---|---|---|---|
QA_POSTMAN_COLLECTION | 是 | — | Postman 2.x 集合 JSON 文件的普通文件系统路径。不要使用 file:// 前缀——集合始终是本地文件,因此 Newman 无需消除方案歧义。 |
QA_POSTMAN_ENVIRONMENT | 否 | — | Postman 环境文件的普通路径(-e <path>)。为集合中的 {{var_name}} 占位符提供值。 |
QA_POSTMAN_GLOBALS | 否 | — | Postman 全局变量文件的普通路径(-g <path>)。格式与环境文件相同,但作用域为全局。 |
QA_POSTMAN_ITERATIONS | 否 | 1 | 将整个集合重放 N 次(-n <N>)。适用于耐久测试和不稳定测试检测。 |
QA_POSTMAN_FOLDER | 否 | — | 用于限制运行范围的 Postman 文件夹名称 CSV(重复使用 --folder 标志)。如果失败集中在已知文件夹中,run_failed 也会按文件夹范围运行。 |
QA_POSTMAN_TIMEOUT_REQUEST_MS | 否 | 30000 | 每个请求的 HTTP 超时时间,单位为毫秒(--timeout-request)。与限制整个子进程运行时间的 QA_TIMEOUT_SECONDS 不同。 |
QA_NO_REDACT | 否 | 0 | 与 Schemathesis 运行器采用相同的脱敏策略——仅在短暂的调试会话中禁用。 |
标准的 QA_TIMEOUT_SECONDS 仍然适用(默认值为 600 秒)。
AI 视觉挑战求解器(v0.7.0)
无法绕过后端时:Claude 查看 CAPTCHA,mk-qa-master 执行点击。
支持 reCAPTCHA v2(自 v0.7.0 起)和 hCaptcha(自 v0.7.1 起)。
这是该功能系列中第一个将 AI 客户端视觉能力作为关键环节,而非可选功能的能力。两个新的 MCP 工具(inspect_visual_challenge + solve_visual_challenge)可检测当前 Playwright 页面上的 reCAPTCHA v2 或 hCaptcha 图片网格挑战,将其截图供多模态 AI 客户端查看,接收 AI 返回的图块选择结果,并执行点击操作链。运行器负责观察和操作;AI 客户端(Claude / Cursor / Gemini / GPT-4o)才是真正的求解器。
何时使用——第 1 层与第 3 层
内置的 QA 知识层(get_qa_context section="CAPTCHA")定义了三个层级。按顺序选择:
| 层级 | 方法 | 适用场景 |
|---|---|---|
| 1 — 绕过 | reCAPTCHA 测试密钥、功能标志、IP 允许列表、测试模式标头 | 默认选择。适用于约 90% 的情况。 |
| 2 — 降级处理 | 标记为 external_dependency,跳过后续断言 | 无法更改后端,且测试本身并非针对 CAPTCHA 时。 |
| 3 — AI 视觉判断 | 此功能。 | 仅当第 1 层和第 2 层都不适用时(已获授权但无法访问后端的客户站点、使用与生产环境相同 CAPTCHA 的预发布环境、无法通过 IP 允许列表访问的移动网页视图)。 |
同意门控
在你明确选择启用之前,求解器不会执行任何操作。以下两个环境变量用于控制:
| 变量 | 必需 | 默认值 | 用途 |
|---|---|---|---|
QA_VISUAL_CHALLENGE_CONSENT | 是 | false | 必须设为 true,任一工具才能运行。否则,两个工具都会返回 consent_required 错误,其中包含完整的法律免责声明(AI 客户端会将其展示给用户)。 |
QA_VISUAL_CHALLENGE_AUTHORIZED_DOMAINS | 否(建议设置) | — | 工具可运行的域名允许列表,以逗号分隔。设置后,工具会拒绝处理其他域名。未设置时,仅发出警告——继续运行,但会在响应中附上警告,提醒你设置此项。建议在共享 CI / 多租户环境中设置。 |
QA_VISUAL_CHALLENGE_TIMEOUT | 否 | 120 | inspect→solve 周期的挂钟时间预算,单位为秒。遵循 QA_TIMEOUT_SECONDS 的硬性上限。 |
快速开始
"env": {
"QA_RUNNER": "pytest",
"QA_PROJECT_ROOT": "/path/to/project",
"QA_VISUAL_CHALLENGE_CONSENT": "true",
"QA_VISUAL_CHALLENGE_AUTHORIZED_DOMAINS": "client-staging.example.com"
}
之后,当 run_tests 调用返回指向 CAPTCHA 的 external_dependency 失败时,AI 客户端可以升级处理:
mk-qa-master.inspect_visual_challenge() # screenshot + tile grid
→ AI vision picks tiles [0, 4, 7]
mk-qa-master.solve_visual_challenge(
challenge_id="...", selected_tile_indices=[0, 4, 7], confirm=true,
)
→ status: "passed", token: "...", hint: "CAPTCHA verified. Resume your test."
完整操作指南见 docs/walkthrough-visual-challenge.md。
PRD:docs/prd-v0.7-visual-challenge.md。
硬性拦截域名
无论是否已获得同意或在允许列表中,求解器都拒绝操作已知的第三方身份提供商(accounts.google.com、
login.microsoftonline.com、id.apple.com、facebook.com、
login.live.com 等)。没有任何合理的 QA 场景能证明针对他人的登录门户使用
CAPTCHA 求解器是正当的。
隐私
除当前检查→求解周期外,不保留任何截图。遥测日志仅记录布尔结果——绝不记录截图、挑战文本或图块选择。5 分钟 LRU 缓存 每个进程最多保存 10 个待处理挑战,且绝不触及磁盘。
成功率注意事项
实际判断由 AI 客户端的视觉模型完成——Claude Sonnet
4、GPT-4o 和 Gemini 2.5 均内置视觉能力,但它们在 3x3 reCAPTCHA 上的准确率各不相同。每个挑战至少预留一次重试(reCAPTCHA 在锁定前允许尝试三次)。get_telemetry
最终会显示汇总通过率,便于你按客户端调整预期。
范围:v0.7.0 仅支持 reCAPTCHA v2 图像网格。hCaptcha 将在 v0.7.1 中推出。reCAPTCHA v3 / Cloudflare Turnstile 永久不在 支持范围内——它们不会显示可供检查的可见挑战。
OWASP API 安全扫描(v0.8.0)
Schemathesis 可捕获正确性偏差。v0.8.0 新增了一层,用于 捕获通过 schema 检查背后隐藏的安全性偏差。
v0.8.0 推出基于规则的 OWASP API Security Top 10(2023)扫描器,
作为一款新的 MCP 工具:run_api_security_scan。它加载 OpenAPI 3.x
规范,遍历每个(路径 × 方法),并执行五项仅依赖 HTTP
可观测信息的规则:
| OWASP # | 规则 | 触发时的严重程度 |
|---|---|---|
| API1 | BOLA / IDOR——通过篡改路径 ID,alice 的令牌读取了 bob 的对象 | CRITICAL |
| API2 | 身份验证失效——服务器接受 alg:none、格式错误或签名错误的 JWT | MEDIUM / HIGH / CRITICAL,视探测结果而定 |
| API3 | 批量赋值——服务器持久化了 role: admin、is_verified: true 等危险的额外字段 | HIGH |
| API5 | 功能级授权——非管理员用户访问了管理员类端点 | HIGH |
| API8 | 安全配置错误——缺少 HSTS/CSP/X-Frame 标头、允许携带凭据的通配符 CORS | LOW / MEDIUM / HIGH |
API4(速率限制导致的 DoS 风险)、API6(业务流程建模)、API7
(SSRF 回调基础设施)、API9(生产环境侦察)、API10(上游 API)均
暂缓实现——参见 docs/prd-v0.8-api-security.md §3。
同意与授权门槛
与 v0.7 视觉挑战的同意模型一致:
| 变量 | 是否必需 | 作用 |
|---|---|---|
QA_API_SECURITY_CONSENT | 是 | 必须为 true。否则返回 consent_required。 |
QA_API_SECURITY_AUTHORIZED_DOMAINS | 外部主机必需 | 以逗号分隔的允许列表。localhost / 127.0.0.1 默认已获授权。 |
mass_assignment 规则会修改服务器状态——因此不包含在默认类别中。调用方必须主动启用:
categories=["headers", "broken_auth", "bola", "function_authz", "mass_assignment"]。
快速入门
"env": {
"QA_RUNNER": "pytest",
"QA_PROJECT_ROOT": "/path/to/project",
"QA_API_SECURITY_CONSENT": "true",
"QA_API_SECURITY_AUTHORIZED_DOMAINS": "api.staging.example.com"
}
然后让 AI 客户端执行扫描:
mk-qa-master.run_api_security_scan(
spec_url="https://api.staging.example.com/openapi.yaml",
auth={
"token": "alice's bearer token",
"alt_user_token": "bob's bearer token",
"bola_test_ids": {"user_a": [101, 103], "user_b": [202]}
},
severity_threshold="medium"
)
返回 v0.8 安全报告区块:
{
"scan_id": "a3f8d1c9b7e2",
"spec_url": "...",
"base_url": "https://api.staging.example.com",
"categories_run": ["headers", "broken_auth", "bola", "function_authz"],
"rules_ran": ["OWASP-API8-Headers", "OWASP-API2-BrokenAuth", ...],
"ops_scanned": 23,
"severity_threshold": "medium",
"findings": [
{
"rule_id": "OWASP-API1-BOLA-CrossUserDataExposure",
"severity": "critical",
"endpoint": "GET /orders/{id}",
"title": "user_a can read user_b's object id=202 — missing object-level authorization check",
"evidence": {"actor": "user_a", "target_owner": "user_b", "target_id": 202, "probed_path": "/orders/202", "status_code": 200, ...},
"remediation_hint": "Compare the caller's identity to the object's owner before returning..."
},
...
],
"summary": {"total": 7, "by_severity": {"critical": 2, "high": 4, "medium": 1, "low": 0, "info": 0}}
}
Tier 1 基准真值
examples/sample_vulnerable_api/ 附带一个故意包含漏洞的
Flask 应用,其中每个支持的 OWASP 类别都有一对漏洞/安全
端点。在本地运行它,即可查看各项规则的实际表现:
cd examples/sample_vulnerable_api
pip install -r requirements.txt
python app.py # binds 127.0.0.1:5099
# Then from another shell, point run_api_security_scan at
# http://127.0.0.1:5099 + the bundled openapi.yaml
扫描器会在 /vuln/* 上发现全部 5 个类别,并在 /safe/* 上不产生任何
误报。每个 PR 都会通过
Tier 1 实测测试强制验证这一特性。
安全说明
扫描器会运行对抗性测试用例。请勿将其指向你不拥有的生产系统,也不要将其指向任何未经你授权的系统。上文的两个环境变量就是授权约定。
PRD:docs/prd-v0.8-api-security.md。
此前的 v0.8 移动端尝试已搁置——请参阅
docs/v0.8-mobile-postmortem.md,了解我们总结的经验,以及这些经验如何影响 API 安全 PRD 的测试
门槛。
用作 Claude Code / Codex / Hermes / OpenClaw 技能(v0.9.0)
同一个技能文件夹可通过 agentskills.io 约定加载到四种不同的 Agent 宿主中。
除了 MCP 服务形式外,v0.9.0 还将 mk-qa-master 打包为跨宿主 Agent 技能。skills/mk-qa-master/ 文件夹是唯一的
事实来源——同一份 SKILL.md、斜杠命令和参考文档会加载到:
- Claude Code — 通过
.claude-plugin/plugin.json(此仓库是一个 插件市场)。 - OpenAI Codex — 通过
.codex-plugin/plugin.json(Codex 会读取 Claude 风格的 市场)。 - OpenClaw — 从本地检出目录安装:
openclaw plugins install /path/to/mk-qa-master。 - Hermes Agent — 将技能文件夹符号链接到
~/.hermes/skills/。
快速安装(Claude Code)
# Inside Claude Code:
/plugin marketplace add kao273183/mk-qa-master
/plugin install mk-qa-master@mk-qa-master
重启 Claude Code,让技能完成注册。之后,任何 QA 测试提示词都会自动激活该技能——你也可以显式调用斜杠命令:
/mk-qa-master:run-tests login
/mk-qa-master:generate https://staging.example.com
/mk-qa-master:api-security https://api.staging.example.com/openapi.yaml
技能的作用
该技能是一个单文件操作约定,用于指导宿主如何协调使用 mk-qa-master 的 22 个 MCP 工具。它规定了:
- 何时自动激活 — 例如“运行我的测试”“这个测试为什么失败了”“扫描此 API 是否存在 OWASP 问题”等短语会触发它。
- 五种工作流 — 运行测试 / 生成测试 / 调试失败 / 解决 CAPTCHA / 扫描 API。
- 硬性规则 — 原样呈现同意错误;不得静默地使用放宽后的过滤条件重新运行;执行破坏性运行前必须确认。
完整参考请见 skills/mk-qa-master/SKILL.md。
为什么要在 MCP 服务之上提供技能?
MCP 服务让任何客户端都能调用这 22 个工具。技能则让它们可发现且受管理:它为宿主的技能路由器提供足够的上下文,使其能够判断何时使用这些工具,以及应遵循哪种工作流。灵感来自 microsoft/Webwright,它采用了相同的模式。
稳定性承诺(v1.0.0)
22 个工具。架构冻结。变更有版本记录。固定版本即可使用。
mk-qa-master 于 2026-06-02 发布 v1.0.0。MCP 工具接口已锁定:22 个工具、同意门控环境变量、计划 / 首尾标记结构,以及硬性停止黑名单都必须经过弃用周期才能变更。
这对调用方意味着什么
| 如果固定版本为…… | 你将获得…… |
|---|---|
mk-qa-master==1.0.* | 仅补丁版本更新(修复错误;接口不变) |
mk-qa-master==1.* | 次要版本更新(仅增加内容:新工具、新的可选参数、新字段) |
mk-qa-master>=1,<2 | 同上 |
破坏性变更需要提升至 v2.0。弃用至少会提前 1 个次要版本发出警告,并在运行时引发 DeprecationWarning、在 MCP 工具描述中添加“Deprecated:”,且在 docs/MIGRATION-1.x-to-2.0.md 中添加条目(v2.0 工作启动时创建)。
如何落实这项承诺
CI 快照测试(tests/test_v1_schema_snapshot.py)会将 22 个工具的接口冻结在 tests/snapshots/v1/tool_surface.json 中。任何偏差都会导致 CI 失败,除非 PR 设置了 BREAKING_CHANGE_ACK=true,并且 docs/MIGRATION-0.x-to-1.0.md 和 docs/DEPRECATION-POLICY.md 均已存在。仅设置确认标记并不能豁免——相关文档必须齐备。
第二项测试(tests/test_v1_doc_sync.py)会扫描所有公开文档中的工具数量声明;若声明与运行中的服务不一致,就会失败。
阅读契约
docs/MIGRATION-0.x-to-1.0.md— 列出了 v0.7 → v1.0 的所有增量式结构变更。简而言之:v0.10 → v1.0 无需变更。docs/DEPRECATION-POLICY.md— 正式的生命周期:补丁版本 = 错误修复,次版本 = 增量更新,主版本 = 移除(仅在弃用后进行)。docs/prd-v1.0-stability-lock.md— 已锁定的 PRD。
许可证演进计划(v1.2.1 公告)
现在采用 MIT。v2.0 采用 Apache 2.0。
mk-qa-master 宣布将在 v2.0.0 中将许可证从 MIT 更改为 Apache 2.0。此补丁版本(v1.2.1)为正式公告,并启动弃用倒计时。
对你的影响
| 如果你固定使用…… | 你将获得…… |
|---|---|
mk-qa-master==1.0.* / ==1.1.* / ==1.2.* 等 | 永久采用 MIT — 所有 v1.x 版本均采用 MIT 许可证 |
mk-qa-master>=1,<2 | 只要你使用 v1.x,就采用 MIT |
mk-qa-master>=2,<3(v2.0 发布后) | Apache 2.0 |
Apache 2.0 授予的权利严格多于 MIT(明确授予专利权 + 商标保护),同时保留相同的商业用途许可。任何情况下,你的使用权都不会减少。
时间线
- v1.2.1(此版本):仅发布公告,不更改代码。
- 从 v1.3.x 起:仍采用 MIT。在 v2.0 发布前,至少保留一个次版本周期。
- v2.0.0(待定):正式更改许可证。届时将提供 Apache 2.0 LICENSE 文件和 NOTICE 文件、全面检查源文件头,并同步清单。
此外,我们承诺在 v2.0.0 发布后至少 6 个月内维护 v1.x 的错误修复版本。如果你的公司无法立即迁移到 Apache 2.0,仍有充足的过渡时间。
原因
确保长期可持续发展——专利保障、商标保护、明确贡献者的知识产权归属,并提高对企业采购的兼容性。完整的理由和 v2.0 检查清单请参阅 docs/RELICENSING.md。
Edge AI Runner(v1.1.0+)
通过单个
QA_RUNNER=edge标记,实现 RTSP 流 + YOLO 推理 + pytest 断言。
v1.1.0 新增了 Edge AI 推理运行器,可接入 Web 和移动端运行器已在使用的同一 analyze → generate → run 循环。新的 analyze_stream MCP 工具(工具 #22)会探测 RTSP 几何信息,并针对每个检测到的标签生成候选测试用例。
快速安装
pip install "mk-qa-master[edge]" # opencv-python + ultralytics + requests
# Plus the binary deps the runner shells out to:
brew install ffmpeg mediamtx # macOS
# or: sudo apt install ffmpeg + download mediamtx from https://github.com/bluenviron/mediamtx
端到端演练
随附的示例测试夹具 examples/sample_edge_fixture/ 展示了完整流程。已针对 mk-qa-master==1.1.0(Edge AI)、mk-qa-master==1.1.1(维护)和 1.1.2(本文档补丁)完成测试。
1. 配置运行器。 桌面端流程只需设置 3 个环境变量:
export QA_RUNNER=edge
export QA_RTSP_SOURCE="$(pwd)/examples/sample_edge_fixture/factory.mp4"
export QA_MODEL_PATH=yolov8n.pt # ultralytics auto-downloads on first use
可选的调优参数(括号内为默认值):QA_MIN_FPS(25)、QA_LATENCY_SLA_MS(40)、QA_IOU_THRESHOLD(0.5)。
2. 向 Claude / Cursor / 任意 MCP 主机发出请求。 将 mk-qa-master 配置为 MCP 服务(参见接入 Claude Desktop)后,提示词:
“使用随附的标注侧车文件,分析
examples/sample_edge_fixture/factory.mp4中的流,然后为每个标签生成检测测试。”
Claude 调用 analyze_stream → 获得 {width: 320, height: 240, fps: 5, labels: ["forklift", "person"], candidate_tcs: [...]} → 为每个标签调用 generate_test → 将 test_edge_factory_person.py 和 test_edge_factory_forklift.py 写入 PROJECT_ROOT/tests/。
3. 运行。 运行器会启动本地 mediamtx + ffmpeg(文件源通过 RTSP 循环播放),将你设置的 QA_* 环境变量导出为 EDGE_* 环境变量,并调用 pytest。生成的每项测试都会:
- 通过
cv2.VideoCapture(EDGE_RTSP_URL)读取帧 - 将每帧送入 YOLO 后端
- 使用
LatencyTracker跟踪每帧延迟 - 断言至少有一帧在真实标注时间窗口内,按 IoU 阈值检测到对应标签
- 断言 p95 延迟 ≤
EDGE_LATENCY_SLA_MS - 断言在 150 帧窗口内,持续吞吐量 ≥
EDGE_MIN_FPS
报告会写入 PROJECT_ROOT/report.json + junit.xml,归档到 test-results/history/,并像其他运行器一样触发 get_optimization_plan。
Vendor 主机安全默认设置
默认情况下,analyze_stream 会拒绝来自已知监控 / IoT 摄像头厂商域名(Dahua、Hikvision、Ezviz、Axis、Amcrest、Lorex、Swann、Reolink)的 RTSP URL,避免默认流程意外探测公共摄像头流。设置 QA_EDGE_ALLOW_VENDOR_HOSTS=true,即可选择加入自有摄像头测试。
弹性注入(v1.3.0)
v1.3.0 为 Edge 运行新增了一个选择启用的网络降级测试框架。向 generate_test 传入 resilience_mode="netem" 后,生成的 pytest 会使用 Linux tc qdisc(通过 mk_qa_master.edge.resilience.apply_netem)在回环接口上注入 200 ms 延迟和 5 % 丢包,断言运行器在降级情况下仍符合 SLA,然后在拆卸时清除 qdisc。
通过双重保护确保安全:
- 在非 Linux 系统上,
apply_netem会引发RuntimeError(macOS / Windows 主机上的测试会自动执行pytest.skip)。 - 即使在 Linux 上,也必须先设置
QA_EDGE_NETEM_ENABLED=true才能运行——这表示明确同意影响回环接口。
同一模块还提供了 3 个配套辅助函数:clear_netem(幂等拆卸)、kill_ffmpeg_subprocess(进程丢失场景)和 build_corrupted_gop_fixture(由 ffmpeg 驱动的比特流噪声注入)。完整选项请参见 src/mk_qa_master/edge/resilience.py 和 v1.3.0 PRD。
在弹性模式下运行测试时,生成的报告会为每项测试附加一个 edge_metrics 区块(帧丢失、恢复时间等)。get_optimization_plan 会读取该区块,在通常的信号组合之外,呈现 4 种 Edge 专属的不稳定性信号(损坏帧率、恢复时间偏差、突发丢帧和持续延迟违规)。
阶段状态
| 阶段 | 内容 | 状态 |
|---|---|---|
| 1 | 桌面 YOLO 运行器 + RTSP 源管理 + 指标 | ✅ v1.1.0 |
| 2 | analyze_stream MCP 工具 + Edge generate_test 模板 | ✅ v1.1.0 |
| 维护 | 示例固件 + edge-sample CI + EN/zh-TW Edge 知识库章节 | ✅ v1.1.1 |
| 文档 | README 使用指南 + 故障排除(本节) | ✅ v1.1.2 |
| 3 | 远程推理(RemoteHTTP.infer() + QA_JETSON_HOST 实际探测) | ✅ v1.2.0 |
| 4 | 弹性注入 + Edge 波动信号 + 降级场景 | ✅ v1.3.0 |
故障排除
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
Could not open RTSP stream: rtsp://localhost:8554/cam | ffmpeg 或 mediamtx 不在 PATH 中;就绪探测在 10 s 后超时 | 验证 which ffmpeg mediamtx;如果 mediamtx 位于其他位置,设置 QA_MEDIAMTX_BIN=/full/path/to/mediamtx;Apple Silicon 上首次运行较慢——首次启动 mediamtx 后重新运行 |
[edge] setup failed: ConnectionError | 端口 8554 已被其他 mediamtx / RTSP 服务占用 | 设置 QA_RTSP_PORT=8555(或任意空闲端口);生成的测试会读取 EDGE_RTSP_URL,无需修改测试 |
analyze_stream 返回 { "error": "missing_extras", "hint": ... } | 基础安装未包含 [edge] extras | 执行 pip install "mk-qa-master[edge]"(或运行 mk-qa-master doctor 检查完整安装情况) |
{ "error": "forbidden_vendor_host", "blocked_host": "..." } | 默认启用的黑名单(Dahua / Hikvision / 等) | 如果这是你自己的摄像头:export QA_EDGE_ALLOW_VENDOR_HOSTS=true。如果不是:保留拦截设置 |
NotImplementedError: RemoteHTTP backend lands in v1.2 (Phase 3 of theme G) | 你在 v1.1.x 上设置了 QA_JETSON_HOST 或 QA_INFERENCE_ENDPOINT | v1.1 仅提供 LocalYolo。取消设置远程环境变量即可回退到桌面 YOLO。阶段 3 将在 v1.2 推出 |
ultralytics 安装耗时过长 | 首次下载 torch(约 700 MB) | 这是一次性开销。在 CI 中缓存 pip install;本地在安装好 torch 后,使用 pip install --no-deps |
生成的测试断言 hit, "label X not detected",但示例固件只有 testsrc | 合成测试图案不包含真实人物 / 叉车 | 这是内置固件的预期行为(它仅用于验证流程)。如需实际检测断言,请换用真实视频和真实标注;参见 examples/sample_edge_fixture/README.md |
| p95 延迟断言在 CPU 上触发,但在 GPU 上通过 | 默认的 QA_LATENCY_SLA_MS=40 假设使用 GPU 推理 | 对 CPU 运行提高 QA_LATENCY_SLA_MS(CPU 上的 yolov8n 通常为 60–120 ms)。参见 get_qa_context(section="Edge Vision Inference") 中的 SLA 默认值表 |
ffmpeg 提示 Stream #0:0: Video: ... at 5/1 fps | 示例固件有意采用较低的帧率(5),以将二进制文件控制在 75KB | 这是预期行为。进行真实测试时,请提供自己的更高帧率视频源 |
从 v1.0.0 迁移到 v1.1.x
v1.0.0 → v1.1.0 仅为增量更新——没有改变现有工具的结构。v1.1.0 → v1.1.1 → v1.1.2 为补丁版本(维护 + 文档)。v1.2.0 增加了阶段 3(远程推理)。v1.3.0 增加了阶段 4(弹性注入 + Edge 波动信号)。完整变更日志及新增 QA_* 环境变量列表(QA_EDGE_NETEM_ENABLED,……)请参见 docs/MIGRATION-1.x.md。
完整 PRD:docs/prd-v1.1-edge-ai-runner.md。
通用计划 + 验证闭环(v0.10.0)
预先声明成功标准,执行任务,然后获取检查清单——适用于每个重要工具,而不只是一个工具。
v0.10.0 将 v0.9.4 的闭环模式(仅用于 run_api_security_scan)扩展到了 5 个核心工具。每个工具都接受 qa_plan 返回的可选 plan_id 关键字参数。传入该 plan_id 后,工具响应中会新增一个 plan_verification 信封,自动根据你声明的关键点验证工作,无需单独调用 verify_plan。
| 工具 | 证据形式 | 典型 CP |
|---|---|---|
run_tests | pytest-json-report 的 tests 数组(逐项测试结果) | "test_login passes" / "suite duration < 30s" |
solve_visual_challenge | 单条记录:{kind, status, token_populated, rounds_used, fingerprint, challenge_id} — 证据中绝不会包含原始令牌 | "captcha solved AND token_populated" |
analyze_url | 每个发现的模块对应一行(包含 kind、selectors、来源 URL) | "form module discovered" / "≥1 cta found" |
auto_generate_tests | 每个生成的测试对应一行(成功或失败) | "form module produced ≥1 test" / "no generation errors" |
run_api_security_scan(v0.9.4) | 每个 OWASP 发现项对应一行 | "BOLA finding on /orders endpoint" |
plan = qa_plan(
task="Smoke the signup flow",
critical_points=[
{"id": "CP1", "verification_hint": "test_happy_path passes"},
{"id": "CP2", "verification_hint": "BOLA-on-orders"},
],
)
result = run_tests(plan_id=plan["plan_id"])
# result["plan_verification"]["status"] == "passed" | "incomplete" | "failed"
# result["plan_verification"]["checklist"] tells you per-CP outcomes
向后兼容:省略 plan_id 时,响应格式保持 v0.9.x 不变。有关各工具的证据约定和已锁定的决策,请参阅 docs/prd-v0.10-universal-bookend.md。
接入 Claude Desktop(旧版 MCP 专用方式)
如果你更倾向于直接接入 MCP 服务(不使用插件 / 技能层),请将
examples/configs/claude_desktop_config.example.json 复制到:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
运行时由两个环境变量控制:
| 变量 | 示例 | 作用 |
|---|---|---|
QA_RUNNER | pytest / jest / cypress / go / maestro / schemathesis / newman | 选择要使用的测试框架 |
QA_PROJECT_ROOT | /path/to/your/project | 指定待测试项目的路径 |
QA_ANDROID_HOST (可选) | 127.0.0.1:5555 | BlueStacks / Genymotion / Nox / 云端 Android 的远程 ADB 端点。设置后,Maestro 执行器会在每次测试 / analyze_screen 调用前自动运行 adb connect <host>。要求 PATH 中存在 adb。 |
QA_TIMEOUT_SECONDS (可选) | 600(默认值) | 限制任何单次子进程调用的最长时间(pytest / jest / cypress / go test / maestro)。超时后会返回 exit_code=124,并在 stderr 中附带 [TIMEOUT…] 标签,让 AI 客户端能够妥善处理,而不是让 MCP 服务永远挂起。 |
各执行器配置示例
pytest-playwright:
"env": { "QA_RUNNER": "pytest", "QA_PROJECT_ROOT": "/path/to/python-project" }
Jest:
"env": { "QA_RUNNER": "jest", "QA_PROJECT_ROOT": "/path/to/node-project" }
Cypress:
"env": { "QA_RUNNER": "cypress", "QA_PROJECT_ROOT": "/path/to/cypress-project" }
Go test:
"env": { "QA_RUNNER": "go", "QA_PROJECT_ROOT": "/path/to/go-project" }
Maestro(移动端,自 v0.3.0 起):
"env": {
"QA_RUNNER": "maestro",
"QA_PROJECT_ROOT": "/path/to/maestro-flows",
"QA_ANDROID_HOST": "127.0.0.1:5555"
}
QA_ANDROID_HOST 为可选项——仅在通过远程 ADB 连接 BlueStacks / Genymotion / 云端 Android 设备池时设置。iOS Simulator / Android Emulator / 本地 USB 设备会自动发现。
Schemathesis(API):
"env": {
"QA_RUNNER": "schemathesis",
"QA_OPENAPI_URL": "https://api.example.com/openapi.json"
}
Newman(Postman):
"env": {
"QA_RUNNER": "newman",
"QA_POSTMAN_COLLECTION": "/absolute/path/to/collection.json"
}
Edge AI(RTSP + YOLO,自 v1.1.0 起):
"env": {
"QA_RUNNER": "edge",
"QA_RTSP_SOURCE": "/absolute/path/to/factory.mp4",
"QA_MODEL_PATH": "yolov8n.pt"
}
需要运行 pip install "mk-qa-master[edge]",并确保 PATH 中存在 ffmpeg 和 mediamtx。完整的环境变量表和故障排查说明,请参阅 Edge AI Runner walkthrough。
其他 MCP 客户端
MCP 是一种开放协议——此服务并非仅供 Claude 使用。相同的 Python 进程可通过 JSON-RPC stdio 与任何 MCP 客户端通信。不同客户端之间的差异在于:(1)配置文件格式;(2)底层模型自动串联工具调用的可靠程度。
| 客户端 | 配置 | 格式 | 模型 | 工具链质量 |
|---|---|---|---|---|
| Claude Desktop / Cursor | ~/Library/Application Support/Claude/...json · ~/.cursor/mcp.json | JSON | Claude Opus / Sonnet | 测试最充分 |
| Codex CLI | ~/.codex/config.toml | TOML | GPT-5 系列 | 出色(经过大量工具串联训练) |
| Gemini CLI | ~/.gemini/settings.json | JSON | Gemini 3.1 Pro / Flash | 可用;偏好明确的提示词(“先分析,再编写”) |
| Cline / Continue / Zed | 各自有专属的 MCP 配置项 | 不同 | 不同 | 取决于所配置的模型 |
仓库中提供了示例配置:
codex-config.example.toml ·
gemini-config.example.json ·
claude_desktop_config.example.json。
Codex(TOML):
[mcp_servers.mk-qa-master]
command = "/path/to/.venv/bin/python"
args = ["-m", "mk_qa_master.server"]
cwd = "/path/to/mk-qa-master"
[mcp_servers.mk-qa-master.env]
QA_RUNNER = "pytest"
QA_PROJECT_ROOT = "/path/to/your-test-project"
Gemini(JSON,结构与 Claude Desktop 相同):
{
"mcpServers": {
"mk-qa-master": {
"command": "/path/to/.venv/bin/python",
"args": ["-m", "mk_qa_master.server"],
"cwd": "/path/to/mk-qa-master",
"env": {
"QA_RUNNER": "pytest",
"QA_PROJECT_ROOT": "/path/to/your-test-project"
}
}
}
}
工具描述已提示推荐的调用链
(analyze_url → generate_test,生成领域测试前先调用
get_qa_context)。工具选择能力较弱的客户端,从明确写出步骤的提示词中获益最大。
工具概览
所有运行器共享(部分工具在非 pytest 运行器上会优雅降级):
| 工具 | 用途 |
|---|---|
get_runner_info | 当前启用的运行器及所有可用运行器 |
list_tests | 列出项目中的测试 |
run_tests | 运行测试(筛选 / 有头模式 / 浏览器;后两项仅适用于 pytest-playwright) |
run_failed | 重新运行上次失败的测试(pytest --lf) |
get_test_report | 汇总(通过 / 失败 / 跳过 / 耗时 / 本次运行中的不稳定测试) |
get_failure_details | 每项失败的消息及截图 / 跟踪 / 视频路径 |
generate_test | 测试框架;使用来自 analyze_url/analyze_screen 的 module 时,可生成可运行的测试(Playwright .py 或 Maestro .yaml) |
auto_generate_tests | 一步完成:分析 URL → 为发现的每个模块生成一个测试 |
codegen | 启动 Playwright codegen(Web)/ 提示使用 maestro studio(移动端) |
generate_html_report | 将最近一次运行渲染为独立 HTML |
get_test_history | 最近 N 次已归档的运行摘要(用于趋势分析 / 排查不稳定测试) |
analyze_url | Web:探测 DOM → 模块 + 选择器 + 候选测试用例 + API 端点 + 布局溢出警告 |
analyze_screen | 移动端:maestro hierarchy → 表单 / CTA / 标签栏模块 + 候选测试用例(已过滤噪声) |
init_qa_knowledge / get_qa_context | 搭建并读取项目的 QA 知识层(方法论 + 领域)。自 v0.6.2 起支持双语——方法论默认使用英语(QA_LANG=en)或繁体中文(QA_LANG=zh-tw);两种语言均包含相同的 13 个部分,最新加入的四个部分涵盖 API 测试方法论、不稳定测试的根因分类、测试替身(mock / stub / fake / spy)和测试数据管理。领域示例:docs/qa-knowledge-en.example.md(zh-TW:docs/qa-knowledge.example.md)。 |
get_optimization_plan | 三层自我改进指导(测试套件 / MCP / AI 策略) |
inspect_visual_challenge / solve_visual_challenge | v0.7.0 AI 视觉挑战求解器——检测 reCAPTCHA v2 图片网格挑战并截屏,接收 AI 客户端选择的图块,执行点击序列。需启用 QA_VISUAL_CHALLENGE_CONSENT=true,并在每次调用时设置 confirm=true。请参阅上方专门章节。 |
run_api_security_scan | v0.8.0 OWASP API Security Top 10 (2023) 基于规则的扫描器——加载 OpenAPI 3.x 规范,遍历路径 × 方法,并执行 5 项范围内规则(API1 BOLA、API2 Broken Auth、API3 Mass Assignment、API5 Function-Level Authz、API8 Misconfig)。需启用 QA_API_SECURITY_CONSENT=true 和 QA_API_SECURITY_AUTHORIZED_DOMAINS。请参阅上方专门章节。 |
资源
| URI | 内容 |
|---|---|
report://html | 实时渲染的 HTML 报告(深色模式,独立运行) |
report://json | 原始 pytest-json-report JSON |
report://optimization | 最新的 optimization-plan.md |
自我改进循环
每次运行后,_archive_report() 都会将 report.json 快照保存到
test-results/history/,并生成新的 optimization-plan.md,内容涵盖:
- 测试套件质量 — 每项测试的结果字符串(
PFPFP);状态转换 → 不稳定分数;3 次或以上相同特征的失败 → 故障;重跑通过 → 本次运行中的不稳定测试 - MCP 可用性 — 常用工具、错误率、重复参数模式、常见 A→B 调用链(来自遥测 JSONL 日志)
- AI 策略 —
generate_test输出的采用率、analyze_url发现但没有匹配测试文件的模块所暴露的覆盖缺口
计划会生成优先级操作项(high / medium / low),每项都包含
目标 + 依据 + 建议 + 可选的 auto_action_hint,供 MCP 客户端接入下一次工具调用。
项目布局
mk-qa-master/
├── pyproject.toml
├── src/mk_qa_master/
│ ├── server.py # MCP entry (tool routing + telemetry wrap)
│ ├── config.py # Paths + env vars
│ ├── runners/ # Per-framework plugins
│ │ ├── base.py # TestRunner abstract interface
│ │ ├── pytest_playwright.py
│ │ ├── jest.py
│ │ ├── cypress.py
│ │ └── go_test.py
│ ├── reporters/
│ │ └── html.py # Self-contained HTML render
│ └── tools/ # Thin shims + analyzer + optimizer + telemetry
└── tests_project/ # Example project under test
添加运行器
- 创建
src/mk_qa_master/runners/your_runner.py,继承TestRunner, 并实现抽象方法 - 在
runners/__init__.py的REGISTRY中注册名称 - 完成
端到端工作流
预期的流程——从一个 URL 到“下次我应该改进什么”:
flowchart LR
URL[URL] -->|analyze_url| MOD[modules<br/>+ candidate TCs<br/>+ API endpoints]
MOD -->|generate_test<br/>module=...| TEST[tests/test_*.py<br/>runnable skeleton]
TEST -->|run_tests| RES[report.json<br/>+ screenshots<br/>+ trace.zip<br/>+ junit.xml]
RES -->|auto archive| HIST[history/ snapshot]
RES -->|generate_html_report| HTML[HTML report<br/>self-contained]
HIST -->|auto write| PLAN[optimization-plan.md]
PLAN -.->|next session reads| URL
循环才是关键:每次运行都会为优化器提供数据,优化器指出最薄弱的环节,下次运行便优先处理该环节。
演练——测试登录页面
在 Claude / Cursor 会话中:
你:分析
https://shop.example/login,帮我写对应测试Claude:[
analyze_url] 找到 1 个表单(email_password_form_0)和 3 个 API 端点。共 5 个候选测试用例。 [使用表单模块调用generate_test] 已编写tests/test_login.py—— 包含可运行的具体选择器,没有# TODO占位代码。
你:运行
Claude:[
run_tests] 23 项通过,0 项失败,用时 31 秒。已为每项测试捕获截图和步骤跟踪记录。
你:下一步该做什么?
Claude:[打开
report://optimization] 排名第一:tests/test_login.py::test_invalid_credentials不稳定 (flake_score=0.4,结果=PFPFP)。建议:在断言错误消息前,添加wait_for_response('/api/login')。
三个优化视角(测试套件质量 / MCP 易用性 / AI 生成效果)让每个“下一步”答案都有数据依据,而非凭感觉判断。
演练——测试移动应用(Maestro)
流程相同,执行器不同。需要安装 Maestro CLI、启动模拟器/仿真器,并启动你的应用(或传入 launch_app=true
和 app_id):
你:分析移动应用首页的条码按钮,写对应测试
Claude:[
analyze_screen(app_id="com.example.app", launch_app=true)] 找到 15 个交互元素;匹配到barcode_button(text="条码",resource_id="barcodeButton")和候选测试用例。 [使用 CTA 模块调用generate_test] 已编写maestro-flows/test_barcode.yaml—— 包含tapOn: { id: barcodeButton }、waitForAnimationToEnd 和 takeScreenshot, 可直接运行maestro test。
你:运行
Claude:[
run_tests] 5 个流程均通过,未触发重试。截图 已嵌入 HTML 报告。
你:上面这个按钮有时会失败,为什么?
Claude:[
get_optimization_plan]barcode_button::barcode_button被标记为 不稳定(flake_score=0.4,结果=PFPFP,rerun_count=1)。建议:添加waitForAnimationToEnd或extendedWaitUntil,等待动画稳定后再点击。
移动端特有说明:
- 相同的
qa-knowledge.md(内置方法论 + 你的领域知识)会用于 Web 和移动端运行——业务规则只需编写一次。 analyze_screen会过滤掉 iOS 状态栏(信号/Wi-Fi/电量)和资源名称标签(bg_*、*_filled);结果以有效信息为主。- Maestro 的
takeScreenshot: <name>指令决定 HTML 报告中哪些屏幕会以内嵌图片的形式显示。
提示词使用指南
每行都展示了一个可粘贴到 Claude / Cursor 会话中的表达,以及它应触发的底层 MCP 工具调用。可将其作为参考,了解“如何让 AI 执行某项操作,而不用自己指定工具名称”。
一次性设置
| 你说 | Claude 调用 |
|---|---|
| “初始化 QA 知识文件。” | init_qa_knowledge → 将 qa-knowledge.md 写入项目根目录 |
| “向我展示当前的 QA 知识。” | get_qa_context → 方法论 + 你的领域部分 |
| “打开 ISTQB 原则部分。” | get_qa_context(section="ISTQB") |
日常测试
| 你说 | Claude 调用 |
|---|---|
| “运行所有测试。” | run_tests |
| “只运行与登录相关的测试。” | run_tests(filter="login") |
| “只重新运行失败项。” | run_failed |
| “向我展示摘要。” | get_test_report |
| “哪些测试失败了?给我截图和跟踪记录。” | get_failure_details |
| “生成 HTML 报告。” | generate_html_report |
从 URL 构建测试(Web)
| 你说 | Claude 调用 |
|---|---|
"为 https://shop.example/ 自动生成测试。" | auto_generate_tests(url=...) — 一次性完成 |
"先分析 https://shop.example/coupon,然后为每个模块编写一个测试。" | analyze_url → generate_test × N |
| "分析优惠券页面,并针对我们之前的幂等性错误编写回归测试。" | get_qa_context(section="Bug") → analyze_url → generate_test(business_context=...) |
| "只需将结账流程记录为基线。" | codegen(url=...) |
从移动端屏幕构建测试(Maestro)
需要 QA_RUNNER=maestro、Maestro CLI,以及已启动的模拟器/仿真器/设备。
| 你说 | Claude 调用 |
|---|---|
| "分析当前移动应用屏幕,并为条形码按钮编写测试。" | analyze_screen(app_id="com.example.app", launch_app=true) → generate_test(module=<cta>) |
| "测试这个应用上的登录表单。" | analyze_screen(launch_app=true) → 选择 form 模块 → generate_test |
| "覆盖标签栏——为每个标签编写一个流程。" | analyze_screen → 选择 tab_bar 模块 → generate_test |
| "使用 Maestro Studio 录制流程。" | codegen(url=...) 会返回指向 maestro studio 的提示(录制后手动保存) |
BlueStacks/远程 Android 实例:设置 QA_ANDROID_HOST=127.0.0.1:5555
(或 BlueStacks 提供的任意 host:port — 参见 Settings → Advanced → Android
Debug Bridge)。Maestro 运行器会在每次测试和 analyze_screen 前执行 adb connect,
并将 hierarchy 超时延长至 60s,以适应较慢的 TCP-ADB 连接。Genymotion/Nox/LDPlayer/WSA 的工作方式相同;
任何能响应 adb connect 的 host:port 都可以。
持续改进
| 你说 | Claude 调用 |
|---|---|
| "我接下来应该修复什么?" | get_optimization_plan |
"最近 test_login_invalid 是否经常不稳定?" | get_test_history + plan lookup |
| "为什么失败了?给我看看跟踪记录。" | get_failure_details(返回截图/跟踪记录/视频路径) |
提示 — 让 Claude 选择正确的工具
- 明确提及 QA 知识 — 测试优惠券时说“参考 QA 知识”,会促使 Claude 先调用
get_qa_context;只说“测试优惠券”可能会跳过这一步。 - 说明顺序 — 说“先分析,然后编写”,会确保先调用
analyze_url再调用generate_test;“只为 X 编写测试”则会跳过分析。 - 批量还是精准 — “自动生成整个页面的测试” →
auto_generate_tests;“为每个 candidate_tc 编写一个测试” → 手动调用链。 - 调试失败 — 询问“为什么失败了/给我看看截图”会可靠地触发
get_failure_details(现在会返回截图、跟踪记录和视频路径)。
反面模式
- ❌ “运行 5 次,看看是否不稳定” — 运行器会自动重试并记录历史;只需询问“是否不稳定”,让
get_optimization_plan给出答案。 - ❌ “生成 100 个测试” — 噪声大于信号。先使用
get_optimization_plan找出缺失项。 - ❌ “测试所有边界情况” — 过于模糊。应具体表述为“测试此表单的每个
candidate_tc”——明确、范围有限且可追踪。
示例输出
analyze_url(节选)
{
"url": "https://shop.example/login",
"page_title": "Login",
"module_count": 3,
"modules": [
{
"kind": "form",
"name": "email_password_form_0",
"selectors": {
"container": "#login",
"fields": [
{"label": "Email", "selector": "#email", "type": "email", "required": true},
{"label": "Password", "selector": "#password", "type": "password", "required": true}
],
"submit": "button[type='submit']"
},
"candidate_tcs": [
"所有必填欄位為空時送出,應顯示必填錯誤",
"Email 欄位填入格式錯誤的字串(無 @),應顯示格式錯誤",
"Password 欄位輸入後應預設遮蔽(type=password)",
"全部填入合法值後送出,應觸發成功流程"
]
}
],
"api_endpoints": [
{
"method": "POST",
"path": "/api/login",
"status": 401,
"candidate_tcs": [
"POST /api/login payload 缺必填欄位應回 400 + 欄位錯誤訊息",
"POST /api/login 合法 payload 應回 2xx",
"POST /api/login 缺少 auth header 應回 401/403"
]
}
]
}
generate_test 输出(智能模式,包含模块)
"""
Login happy path
Auto-generated from analyze_url module: email_password_form_0 (kind=form)
"""
from playwright.sync_api import Page, expect
def test_login(page: Page):
page.goto('https://shop.example/login')
page.locator('#email').fill('[email protected]')
page.locator('#password').fill('TestPass123!')
page.locator("button[type='submit']").click()
# TC: Email 欄位填入格式錯誤的字串(無 @),應顯示格式錯誤
# TC: Password 欄位輸入後應預設遮蔽
# TC: 正確 Email + 正確密碼 → 導向 dashboard
# TODO: 補上實際斷言,例如:
# expect(page).to_have_url(...)
# expect(page.get_by_text("成功")).to_be_visible()
optimization-plan.md(节选)
# Optimization Plan — 2026-05-12T14:03:40
_Based on 6 archived runs._
## Prioritized Actions
### 1. 🔴 HIGH — flaky
- **Target**: `tests/test_login.py::test_invalid_credentials`
- **Evidence**: flake_score=0.4, outcomes=PFPFP, rerun_count=1
- **Suggestion**: 加 explicit wait(wait_for_response / locator wait)
### 2. 🟡 MEDIUM — coverage_gap
- **Target**: `register_form`
- **Evidence**: 由 analyze_url 偵測但 repo 內找不到對應 test_*.py
- **Suggestion**: `call generate_test(description="...", filename="test_register_form.py")`
HTML 报告
打开实时渲染演示 →
(通过 GitHub Pages 提供 — 在 GitHub 界面中点击
sample_report.html 链接只会显示源代码)。
演示展示了统计网格、趋势迷你图、包含嵌入截图和步骤列表的失败卡片,以及折叠的“已通过”部分。
集成
mk-qa-master 不捆绑第三方 SDK——它保持为纯粹的
测试执行与分析层。实际的 QA 工作流通过在同一客户端配置中并行运行
多个 MCP 服务来组合;Claude 负责编排跨服务的调用链。MCP 之间没有
RPC——每个服务彼此独立,由 AI 客户端负责协调。
以下配套组合最常用于完成整个流程:
| 配合使用 | 原因 | 示例调用链 |
|---|---|---|
| Atlassian MCP (JIRA + Confluence) | 根据失败自动创建缺陷工单;将 optimization-plan.md 同步到团队的 Confluence 页面 | run_tests → get_failure_details → atlassian.createJiraIssue (附加截图 + 跟踪路径) |
| Slack MCP | 失败时通知频道,分享渲染后的 HTML 报告,并提醒值班人员处理不稳定测试 | generate_html_report → slack.send_message(channel="#qa-bots", attachments=...) |
| GitHub MCP | 生成测试前,读取 PR 描述 / 关联问题以了解业务背景;将结果作为 PR 评论发布回去 | github.get_pull_request → analyze_url → generate_test(business_context=PR body) → github.create_issue_comment |
| Sentry MCP | 生产环境错误决定回归测试的优先级:高频崩溃 → 匹配的回归测试 | sentry.list_issues(sort="frequency") → generate_test(business_context=stack trace) → run_tests |
| Filesystem MCP | 读取位于 QA_PROJECT_ROOT 之外的共享 qa-knowledge.md 或 TC 源文件(单体仓库、多项目设置) | filesystem.read_file("~/shared/qa-knowledge.md") → init_qa_knowledge |
特别提及——Google Drive MCP:适用于基于 Google 表格的 TC 管理(从表格读取 TC → generate_test → 写回状态)。
在客户端配置中组合
这五个服务与 mk-qa-master 一样,作为独立进程运行:
{
"mcpServers": {
"mk-qa-master": { "command": "python", "args": ["-m", "mk_qa_master.server"], "env": { "QA_RUNNER": "maestro" } },
"atlassian": { "command": "npx", "args": ["-y", "@atlassian/mcp"] },
"slack": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-slack"] },
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] }
}
}
然后只需一条提示词即可串联整个流程:
“运行结账测试套件。对于每个失败项,在项目 QA 中按照 RIDER 格式创建 JIRA 工单,并附上截图。完成后,将 HTML 报告发布到 #qa-bots。”
这样做的意义在于:mk-qa-master 可以专注于测试循环
(分析 → 生成 → 运行 → 辅导)。JIRA / Slack / Sentry 都是有各自专用服务的完整
领域——把它们塞进这一个服务会模糊职责范围、重复处理身份验证,并迫使每位用户
继承他们可能并不需要的依赖。
本仓库不捆绑任何第三方 SDK——它保持「测试执行 + 分析」的单一职责。实际的 QA 工作流通过并行运行多个 MCP 服务,并由 Claude 编排跨服务的工具调用链来实现。示例组合:JIRA / Slack / GitHub / Sentry / Filesystem 各自作为独立 MCP 服务,与 mk-qa-master 配合,组成完整的测试流水线。
发布(仅维护者)
通过 Trusted Publishing 将版本发布到 PyPI——仓库中不会存储 API 令牌。流程如下:
- 在
pyproject.toml中更新version = "x.y.z"(通过常规 PR 操作——main 已启用分支保护)。 - 合并后,为 main 创建标签并推送:
git tag -a vX.Y.Z -m "vX.Y.Z — short summary" git push origin vX.Y.Z - 为该标签创建 GitHub Release(
gh release create vX.Y.Z ...)。 - release 事件会触发
.github/workflows/publish.yml→ 构建 sdist + wheel → 上传到 PyPI。
PyPI 一次性设置(首次发布前必须完成):
- 登录 https://pypi.org → 启用 2FA。
- 项目页面 → Settings → Publishing → 添加一个待定发布者,并填写:
- 所有者:
kao273183 - 仓库:
mk-qa-master - 工作流文件名:
publish.yml - 环境名称:
pypi
- 所有者:
首次成功运行后,PyPI 会自动将待定发布者升级为可信发布者,后续版本会通过 OIDC 进行身份验证。
如果 release 标签与 pyproject.version 不匹配,工作流会拒绝发布,从而在错误上传到 PyPI 前发现“创建了标签但忘了更新版本”的问题。
支持本项目 ☕
mk-qa-master 由我一人利用夜晚和周末开发并维护。如果它为你节省了时间,或影响了你的团队对 AI 驱动 QA 的看法,请请我喝杯咖啡,让我继续深夜调试 Maestro:
你的支持将用于:让此仓库保持免费并积极维护,为 Maestro 测试增加更多设备类型(真实 iPhone / Android 平板 / BlueStacks),为 QA 社区录制教程,以及支持下一次凌晨 2 点的 Bug 排查。
没有广告、没有赞助、没有企业版推销——只有开发工作。
贡献
此仓库由我一人维护。非常欢迎提出想法和报告 Bug——请提交 Issue 或发起 Discussion。我会逐一阅读,并实现符合项目方向的内容。
**外部 pull request 会被自动关闭。**这并非不欢迎贡献,而是相比多人协作模式带来的效率,保持代码库风格统一对本项目更重要。如果你确实希望进行某项具体更改,提交 Issue 描述问题会比 PR 更有效。
本仓库由我一人维护。欢迎通过 Issue / Discussion 提出想法或报告问题,我会亲自评估并实现。外部 PR 会自动关闭——不是不欢迎贡献,而是希望保持代码风格与项目方向一致。
许可证
MIT © 2026 Jack Kao — 请参阅 LICENSE
(中文翻译参考:LICENSE.zh-TW.md;英文版本具有权威性)。
简单来说:你可以将其用于任何用途(个人项目、商业工作、修改和再分发)。唯一的要求是,在你发布的任何副本中保留版权和许可证声明。本软件不提供任何保证——使用风险自负。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。