本地部署Dify+Ollama,打造测试用例自动生成系统
2026/9/9 12:16:58 网站建设 项目流程

最近把 Dify 和 Ollama 搭起来做了一套测试用例自动生成系统,整体效果比我预期好不少。以前写用例基本靠人肉对着需求文档做脑暴,遗漏场景是常有的事,现在我把需求文字丢给工作流,几分钟后就能得到一版结构化程度很高的测试用例草案,再人工 review 一轮就能用。这篇文章不写概念科普,直接记录我是怎么从零把它跑起来的,包括环境部署、工作流编排、Prompt 设计,以及过程中真正踩过的坑。如果你也想在本地不依赖在线 API 的情况下搭一套测试用例生成系统,这篇应该能帮你少走很多弯路。

1. 项目概述与方案选型

1.1 这套系统到底解决什么问题

测试用例这个事,大多数人低估了它的工作量。一个中等规模的业务模块,功能用例、接口用例、异常场景、边界值、权限校验全铺开,几十上百条很常见。手工写不是不能写,但非常耗精力,而且非常依赖个人经验,新人写出来的覆盖率通常不稳定。

这套系统解决的就是“把需求描述转成结构化测试用例”这个环节。输入可以是一句话需求,也可以是一段完整的 PRD,输出是包含用例编号、前置条件、操作步骤、预期结果、优先级等字段的 Markdown 表格或 JSON。它能覆盖的功能类型包括:

  • 功能测试用例:按用户操作路径拆解正常流程和反向流程。
  • 接口测试用例:从接口描述、字段约束中提取正常参数、边界值、必填项校验、异常参数组合。
  • 异常场景用例:网络超时、重复提交、并发冲突、数据不存在等。
  • 业务规则用例:从需求文本里抽取条件分支,逐条映射到用例。

Dify 在这里承担的是工作流编排、知识库管理、Prompt 调试和结果输出,Ollama 负责在本地跑大模型推理。整个链路完全离线也能工作,对数据敏感的项目特别友好。

1.2 为什么选 Dify + Ollama 而不是在线大模型

我最早其实试过直接在 ChatGPT 网页里贴需求让它生成用例,效果好是好,但有两个问题:一是需求文档本身就是敏感资产,不可能随便贴到外部服务;二是“生成用例”这个流程不是一次对话就能搞定的,你需要固定格式、固定角色、固定检查项,每次都靠手写 Prompt 太不稳定。

后来想了自己用 Python 写脚本直接调用 OpenAI API,但发现维护成本也不低。Prompt 改一个词就要改代码,多个模型之间切换也麻烦,更不用说还需要自己做知识库检索。这时候 Dify 的价值就体现出来了。

Dify 是开源的大模型应用开发平台,工作流可视化编排、知识库、Prompt 管理、模型接入都有,而且社区版免费,数据都在你自己服务器上。Ollama 则是一个极简的本地大模型运行工具,一条命令就能拉起 Qwen、Llama 这些开源模型,提供 OpenAI 兼容接口,Dify 可以直接接进去。这套组合的好处有几点:

  • 数据不出内网,满足合规要求。
  • 一次配置,后续只改工作流节点和 Prompt,不用改代码。
  • 模型跑在本地,固定成本可控,没有按 token 计费的心痛感。
  • 可复用性高,同一套环境还能做数据分析、知识库问答、代码审查等场景。

1.3 整体架构与数据流转

整个系统的架构并不复杂,核心是“输入—处理—输出”三段式。用户把需求文本填到 Dify 的工作流入口,工作流里先用 Prompt 模板把需求包装成待办任务,再用知识检索节点把相关历史用例、业务术语捞出来一并塞给大模型,然后调用 Ollama 接口完成推理,最后把模型输出的原始文本用模板节点整理成结构化表格。

实际数据流大概是这样的:

  1. 用户通过 Dify 页面或 API 提交需求描述。
  2. 开始节点解析参数,比如需求文本、模块名、用例类型。
  3. 知识检索节点按相似度从知识库中召回相关用例片段和业务规则。
  4. Prompt 组装节点把需求、召回内容、角色设定、few-shot 示例拼成一个完整的 prompt。
  5. LLM 节点调用 Ollama 中已加载的 qwen2.5 模型生成用例。
  6. 输出解析节点把模型返回的 Markdown 表格或 JSON 提取出来,最后展示给用户。

