🚀 QA自动驾驶仪
Pytest插件-玩家之光故障的实时AI诊断
      
安装 • 快速开始 • 记分卡 • 它是如何工作的 • 配置
______________________________________________________________________
🎯 问题
Playwright测试失败。错误消息显示:
TimeoutError: Page.click: Timeout 5000ms exceeded.
waiting for locator("a[href='/international/']")选择器是好的。元素存在。 那为什么它不起作用呢?
因为Cookie横幅覆盖了一切。或者因为元素在iframe中。或者因为DOM是用AJAX重新加载的。或者因为按钮是 disabled或者因为你做了 click() 代替联合国 dblclick().
QA自动驾驶仪在一个命令中诊断真正的原因。
______________________________________________________________________
📊 记分卡
结果在一系列 7陷阱测试 设计用于捕获诊断工具:
| 测试 | 陷阱 | AI诊断 | 类别 | 信任 |
|---|---|---|---|---|
| 🫣覆盖Cookie | 横幅覆盖元素 | ✅ Cookie横幅阻止点击 | element_obscured | 🟢 95% |
| 🖼️ iframe不可见 | iframe中的元素,在主帧中搜索 | ✅ 缺少iframe上下文 | iframe_context | 🟢 95% |
| 👻 stale ajax | 重新加载dom之前捕获的定位器 | ✅ Ajax之后的引用已弃用 | stale_reference | 🟢 95% |
| ↪️ 静默重定向 | 重定向URL 301/302 | ✅ 测试通过(检测到陷阱) | - | ✅ |
| 🚫 按钮禁用 | 项目可见但禁用 | ✅ 检测到禁用属性 | element_disabled | 🟢 95% |
| 🔤 正则表达式Unicode | Zinedine 对比 Zinédine | ✅ Regex中的不匹配重音 | encoding_mismatch | 🟢 95% |
| 🫣双击 | 同意管理器拦截单击 | ✅ 检测到覆盖 | element_obscured | 🟢 95% |
6/6 95%置信度的正确诊断 -第七次测试通过(无需诊断)。
______________________________________________________________________
⚠️ 局限性
\[!小心\] 测试+200行: 发送到AI的上下文被故意截断。 E2E测试必须保持简短-一个场景,一个责任,少于50行。 除此之外,这是一个设计问题,而不是诊断问题。 在寻找失败原因之前重构测试。
📦 安装
QA Autopilot是一个本地Python模块,可直接从PyPI获得:
pip install qa-autopilot仅此而已。没有配置,没有服务器,没有帐户。一条线。
具有自动加载 .env :
pip install qa-autopilot[dotenv]或来自来源:
git clone https://github.com/julienmerconsulting/qa-autopilot.git
cd qa-autopilot
pip install -e .先决条件
playwright install chromium配置 .env
创建文件 .env 在项目的根源:
# OpenAI (défaut)
OPENAI_API_KEY=sk-...
# Ou DeepSeek
BASE_URL=https://api.deepseek.com
API_KEY=sk-...
QA_MODEL=deepseek-chat
# Ou Ollama local (zéro coût)
BASE_URL=http://localhost:11434/v1
API_KEY=ollama
QA_MODEL=llama3______________________________________________________________________
⚡ 快速开始
Pytest模式(推荐)
向pytest命令添加单个标志:
pytest tests/ --qa-autopilot -v仅此而已。每个故障测试都会收到自动AI诊断。
使用HTML报告
pytest tests/ --qa-autopilot --html=qa-reports/rapport.html --self-contained-html -v独立模式
python -m qa_autopilot tests/test_checkout.py
python -m qa_autopilot tests/test_login.py::test_auth
python -m qa_autopilot tests/ -k "checkout" --headed模式直接导入
from qa_autopilot import QAInterceptor
# Dans ton test
interceptor = QAInterceptor(page)
interceptor.start()
# ... ton test ...
# En cas d'échec
diagnosis = interceptor.diagnose(error_message, "test_file.py")
print(diagnosis["root_cause"])
print(diagnosis["category"])______________________________________________________________________
🔍 它是如何工作的
┌─────────────────────────────────────────────────────┐
│ TON TEST PLAYWRIGHT │
│ │
│ page.goto("https://example.com") │
│ page.click("#submit") ← FAIL │
│ expect(page).to_have_url(...) │
└──────────────────────┬──────────────────────────────┘
│
┌─────────────▼─────────────┐
│ QA AUTOPILOT HOOK │
│ (écoute en parallèle) │
└─────────────┬─────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌───────────┐
│ DOM │ │ RÉSEAU │ │ CONSOLE │
│Listener│ │ Capture │ │ Capture │
│ (JS) │ │ req/res │ │ err/warn │
└───┬────┘ └────┬─────┘ └─────┬─────┘
│ │ │
└────────────────┼───────────────────┘
│
┌───────────▼───────────┐
│ BUNDLE CONTEXTE │
│ code + erreur + DOM │
│ + réseau + console │
│ + screenshot (opt) │
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ UN PROMPT → IA │
│ (12 catégories) │
│ diagnostic + fix │
└───────────┬───────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌────────┐ ┌───────────┐ ┌──────────┐
│Terminal│ │ JSON │ │ Jira │
│ Output │ │ Report │ │ (si bug) │
└────────┘ └───────────┘ └──────────┘5步管道
- 挂钩透明 -通过本地事件插入Playwright页面
- 并行捕获 -DOM(注入JS侦听器)、网络、控制台、屏幕截图
- 故障检测 -Pytest钩子拦截
FAILED - 捆绑+提示 -整个上下文在IA调用中共享
- 诊断 -根原因+类别+具体修复+JSON报告
______________________________________________________________________
🏷️ 12类诊断
| 图标 | 类别 | 描述 |
|---|---|---|
| 🎯 | wrong_selector | 选择器损坏、不存在或太宽 |
| ⏭️ | missing_step | 缺少步骤(Cookie、goto、dropdown) |
| ⏱️ | timing | 比赛条件,项目尚未准备好 |
| 🫣 | element_obscured | 覆盖元素/模态/横幅 |
| 🚫 | element_disabled | 已找到但已禁用的项目 |
| 🔀 | wrong_action 错误的方法(单击vs dblclick,填充vs类型) | |
| 🖼️ | iframe_context | 在错误的帧中查找项目 |
| 🔤 | encoding_mismatch Unicode/Accents/Regex问题 | |
| 👻 | stale_reference | 更改DOM后已弃用定位器 |
| 📊 | test_data | 具有错误预期值的断言 |
| 🐛 | app_bug | 应用程序错误(不是测试)→生成JIRA票证 |
| 🌐 | network 失败的网络请求(4xx/5xx) |
______________________________________________________________________
⚙️ 配置
环境变量
| 变量 | 缺陷 | 描述 |
|---|---|---|
OPENAI_API_KEY | *(如果没有API-KEY,则需要)* | CléAPI开放人工智能 |
API_KEY | *(可选)* | 替代提供商的密钥(Deepseek、Ollama…) |
BASE_URL | None (原生OpenAI) | 提供商LLM的基本URL |
QA_MODEL | gpt-4.1-mini | 要使用的IA模型 |
QA_SCREENSHOT | 0 | 1 要在提示符中包含屏幕截图 |
QA_REPORT_DIR | qa-reports/ | 关系档案 |
参数pytest
pytest tests/ --qa-autopilot # Active le diagnostic IA
pytest tests/ --qa-autopilot --headed # Avec navigateur visible
pytest tests/ --qa-autopilot -k "login" # Filtrer par keyword______________________________________________________________________
📁 关系结构
qa-reports/
├── summary_20260223_014751.json # Rapport consolidé du run
├── diag_test_casse_20260223_014713.json # Diagnostic individuel
├── diag_test_casse_20260223_014659.json
├── jira_test_casse_20260223_014659.md # Ticket Jira (si app_bug)
└── rapport.html # Rapport HTML pytest合并报告示例
[
{
"test": "test_element_cache_par_overlay[chromium]",
"category": "element_obscured",
"confidence": 0.95,
"root_cause": "L'élément ciblé est recouvert par le bandeau cookies",
"suggested_fix": "Fermer le bandeau cookies avant de cliquer"
}
]______________________________________________________________________
🏗️ 建筑
qa-autopilot/
├── qa_autopilot/
│ ├── __init__.py # Exports publics
│ ├── core.py # QAInterceptor + capture
│ ├── prompt.py # Prompt v2 (12 catégories)
│ ├── diagnose.py # Appel IA + retry + JSON mode
│ ├── reporter.py # Rapports JSON + Jira markdown
│ ├── listener.js # DOM listener (injection navigateur)
│ └── plugin.py # Hooks pytest
├── tests/
│ ├── test_casse.py # Suite de tests pièges
│ └── conftest.py
├── examples/
│ └── standalone.py # Exemple d'utilisation directe
├── pyproject.toml
├── LICENSE
└── README.md注: 当前版本是一个单片文件 qa_autopilot.py (约600行)。 上述细分是V2的目标。______________________________________________________________________
🆚 还有其他选择吗?
||QA自动驾驶仪|剧作家MCP(23K线)|SaaS(Testim、Mabl…)| |:--|:--|:--|:--| | 代码行 |~600|23000+|关闭| | 安装 | pip install |MCP服务器+配置|组件+许可证| | 配置 |1标志|32 MCP工具|仪表板+集成| | 奖 |免费+OpenAI密钥 | 诊断 |12个类别,95%|基本|可变| | 厂商锁定 |MCP协议总计|
______________________________________________________________________
🛠️ DOM监听器——级联6层
注入浏览器的JavaScript侦听器使用6个级别的选择器级联,从最稳定到最不稳定:
| 策略 | 示例 | |
|---|---|---|
| 1 | data-testid / id / name | [data-testid="submit-btn"] |
| 2 | aria-label / placeholder / title | [aria-label="Fermer"] |
| 3 | href (留置权) | a[href="/checkout"] |
| 4具有稳定属性的父级 | [data-testid="form"] button | |
| 5 | 标签关联(输入) | //label[contains(text(),"Email")]//input |
| 6 | CSS法庭+ nth-of-type | button.primary:nth-of-type(2) |
每个选择器在DOM中的唯一性都经过验证。包括阴影DOM支持。
______________________________________________________________________
🤝 贡献者
欢迎贡献-问题、错误报告、拉取请求。
______________________________________________________________________
📄 许可证
麻省理工学院-做你想做的事。
______________________________________________________________________
创建人 朱利安·梅尔 --JMer咨询
*QA架构师·20多年经验·卡塔隆欧洲顶级合作伙伴*

