本地测试自动化框架
自动化工作区,用于配置Conduit RealWorld演示应用程序,填充确定性数据,并在本地基础设施上完全运行API、UI和LLM提示验证。
特点/功能
- 基于PostgreSQL的演示应用程序 通过Docker Compose进行部署,包含健康检查和确定性迁移。
- 捆绑式导管RealWorld演示应用程序,附带一个引导脚本,该脚本可在无需额外git克隆的情况下安装依赖项并运行迁移。
- 确定性的种子数据通过公共API创建了五个用户和十条文章。
- 健康护栏在 pytest 执行前验证前端、后端和数据库的准备情况。
- Pytest测试套件涵盖了REST CRUD操作、身份验证、分页功能,以及支持多上下文(桌面+移动)的Playwright UI流程。
- 在每次运行中都内置了Allure报告,附带API响应、Playwright追踪和LLM输出的附件。
- 双模式大语言模型(LLM)测试稳定性测试(有限次重试)+ 严格的质量审核(零重试,旨在暴露模型缺陷)。
- 基于Ollama + Promptfoo构建的用于小型本地模型的提示评估工具
gemma3:4b,deepseek-r1:8b)并通过(某种方式)进行判断验证gpt-oss:20b。 - 真正的缺陷检测 当模型产生幻觉时,大型语言模型(LLM)测试可以并且应该失败,这证明了测试框架的有效性。
- 源自(某处/某种方法)的打包提示套件
llm-prompt-testing-quick-start,每个都有其独立的配置用于单独评估。 - GitHub Actions CI流水线验证API、UI和LLM套件,并为每次推送/拉取请求存档Allure包。
- 可选集成Playwright MCP服务器,以在同一工作区中进行交互式定位器捕获。
项目布局
.
├── config/ # Environment, seed, and promptfoo configs
├── demo-app/ # Vendored RealWorld example app (frontend + backend sources)
├── scripts/ # Bootstrap, seeding, and health utilities
├── src/ # Shared helpers (API client, health, ollama)
├── tests/
│ ├── api/ # Requests-based API coverage
│ ├── ui/ # Playwright MCP multi-context UI coverage
│ └── llm/ # Promptfoo + Ollama integration tests
├── promptfoo/ # Offline prompt suites and shared templates
├── docker-compose.yml # Optional container stack for postgres/backend/frontend
├── Makefile # Friendly entry points
├── pyproject.toml # Python dependencies + pytest config
└── package.json # Node dependencies for promptfoo先决条件
- Python 3.10+(或更高版本)
pip以及虚拟环境支持(python3-venv在Debian/Ubuntu上。 - Node.js 18+(演示应用和Promptfoo CLI所需)。
- Docker + Docker Compose(可选,但可简化演示应用+PostgreSQL的编排)。
- Allure 命令行
brew install allure,scoop install allure(或从 JetBrains 下载)。 - 本地安装的Ollama可访问以下模型:
- ollama pull gemma3:4b - ollama pull deepseek-r1:8b - ollama pull gpt-oss:20b
- PostgreSQL 客户端工具
psql)用于迁移和健康检查。
快速入门
- 安装Python依赖项
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt- 安装Node依赖项
npm install- 提供RealWorld演示应用程序
make demo:setup # Installs workspaces, writes backend .env, runs migrations
make demo:seed # Populates five users + ten articles through the public API> 此仓库随附了RealWorld前端+后端的源代码。 make demo:reset 简单地移除工作区 node_modules 在重新安装之前。
- 启动堆栈(Docker Compose)
make compose:up # brings postgres + backend + frontend up in the background
make check:health # waits for backend/frontend/database readiness完成后,运行 make compose:down 使集装箱停止。
> 更喜欢手动工作流程?你仍然可以运行 (cd demo-app/src && npm run dev) 在两个终端中启动后端(3001)和前端(3000),无需使用Docker。
- 种子演示数据(每个环境可选一次)
make demo:seed在第一次之后pip/npm安装时,所有RealWorld资源和提示套件都已打包集成,因此整个测试栈可以离线运行。
测试套件
| 命令 | 描述 | 预期行为 |
|---|---|---|
make test:api | 基于请求的CRUD(创建、读取、更新、删除)、认证和分页测试 | 应始终通过 |
make test:ui | Playwright MCP 多上下文运行 (--headed | 应始终通过 |
make test:llm | 由Ollama驱动的文章生成(为稳定起见重试2次) | 应在CI(持续集成)中通过,本地可能偶尔失败 |
make test:llm:audit | 严格的LLM质量审核 (零重试,统计分析) 预计使用劣质模型会失败 | |
make test | 完整的 pytest 套件(除 llm_audit 外的所有标记) | 稳定性均衡 |
所有 pytest 运行都会将 Allure 结果写入 allure-results/通过以下方式生成报告:
make report # opens Allure dashboard in a browser大型语言模型(LLM)测试理念:双模式方法
这个框架实现了 两种互补的大语言模型(LLM)测试策略:
1. 稳定性测试 (test_article_generation.py, @pytest.mark.llm)
- 目的持续集成/持续交付(CI/CD)的可靠性,冒烟测试
- 重试逻辑每个场景最多尝试2次
- 失败阈值仅在所有重试尝试均失败时才视为失败
- 使用方法:
make test:llm或者pytest -m llm - 预期结果在CI中传递(带有
USE_FAKE_OLLAMA=1),当地偶尔出现局部剥落现象
2. 质量审核测试 (test_article_quality_audit.py, @pytest.mark.llm_audit)
- 目的真正的缺陷检测,模型评估
- 重试逻辑: 零重试 - 第一次尝试必须通过
- 故障阈值如果任何模型在5次迭代中的成功率低于60%,则判定为失败
- 用法:
make test:llm:audit或者pytest -m llm_audit --verbose - 预期结果: 小模型失败 (gemma3:4b,deepseek-r1:8b)
为什么这很重要审计测试是 设计成会失败 当模型产生幻觉、离题内容或不连贯的输出时。测试失败证明该框架能够检测出大型语言模型(LLM)的真实缺陷,而不仅仅是通过重试等临时解决方法来通过测试。
审计失败的解读
当 test_article_quality_audit.py 失败:
✅ 这是成功 - 测试已检测出真实模型的弱点\ ✅ 检查Allure附件以获取详细的失败分析(幻觉、判断推理)\ ✅ 查看“质量审核报告”附件中的成功率和建议
模型替换指南 (来自审计报告):
- 成功率低于40%🔴 立即更换模型
- 成功率40%-60%🟡 考虑更换或及时调整
- 成功率60%-80%🟢 适用于本地测试(可接受)
- 成功率 > 80%🟢 模型表现良好
示例:在本地运行审计测试
# Start the stack
make compose:up
make demo:seed
# Run strict quality audit (WILL LIKELY FAIL with small models)
make test:llm:audit
# View detailed failure analysis
make report # Check "quality_audit_report" and "FAILURE_*" attachments预期的gemma3:4b审计输出结果:
## gemma3:4b
- Success Rate: 53.3% (8/15)
- Recommendation: 🟡 CONSIDER REPLACEMENT - Model is marginal
### Failure Breakdown:
- judge_rejected (hallucination/incoherence): 4 occurrences
- off_topic (coverage 33%): 2 occurrences
- too_short (245 `它们改编自 `llm-prompt-testing-quick-start` 仓库已重新开发,以完全在本地Ollama模型上运行。使用以下方式评估捆绑的文章撰写工具套件:
make promptfoo
or watch mode
make promptfoo-watch
可用套房:
- `articles` – 按照评分标准进行结构化文章撰写。
- `is_nlq_agent_prompt` – 对自然语言问答(NLQ)进行JSON评分。
- `is_nlq_minimal_agent_prompt` – 轻量级的“是/否”验证。
- `nlq_to_sql` – 带聚合查询的SQL合成。
- `nlq_to_sql_experiment` – 以JOIN为重点的SQL提示。
- `try_this_nlq_agent_prompt` – 带有行数限制的自然语言问题生成。
你可以单独运行一个测试套件 `npx promptfoo eval --config promptfoo/suites//promptfooconfig.yaml`。
### Pytest + Ollama(注:Ollama是一个用于运行和管理大型语言模型的工具,这里直接保留原名,不做具体翻译)
该框架包含两个互补的测试模块:
#### `test_article_generation.py` - 稳定性测试
从(指定位置)读取提示模板 `promptfoo/prompts/articles.yaml`使用Jinja2进行渲染,并且采用 `OllamaRunner`/`gpt-oss:20b` 收件人:
1. 使用每个轻量级模型生成内容(为确保稳定性,最多尝试2次)
1. 确保字符长度符合要求(300-500个字符)
1. 使用关键词启发式方法验证主题覆盖范围
1. 通过(某种方式)判断验证 `gpt-oss:20b` 带有重试逻辑
1. 将所有尝试(包括失败的尝试)附加到Allure中
**用例**CI/CD 管道,冒烟测试(设置 `USE_FAKE_OLLAMA=1` (对于确定性存根)
#### `test_article_quality_audit.py` - 质量审计(新增)
实施(措施/计划等);实现 **严格的零重试验证** 揭示模型的真实缺陷:
1. 每个模型对每个场景运行5次迭代(具有统计显著性)
1. **不重试** - 每次尝试都必须通过裁判验证
1. 如果模型成功率低于60%,则测试失败
1. 生成包含以下内容的全面审计报告:
- 每个模型的成功率及失败原因细分
- 可操作的替换建议
- 所有失败输出均附加到Allure(报告/系统中)
1. 证明测试框架能够检测幻觉/不连贯性
**用例**本地模型评估,展示测试严谨性(预期小型模型会失败)
**关键区别**稳定性测试以可靠性(重试)为优先,审计测试以缺陷检测(零重试)为优先。
输出、提示、判决结果以及统计摘要均附在Allure中,以便进行追溯。
### Playwright MCP(可选)
在RealWorld前端运行时,启动MCP助手以捕获DOM片段和选择器:
npm run mcp -- --url http://localhost:3000/#/
服务器公开了模型上下文协议命令,Cursor 或 Claude 等工具可以利用这些命令来生成 Playwright 流程。详见终端内的说明。
## 设置说明
- **PostgreSQL 是默认数据库** - 使用 Docker Compose 进行配置,健康检查和数据库迁移由 Sequelize 管理。
- 该仓库故意忽略了 `demo-app/src/` 并且 `promptfoo/source/` 这样你就可以自由地更新上游项目,而不会污染Git历史记录。
- 更新 `config/demo.env` 以与自定义端口、数据库凭据或Ollama终端节点对齐。
- 如果你依赖Docker,请确保 `demo-app/src` 之前存在 `docker compose up` 因此,卷挂载成功了。
- 数据库凭据默认为 `conduit/conduit` (用户名/密码)用于 `conduit_local` 运行在(某处/某个系统/某个平台上)的数据库 `localhost:5432`。
## 故障排除
- **缺少的Python包** – 创建一个虚拟环境(`python3 -m venv .venv`) 在安装之前 `requirements.txt`.
- **`ollama` 错误** – 确认守护进程正在运行(`ollama serve`) 并且模型在本地进行拉取。
- **未找到 Promptfoo CLI** – 跑 `npm install` 放置 `promptfoo` 在 `node_modules/.bin`,或者通过调用 `npx promptfoo`.
- **缺少用于编写测试脚本的浏览器** – 之后 `pip install`,运行 `python -m playwright install --with-deps chromium`.
- **Allure CLI 不可用** – 全局安装或使用 Docker`docker run -p 4040:4040 -v $PWD/allure-results:/app/results frankescobar/allure-docker-service`)。
- **GitHub Actions 失败** – 复习/回顾 `.github/workflows/ci.yml` 重新播放 `npm install`, `python scripts/health_check.py`, `python scripts/seed_demo_data.py`,和 `python -m pytest` 在本地,然后检查工作流运行中上传的所有ure(Allure)工件。
## 已知的差距与未来的改进方向
### 行之有效的做法 ✅
- **双模式LLM测试** 在保持持续集成(CI)稳定性的同时,成功暴露模型缺陷
- **PostgreSQL 集成** 通过Docker编排提供类似生产环境的数据库行为
- **全面魅力报告** 捕获所有故障模式以进行分析
- **健康检查** 防止因基础设施时序问题导致的间歇性测试失败
### 潜在改进点 🔄
- **模型替换建议**目前为手动操作;可根据故障模式自动建议特定的替换型号(例如,“gemma3:4b → llama3:8b”)
- **历史趋势追踪**长期持续审计结果以检测模型退化
- **SQLite 降级方案**添加可选的 SQLite 模式,以便在没有 Docker 的情况下进行超快速的冒烟测试
- **视觉回归**扩展UI测试,通过截图对比进行CSS/布局验证
- **裁判共识**使用多个评判模型来减少单一评判模型中因不稳定因素导致的误报(假阳性)
- **并行审计执行**并行运行审计迭代以加快本地反馈速度
### 设计决策 📋
- **为什么要允许大语言模型(LLM)测试失败?** 小型本地模型(如gemma3:4b、deepseek-r1:8b)经常会产生幻觉。通过过多重试来掩盖失败会损害测试的可信度。审核失败证明了框架的有效性。
- **为什么选择Postgres而不是SQLite?** 生产环境使用的是PostgreSQL;而使用SQLite进行测试会让人对数据库兼容性(事务处理、并发访问、JSON操作符)产生错误的信心。
- **为什么审计采用60%的门槛?** 经验调优——低于60%表明模型存在系统性问题,高于60%则表明局部测试质量可接受。