这一套链路看着简单,但真正跑通需要把环境、模型、工作流、Prompt 四个层面的细节都处理好。下面逐个说。

2. 环境搭建与关键配置

2.1 宿主机与基础环境准备

先说硬件。我手上这台机器是 AMD Ryzen AI 9 HX 370 的本子,内存 32GB,核显是 Radeon 890M。跑 7B 量级的量化模型基本够用。如果你的机器只有 16GB 内存,跑 7B 模型会比较紧张,建议优先选 4B 或者更小体量的模型,比如 qwen2.5:3b。内存不够的时候,模型会部分落到内存交换,推理速度肉眼可见变慢。

软件层面需要准备这几样东西:

  • Docker 和 Docker Compose,Dify 官方推荐的部署方式就是 docker compose。
  • Git,用来拉取 Dify 代码仓库。
  • Ollama,负责模型下载和推理服务。
  • 浏览器,Dify 控制台是 Web 界面。

如果你在 Windows 上部署,建议把 Docker Desktop 和 Ollama 都装好,Dify 用 Docker Desktop 跑。Dify 容器内部访问宿主机上的 Ollama 时,不能直接用 localhost,要用host.docker.internal。这个细节很重要,后面接入模型 Provider 时再细说。

2.2 Ollama 安装、模型管理与镜像加速

Ollama 的安装本身不难,Linux 上执行官方安装脚本或者 Windows 下安装 exe 都能搞定。装完之后第一步是拉模型,我主力用的是qwen2.5:7b,这也是 Dify 本地化部署场景里很常见的选择。

ollama pull qwen2.5:7b

不过这里必须要说一个国内用户大概率会踩的坑:直接ollama pull非常慢,甚至经常卡在等待下载。原因不复杂,模型默认从国外源拉取,网络环境不稳定。解决办法有几个,我推荐最省心的一个:从国内可访问的模型平台下载 GGUF 格式的模型文件,再通过 Ollama 导入。

具体操作是先去国内模型站点下载qwen2.5-7b-instruct-q4_k_m.gguf这类文件,然后写一个 Modelfile:

FROM ./qwen2.5-7b-instruct-q4_k_m.gguf TEMPLATE """{{ .Prompt }}""" SYSTEM """你是一名资深测试工程师,请根据需求生成结构化测试用例。"""

然后在同一目录下执行:

ollama create qwen2.5-7b -f Modelfile ollama run qwen2.5-7b

这样就能绕开官方模型源,速度稳定很多。如果你希望模型文件不占系统盘,可以在启动 Ollama 前设置环境变量OLLAMA_MODELS=D:\ollama_models,Windows 下重启 Ollama 服务即可生效。

拉完模型后最好验证一下接口是否正常,Dify 接的是这个接口:

curl http://localhost:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "qwen2.5-7b", "messages": [{"role": "user", "content": "你好"}]}'

只要能返回正常 JSON,说明 Ollama 的 OpenAI 兼容接口已经在工作了。

2.3 Dify 本地部署与模型接入

Dify 的社区版部署方式很成熟。我按官方 docker compose 方式部署:

git clone https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env docker compose up -d

第一次启动会拉很多镜像,建议提前把 Docker 镜像加速地址配置好。等所有容器都起来后,浏览器访问http://localhost/install设置管理员账号,就能进控制台了。

接下来要做的是把 Ollama 接入 Dify。进入“设置—模型供应商”,找到 Ollama,填写模型名称和 Base URL。这里有一个经典错误:Dify 容器和 Ollama 不在同一个网络命名空间,填http://127.0.0.1:11434是无效的。在 Windows 和 Mac 上应该填:

http://host.docker.internal:11434

如果 Dify 部署在 Linux 服务器上,则填宿主机内网 IP,比如http://192.168.1.20:11434

模型名称要和 Ollama 里的名字完全一致。如果你执行ollama list看到的是qwen2.5:7b,那 Dify 里 Model Name 就填qwen2.5:7b。上下文长度我一般填 4096,超过 7B 模型实际能力范围反而容易出现性能问题。

2.4 让 Ollama 使用 GPU 运行(AMD 核显实测)

很多人以为 Ollama 只支持 NVIDIA 显卡,其实不是。尤其是带 AMD 核显的机器,我用 AMD Ryzen AI 9 HX 370 实测下来,Ollama 是可以调用 GPU 加速的。关键在于两点:Ollama 要使用较新的版本,Radeon 890M 的 Vulkan 驱动要装好。

