基于 Dify 知识库 + Ollama 大模型,自动生成测试用例并导出 XMind 的完整方案
告别手动写测试用例,让 AI 帮你从知识库中提取业务信息,自动生成高质量测试用例
---最近很多测试应该使用AI skill方法生成测试用例,那有其他什么方式进一步提高测试用例的准确性,估计要用到了知识库,本文大概整理出一套落地思路
一、背景
在日常测试工作中,编写测试用例是一项耗时且重复的工作。尤其是当业务逻辑复杂、涉及多个模块时,测试人员需要:
- 翻阅大量需求文档、产品说明
- 理解业务逻辑,提取关键信息
- 应用各种测试设计方法(等价类、场景法、正交实验法等)
- 逐条编写测试用例,整理成 Excel 或 XMind
这个过程不仅耗时,而且容易遗漏边界场景和异常情况。
我们的目标:构建一个自动化工具,能够:
- 从 Dify 知识库中检索与需求相关的业务文档
- 利用本地部署的 LLM(Ollama + deepseek-r1:7b)理解业务逻辑
- 内置多种测试设计方法(等价类、场景法、正交实验法、异常测试、接口测试)
- 自动生成测试用例,并输出为 XMind 思维导图 + Excel 表格
二、思路
整个方案的设计思路可以用一句话概括:
知识检索 → 智能生成 → 结构化输出
具体来说:
1. 为什么用 Dify 知识库?
很多公司已经有沉淀的业务文档(PRD、接口文档、操作手册等),但这些文档散落在各处,难以被有效利用。Dify 提供了开箱即用的 RAG(检索增强生成)能力,支持上传文档、自动分块、向量化存储,并提供 Retrieval API。
2. 为什么用本地 Ollama?
考虑到数据安全和隐私,很多企业不允许将业务数据上传到公有云大模型。通过 Ollama 在本地部署开源模型(如 deepseek-r1:7b),既能保证数据不外泄,又能获得不错的生成质量。
3. 为什么设计 Skill 插件机制?
不同的业务场景需要不同的测试设计方法:
- 表单验证 → 等价类划分 + 边界值分析
- 业务流程 → 场景法(基本流、备选流、异常流)
- 多参数组合 → 正交实验法(Pairwise)
- 系统稳定性 → 异常/容错测试
- API 接口 → 接口测试(参数校验 + 状态码覆盖)
通过 Skill 插件机制,每种方法独立实现,可以自由组合,也方便后续扩展。
4. 为什么输出 XMind?
XMind 是测试人员最常用的思维导图工具,适合展示用例的结构层次。同时导出 Excel 方便统计和归档。两者互补,满足不同场景的需求。
三、整体架构
┌─────────────────────────────────────────────────────────────────────┐
│ main.py (主流程编排) │
│ │
│ ┌─────────── 步骤 1 ───────────┐ ┌──────── 步骤 2 ──────────┐ │
│ │ Dify 知识库检索 │ │ LLM 生成测试用例 │ │
│ │ │ │ │ │
│ │ ┌─────────────────────┐ │ │ ┌──────────────────┐ │ │
│ │ │ DifyRetriever │ │ │ │ LLMClient │ │ │
│ │ │ ┌───────────────┐ │ │ │ │ ┌────────────┐ │ │ │
│ │ │ │ Dify 知识库 │ │─────┼──┼──│ │ Ollama API │ │ │ │
│ │ │ │ Retrieval API │ │ │ │ │ │ (streaming) │ │ │ │
│ │ │ └───────────────┘ │ │ │ │ └────────────┘ │ │ │
│ │ └─────────────────────┘ │ │ └────────┬─────────┘ │ │
│ └──────────────────────────────┘ └───────────┼──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ skills/ 插件层 │ │
│ │ ┌────────────────────┐ │ │
│ │ │ equivalence.py │ │ │
│ │ │ scenario.py │ │ │
│ │ │ orthogonal.py │ │ │
│ │ │ exception.py │ │ │
│ │ │ api_test.py │ │ │
│ │ └────────────────────┘ │ │
│ └──────────────────────────┘ │
│ │
│ ┌──────────────────── 步骤 3 ────────────────────────────────┐ │
│ │ xmind_generator.py │ │
│ │ │ │
│ │ 表格解析 → 列头自动映射 → 去重 → 质量过滤 → 统计 → 生成 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │ │
│ │ │ XMind │ │ Excel │ │ 统计报告 (控制台) │ │ │
│ │ │ .xmind │ │ .xlsx │ │ P0/P1/P2 分布 │ │ │
│ │ └──────────┘ └──────────┘ └──────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
各模块职责
| 模块 | 文件 | 职责 |
|---|---|---|
| 主入口 | main.py |
编排三步流程,解析命令行参数 |
| 知识库检索 | dify_retriever.py |
通过 Dify API 检索相关文档片段 |
| LLM 生成 | llm_client.py |
调用 Ollama 流式生成测试用例 |
| Skill 插件 | skills/*.py |
各种测试设计方法的 Prompt 模板 |
| 输出生成 | xmind_generator.py |
解析 LLM 输出 → 去重/过滤 → XMind + Excel |
| 配置 | config.py |
全局配置项 |
四、核心流程详解
整体流程图
开始
│
▼
┌──────────────────────────────┐
│ 输入:需求描述文本 │
│ 例:"用户登录功能" │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 步骤 1:检索知识库 │
│ │
│ DifyRetriever.retrieve() │
│ → 语义搜索 │
│ → 返回 Top-K 相关文档 │
│ → 格式化为上下文 │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 步骤 2:LLM 生成测试用例 │
│ │
│ LLMClient.generate() │
│ → 拼接 Prompt │
│ = 需求 + 知识库 + Skill │
│ → 流式调用 Ollama │
│ → 实时显示生成进度 │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 步骤 3:解析并输出 │
│ │
│ ① 合并多行表格 │
│ ② 自动识别列头 │
│ ③ 提取测试用例字段 │
│ ④ 按编号去重 │
│ ⑤ 过滤低质量用例 │
│ ⑥ 生成统计报告 │
│ ⑦ 构建 XMind XML 结构 │
│ ⑧ 导出 Excel 表格 │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ 输出:.xmind + .xlsx │
│ 控制台:统计报告 │
└──────────────────────────────┘
步骤 1:知识库检索
python
class DifyRetriever:
def retrieve(self, query: str, top_k: int = 5) -> List[Dict]:
"""检索知识库,返回相关文档块"""
payload = {
"retrieval_model": {
"search_method": "semantic_search", # 语义搜索
"top_k": top_k, # 返回数量
"score_threshold_enabled": True, # 启用阈值过滤
"score_threshold": 0.6, # 相似度阈值
},
"query": query,
}
# 调用 Dify Retrieval API
resp = self._client.post(
f"/v1/datasets/{self.dataset_id}/retrieve",
json=payload,
)
# 解析返回结果,按分数降序排列
results = []
for record in data.get("records", []):
segment = record.get("segment", {})
results.append({
"content": segment.get("content", ""),
"score": segment.get("score", 0),
"title": segment.get("document_name", ""),
})
results.sort(key=lambda x: x["score"], reverse=True)
return results
关键点:
- 使用 语义搜索 (
semantic_search),而非全文搜索,能理解查询意图 - 设置
score_threshold: 0.6,过滤掉低相关度结果 - 结果按相关度降序排列,只取 Top-K 条
步骤 2:LLM 生成
LLM 的 Prompt 由三部分组成:
用户 Prompt = 需求描述 + 知识库上下文 + Skill 提示词
系统 Prompt 定义了 LLM 的角色定位:
你是一个资深的测试工程师,擅长根据需求文档和业务知识生成高质量的测试用例。
要求:
1. 覆盖正常流程、异常流程和边界场景
2. 测试步骤清晰、可执行
3. 预期结果明确、可验证
4. 按优先级标记:P0(核心功能)、P1(重要功能)、P2(次要功能)
Skill 提示词 是每种测试设计方法的模板。以等价类划分为例:
## 【Skill:等价类划分 + 边界值分析】
请使用等价类划分和边界值分析法,对每个输入字段生成测试用例:
### 方法说明
1. 有效等价类:符合需求的有效输入,覆盖正常场景
2. 无效等价类:不符合需求的无效输入,覆盖异常场景
3. 边界值分析:对每个边界(上点、内点、离点)单独测试
### 输出格式(必须严格使用以下6列表格)
| 用例编号 | 测试场景 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|---------|---------|---------|---------|---------|-------|
| TC-EP-001 | 有效等价类-正常值 | 输入正常值 | 执行输入校验 | 通过 | P0 |
流式输出 的实现:
python
stream = self.client.chat.completions.create(
model=self.model,
messages=[...],
stream=True, # 启用流式
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta and delta.content:
collected.append(delta.content)
token_count += 1
if token_count % 20 == 0:
print(".", end="", flush=True) # 每20token打印一个点
步骤 3:解析与输出
这一步是整个方案中最具挑战性的部分,因为 LLM 的输出具有不确定性。
3.1 表格解析的挑战
LLM 输出的 Markdown 表格可能存在以下问题:
| 问题 | 示例 | 解决方案 |
|---|---|---|
| 列头不一致 | "前置条件" vs "请求参数" | 列头自动映射 |
| 列顺序变化 | 优先级列不在第6列 | 按列名匹配,不依赖位置 |
| 单元格内换行 | 步骤列有多行内容 | 多行合并算法 |
| 用例重复 | 多次生成相同用例 | 按编号去重 |
| 无效内容 | 场景为空、占位符 | 质量过滤 |
3.2 列头自动映射
python
COLUMN_ALIASES = {
"id": ["用例编号", "用例id", "编号", "id", "case id", "case_id"],
"scenario": ["测试场景", "场景", "场景描述", "场景类型", "组合说明", "异常场景"],
"precondition": ["前置条件", "前置", "前提", "前提条件", "请求参数", "预置条件", "输入值"],
"steps": ["测试步骤", "步骤", "操作步骤", "测试过程", "执行步骤", "注入方式", "操作"],
"expected": ["预期结果", "预期", "结果", "期望结果", "预期响应", "预期行为", "响应", "恢复验证", "预期状态码"],
"priority": ["优先级", "优先", "级别", "等级", "p0", "p1", "p2"],
}
这个映射表覆盖了各种可能的列头写法,即使是英文混写也能正确匹配。
3.3 多行单元格合并
当 LLM 在某个单元格内使用换行时,表格会被拆分成多行。通过比较列数来判断:
python
def _merge_multiline_table(markdown_text):
for line in lines:
stripped = line.strip()
is_table_line = stripped.startswith("|")
if is_table_line:
cell_count = len([c for c in stripped.split("|")[1:-1] if c.strip()])
# 列数少于预期 → 续行(合并到上一个单元格)
# 列数等于预期 → 新行
if cell_count < expected_cols:
buffer += " " + stripped # 续行
else:
merged.append(buffer) # 新行
buffer = stripped
3.4 XMind 构建
XMind 文件本质上是 ZIP 压缩包,包含 XML 格式的内容文件:
output.xmind
├── content.xml # 思维导图内容(XML)
├── meta.xml # 元数据(作者信息)
└── META-INF/
└── manifest.xml # 文件清单
构建 XML 的层次结构:
XMind Topic Tree:
└── 测试用例 (根节点)
├── 模块名1 (N用例)
│ ├── [P0] TC-001 测试场景描述
│ │ ├── 前置条件: xxx
│ │ ├── 测试步骤: xxx
│ │ └── 预期结果: xxx
│ └── [P1] TC-002 测试场景描述
└── 模块名2 (N用例)
└── ...
3.5 Excel 导出
使用 openpyxl 生成带样式的 Excel 表格:
- 蓝色表头、冻结首行
- 优先级列着色:P0 红色、P1 橙色、P2 黄色
- 自动列宽、自动换行
五、Skill 插件系统详解
Skill 是这套方案的核心设计亮点,它让测试设计方法成为可插拔的组件。
基类定义
python
class BaseSkill(ABC):
@property
@abstractmethod
def name(self) -> str:
"""Skill 唯一标识"""
@property
@abstractmethod
def description(self) -> str:
"""Skill 描述"""
@abstractmethod
def build_prompt_section(self, requirement: str, knowledge: str) -> str:
"""构建该 Skill 对应的 Prompt 片段"""
加载机制
python
def load_skills(names: List[str]) -> List[BaseSkill]:
registry = {
"equivalence": EquivalenceSkill,
"scenario": ScenarioSkill,
"orthogonal": OrthogonalSkill,
"exception": ExceptionSkill,
"api": ApiTestSkill,
}
return [cls() for name in names if (cls := registry.get(name))]
5 种内置 Skill 详解
| Skill | 标识 | 适用场景 | 典型用例数 | 示例 |
|---|---|---|---|---|
| 等价类划分 | equivalence |
输入框、表单验证、参数校验 | 6-10 | 用户名长度校验 |
| 场景法 | scenario |
业务流程、状态流转、端到端 | 4-8 | 订单支付流程 |
| 正交实验法 | orthogonal |
多参数组合、配置项测试 | 6-15 | 搜索筛选条件 |
| 异常测试 | exception |
错误处理、系统容错 | 5-10 | 网络超时、SQL注入 |
| 接口测试 | api |
RESTful API、微服务接口 | 6-12 | 用户登录接口 |
组合使用
Skill 可以自由组合,LLM 会按顺序生成对应的测试用例:
bash
# 等价类 + 场景法 → 覆盖输入校验和业务流程
python main.py -r "订单支付" -s equivalence scenario
# 接口测试 + 正交实验法 → 覆盖接口参数和组合
python main.py -r "搜索API" -s api orthogonal
# 全部 Skill 组合 → 全面覆盖
python main.py -r "用户注册" -s equivalence scenario orthogonal exception api
六、使用示例
1. 基本使用
bash
python main.py -r "用户登录功能支持用户名密码和验证码登录"
输出:
[1/3] 检索知识库...
检索到 3 条相关文档
[2/3] LLM 生成测试用例...
生成中: .................... 完成 (420 tokens, 2350 字符)
[3/3] 生成 XMind 文件...
[XMindGenerator] 解析到 12 个原始用例
[XMindGenerator] 去重: 移除 1 个重复用例
[XMindGenerator] 质量过滤: 移除 0 个低质量用例
[统计] 共 11 个测试用例
P0(核心): 4 | P1(重要): 5 | P2(次要): 2
[XMind] 已生成: output/test_cases_abc12345.xmind
[Excel] 已导出: output/test_cases_abc12345.xlsx
2. 组合多个 Skill
bash
python main.py -r "订单支付流程" -s equivalence scenario exception
3. 跳过知识库检索
bash
python main.py -r "文件上传功能" --no-retrieve -s equivalence
4. 指定输出路径
bash
python main.py -r "登录模块" -o login_test.xmind -k 10
七、项目目录结构
testcase_generator/
├── main.py # 主入口,编排三步流程
├── config.py # 全局配置(API Key、模型、参数)
├── dify_retriever.py # Dify 知识库检索模块
├── llm_client.py # LLM 客户端(Ollama API,流式输出)
├── xmind_generator.py # 解析 + 去重 + 生成 XMind + Excel
├── preview_xmind.py # XMind → HTML 预览工具(浏览器查看)
├── requirements.txt # 依赖
├── README.md # 使用文档
├── skills/ # 测试设计方法(Skill 插件)
│ ├── __init__.py # BaseSkill 基类 + 加载器
│ ├── equivalence.py # 等价类划分 + 边界值分析
│ ├── scenario.py # 场景法(业务流程覆盖)
│ ├── orthogonal.py # 正交实验法(组合覆盖)
│ ├── exception.py # 异常/容错测试
│ └── api_test.py # 接口测试(参数 + 状态码)
└── output/ # 生成的输出文件
├── test_cases_*.xmind
└── test_cases_*.xlsx
八、环境准备
1. 部署 Dify
bash
# 在服务器上部署 Dify 社区版
docker compose up -d
# 访问 http://localhost:8080
2. 部署 Ollama
bash
# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 拉取模型
ollama pull deepseek-r1:7b
ollama pull nomic-embed-text
3. 配置 Dify 知识库
- 登录 Dify,创建知识库(数据集)
- 上传业务文档(PRD、接口文档等)
- 选择嵌入模型为
nomic-embed-text - 获取数据集 ID 和 API Key
4. 安装 Python 依赖
bash
pip install httpx openai openpyxl
5. 配置
编辑 config.py:
python
DIFY_API_KEY = "dataset-xxx" # 从 Dify 获取
DATASET_ID = "xxx" # 知识库数据集 ID
DIFY_BASE_URL = "http://localhost:8080" # Dify 服务地址
OLLAMA_BASE_URL = "http://localhost:11434" # Ollama 服务地址
LLM_MODEL = "deepseek-r1:7b" # 生成模型
九、总结与展望
已实现的功能
- ✅ 自动检索 Dify 知识库,获取业务文档上下文
- ✅ 5 种测试设计方法(等价类、场景法、正交实验法、异常测试、接口测试)
- ✅ Skill 插件机制,可自由组合和扩展
- ✅ 流式输出,实时显示生成进度
- ✅ 表格解析容错(列头自动映射、多行合并)
- ✅ 用例去重 + 质量过滤
- ✅ 同时输出 XMind 思维导图 + Excel 表格
- ✅ 统计报告(P0/P1/P2 分布、模块分布)
可扩展的方向
- 更多 Skill:可以继续添加决策表测试、状态迁移测试、性能测试等
- 多轮对话:对生成的用例进行追加、修改、补充
- 批量生成:从需求文档中自动提取多个需求点,批量生成
- 测试用例管理:对接 TestLink、Jira 等测试管理平台
- Web 界面:提供简单的 Web 操作界面,降低使用门槛
项目地址:可直接在本地部署使用
如果你也在做测试提效相关的工作,欢迎交流讨论!