启动 Ollama 后,跑一个模型,然后用ollama ps查看资源占用。如果 GPU 列显示百分比,说明模型已经加载到显存里了。如果显示 0%,那就是还在用 CPU,需要检查显卡驱动和 Ollama 日志。

一个比较常见的现象是首次加载模型很慢,这是正常情况,因为模型要从磁盘读入内存并完成初始化。跑起来之后速度会明显加快。RDNA 3.5 核显跑 7B Q4 量化模型,生成速度比纯 CPU 快不少,实测感受是“能接受但不算飞快”。如果你的诉求是极快的流式输出,建议用 3B 模型或者缩小上下文长度。

还需要注意一点:AMD 核显会占用一部分系统内存作为显存,所以机器内存建议至少 24GB,32GB 会更从容。如果你没有 GPU 加速的条件,纯 CPU 跑 7B 模型也不是不能用,只是生成 20 条用例可能要多等几分钟。

3. 测试用例自动生成工作流的设计与实现

3.1 需求描述与 Prompt 模板设计

接入模型只是第一步,真正决定用例质量的是 Prompt。我刚开始直接把需求文本丢给模型,说“帮我生成测试用例”,结果输出非常飘,用例之间逻辑不连贯,格式也乱七八糟。后来我把 Prompt 结构改成下面几个固定部分:

  1. 角色设定,明确告诉模型它是资深测试工程师。
  2. 任务说明,要求它根据需求生成覆盖正常、异常、边界、权限等维度的测试用例。
  3. 输入数据,把用户填写的需求文本放在里面。
  4. 输出约束,规定必须输出 Markdown 表格,列名固定。
  5. few-shot 示例,给一组真实用例作为参考。

在 Dify 的 LLM 节点里,Prompt 模板可以写成这样:

你是一名有十年经验的测试工程师。请根据以下需求描述生成测试用例。 要求覆盖:正常流程、异常流程、边界值、权限校验、数据一致性。 输出格式为 Markdown 表格,包含:用例编号、模块、优先级、前提条件、操作步骤、预期结果。 需求描述: {{#sys.req_text#}} 历史用例参考: {{#context#}}

这里的{{#sys.req_text#}}是 Dify 工作流里定义的输入变量,{{#context#}}是知识检索节点输出的参考内容。变量命名要规范,否则节点之间的数据传不到。

3.2 在 Dify 中编排工作流:从输入到输出

Dify 的工作流编辑器是可视化拖拽,实际编排我用了这几个节点:

  • 开始节点:定义两个输入字段,req_text为段落类型,module_name为短文本。
  • 知识检索节点:连接知识库,按语义相似度召回相关用例。
  • LLM 节点:选择 Ollama 供应商,模型选qwen2.5:7b,Prompt 里引用开始节点和知识检索节点的变量。
  • 模板转换节点:对模型输出做二次格式化,确保是完整 Markdown 表格。
  • 结束节点:把最终文本返回给用户。

这里有个容易搞混的地方。LLM 节点输出的是原始 token 序列,如果模型偶尔在表格前加了一段废话,Dify 直接展示出来会显得很不专业。我建议在 LLM 节点后面加一个“模板转换”节点,把输出字段规整化。

模板转换节点里可以写:

{{#llm_node.text#}}

然后再加一个条件分支?如果模型返回了 JSON 结构的数据,还可以用代码节点把它解析成表格。不过最简单的方案是要求模型“只输出 Markdown 表格,不要输出解释”,然后在 Prompt 里强制强调。

3.3 知识库增强:让生成的用例贴合业务

单纯靠 Prompt 生成的用例,通用性很强,但缺少业务细节。比如一个“订单支付”的功能,通用用例只会说“支付成功”“支付失败”,但你的业务规则可能是“余额不足时提示充值”“白名单用户可享受后付费”。这些规则如果不在 Prompt 里,模型根本不知道。

解决方法是给 Dify 建知识库,把历史用例、业务规则、接口字段说明传进去。Dify 的知识库支持文档上传,而且可以通过数据清洗和分段配置来优化检索效果。

你需要先在 Ollama 里拉一个 embedding 模型,然后在 Dify 设置里配好:

ollama pull nomic-embed-text

配置完 embedding 模型后,在知识库页面上传文档。文档格式我建议用 Markdown 或 TXT,分段长度控制在 500 到 1000 字之间,这样检索命中率更高。检索模式我用的是“向量检索 + 关键字检索”混合方式,召回结果更稳定。

知识库生效后,工作流里的“上下文”参数会自动带上召回内容,模型生成用例时就能参考真实业务规则了。这一步是整个系统从“玩具”变成“可用工具”的关键。

3.4 输出解析与用例落地

模型生成的 Markdown 表格直接展示在页面上,没问题,但如果要落到测试管理平台或 Excel 里,还需要转成结构化数据。我在工作流最后加了一个“代码执行”节点,用 Python 把 Markdown 表格解析成 JSON 数组。

代码节点示例:

import re def main(markdown_text: str) -> dict: rows = [] lines = [line.strip() for line in markdown_text.strip().split("\n")] for line in lines: if line.startswith("|") and "---" not in line: cells = [c.strip() for c in line.strip("|").split("|")] if len(cells) >= 6: rows.append({ "id": cells[0], "module": cells[1], "priority": cells[2], "precondition": cells[3], "steps": cells[4], "expected": cells[5] }) return {"cases": rows}

然后结束节点返回这个 JSON,方便后续接 API 推送到禅道、Jira 或者自研平台。如果没有这些平台,直接在 Dify 页面里看表格也够用。

4. 实操过程与效果验证

4.1 一个真实项目的生成过程

拿一个具体需求举例。假设输入是:

需求:用户通过手机号验证码登录。 规则: 1. 手机号必须是 11 位,以 1 开头。 2. 验证码有效期 5 分钟。 3. 同一手机号 60 秒内只能发送一次。 4. 验证码错误 5 次后,该手机号锁定 30 分钟。 5. 登录成功后返回 token 和用户信息。

我把它填到工作流里,点击运行。生成结果的主要内容包括:

正常流程用例:输入正确手机号和验证码,登录成功;输入正确验证码在有效期内可以换取 token。

异常流程用例:验证码过期、验证码错误、手机号格式不正确、验证码发送次数超限。

边界值用例:手机号 11 位但首位不是 1;验证码第 5 次错误触发锁定;锁定期间再次尝试登录。

权限与状态用例:已锁定手机号不能登录,锁定状态到期后自动恢复。

这个生成质量比我预期高不少,尤其是“锁定 30 分钟”“验证码 60 秒发送一次”这类具体业务规则,都准确落到了用例预期结果里。原因一方面是大模型对中文需求理解能力不错,另一方面是 Prompt 里明确要求了覆盖维度。

4.2 生成结果的整理与评估

生成完之后,我并没有直接把它当最终产物,而是做了一轮人工 review。我的检验维度有三个:

  • 需求覆盖率:对需求文本里的每条规则逐条核对,是否都有对应用例。
  • 可执行性:操作步骤是否写得足够具体,能不能照着执行。
  • 格式规范性:字段是否存在遗漏,预期结果是否可判定。

实测下来,qwen2.5:7b 生成的用例,需求覆盖率大概在 85% 左右。剩下的遗漏大多是需求中隐含的逻辑没写清楚,比如“用户已登录状态下访问登录页应跳转首页”这种状态切换,需求文本没提示,模型也想不出来。这部分需要靠知识库里的历史用例来弥补。

经过人工 review 补齐后,一套 40 条左右的用例,总耗时控制在 30 分钟以内。以前纯手工写,至少要半天。这个效率提升是非常可观的。

4.3 调优:温度、上下文与模型选择

大模型生成用例有一个天然矛盾:温度高了容易发散,温度低了容易模板化。测试用例要的是稳定和准确,所以我把 LLM 节点的温度调到 0.2,最大限度减少随机性。如果你发现输出总是重复同一套句式,可以适当调高到 0.4,但别超过 0.7。

上下文长度也影响很大。如果需求文本很长,超过模型上下文窗口,后面的内容会被截断,用例覆盖自然不完整。我一般把 Dify 里的上下文体长设为 4096,并且要求用户输入需求时尽量结构化,比如用“需求:+ 规则列表”的格式。

模型选择方面,我主力用 qwen2.5:7b,它在中文需求和结构化输出上表现不错。如果你机器性能弱,可以降到 qwen2.5:3b,速度更快,但对复杂规则的理解会差一些。如果追求更高精度,可以用 qwen2.5:14b,但内存和推理时间都会明显上升。我的建议是先用 7B 跑通流程,再根据实际效果决定是否升级。

5. 常见问题与排查技巧实录

5.1 Ollama 相关高频问题

这段时间收到最多的问题就是“Ollama 下载太慢了怎么解决”。除了前面说的 GGUF 导入方案,还有一个技巧:模型文件下载到本地后,直接把文件路径改成自定义目录,避免 C 盘爆满。Windows 下设置在系统环境变量里加一个OLLAMA_MODELS,然后重启 Ollama 服务,新模型就会下载到指定目录。

“Ollama 调用乱码”也是一个高发问题。Windows 下 Dify 调用 Ollama 返回中文乱码,大部分原因是 PowerShell 或系统的默认编码不是 UTF-8。在运行 Dify 之前先执行:

chcp 65001

然后在 Ollama 服务所在的环境变量里加OLLAMA_HOST=0.0.0.0,让服务监听所有网络接口,避免 Docker 容器访问不到。

“Ollama 下载太慢”另外还有一个常见来源是模型文件太大。如果只是测试,建议先拉 1B 或 3B 的小模型验证链路,等系统跑通了再换 7B。别一上来就拉 7B,下载时间长不说,模型加载也容易在中间失败。

5.2 Dify 相关高频问题

“Dify 中的 Ollama 模型处理超时”出现频率很高。原因通常是模型首次加载太慢,或者推理时间超过了 Dify 默认的超时时间。解决方法有三个方向:

  1. 调整 Dify 供应商配置里的超时参数,给到 120 秒以上。
  2. 让 Ollama 模型保持常驻,设置环境变量OLLAMA_KEEP_ALIVE=24h
  3. 确认物理机内存足够,不要把系统搞到 swap 状态。

“更新 Dify”也是很多人关心的。Dify 更新我一般直接执行:

docker compose pull docker compose up -d

但升级前一定要备份数据库和存储卷。我用的是 docker volume 方式,备份很简单:

docker run --rm -v dify_database:/data -v $(pwd):/backup alpine tar czf /backup/dify_db_backup.tar.gz -C /data .

如果你改了 Dify 前端代码,二开部署时会发现前端容器里跑的是静态资源,需要自己构建前端镜像并替换。社区版从 1.10 开始支持多租户,管理员可以创建多个工作空间隔离数据和成员,这种场景下更新要尤其谨慎,最好先在测试环境里验证。

5.3 模型输出质量问题的排查

生成用例质量不行,先别急着怪模型,大多数时候是输入没给够。排查顺序我按四步走:

第一步,看需求文本是否结构化。如果是一大段散文式描述,模型很难提取规则。先整理成“需求: + 规则:”的列表格式,效果立竿见影。

第二步,看 Prompt 里有没有 few-shot。我给模型塞了两组高质量历史用例后,输出格式稳定度提升非常明显。

第三步,看知识库召回内容是否相关。如果知识库里有大量无关文档,检索节点会返回一些噪声信息,反而干扰模型。

第四步,看模型温度。如果输出内容每一条都像“验证功能是否正常”这种废话,把温度降下来,再在 Prompt 末尾强调“预期结果要具体可判定,不能写笼统描述”。

5.4 部署维护心得与避坑清单

最后整理一份我的避坑清单,给正在搭这套系统的人参考:

  1. Docker 容器访问宿主机 Ollama,一定要用host.docker.internal,不要用localhost
  2. 模型名字必须精确匹配ollama list里的名字,大小写和冒号都不能错。
  3. 7B 模型至少留出 16GB 可用内存,否则推理速度会惨不忍睹。
  4. 知识库的 embedding 模型要单独拉,别拿对话模型顶替。
  5. Prompt 里要求模型只输出 Markdown 表格,能省掉后面一大半解析工作。
  6. 升级 Dify 前先备份 volume,这是花两分钟能换回一晚上的事情。
  7. 模型的首次加载慢是正常的,不要一超时就反复重试,先观察日志和内存占用。

我在这套系统上投入的时间,大部分花在 Prompt 和知识库的反复调整上,环境本身反而不是最耗时的。你如果也想复现,建议先从一个小模块跑通,再逐步扩展知识库和用例模板。等整套链路稳定了,再往团队里推广,到时候你就会发现,测试用例自动生成不是“替代测试人员”,而是把测试人员从重复劳动里解放出来,把精力放到更有价值的地方。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询