ARTICLE · 1301705
AI Agent 软件测试实战(01):从零搭建 AI Test Agent,先实现一个能运行的智能测试助手
TL;DR
系列方向: 从软件测试实际场景出发,使用 Python 和大模型技术,从零搭建一个 AI Test Agent。逐步实现任务理解、工具调用、任务规划、测试执行、结果分析、记忆管理和工程集成,最终形成一个可以融入软件测试工作流的智能测试助手。
本篇重点: 不急着接入大模型,也不依赖复杂 Agent 框架。先从零搭建一个最小可运行的 AI Test Agent,理解 Agent 的基本组成,以及它如何接收测试任务、选择工具、执行操作并返回结果。
一、为什么要单独做一个 AI Test Agent?
前面两个专题,我们已经讨论过不少 AI 与软件测试结合的实践:
如何利用 AI 辅助生成和评审测试用例。 如何让 AI 分析自动化测试失败日志。 如何利用 AI 辅助精准回归测试。 如何把 AI 能力融入现有测试工作流。
这些实践解决了不少实际问题,但我在整理这些内容时也发现一个问题:
很多 AI 测试工具,本质上还是在原有测试流程中增加了一个 AI 调用环节。
例如:
测试人员上传一份测试报告,调用大模型分析失败原因,然后返回一段分析结果。
这个过程确实有价值,但它还存在几个明显的局限:
AI 只能处理当前提供的信息,不能主动获取其他测试数据。 AI 可以提出解决建议,但不一定能够实际执行测试操作。 每个功能往往相互独立,缺少统一的任务管理和执行机制。 如果需要连续完成多个步骤,就需要人工不断地输入指令。
举个例子。
现在有一个订单系统,测试人员提出:
帮我检查订单接口是否正常,如果发现返回数据异常,告诉我具体是哪项校验没有通过。
普通的 AI 对话方式可能是:
测试人员提供接口响应。 AI 根据响应内容进行分析。 AI 返回分析结论。
但一个真正具备执行能力的 AI Test Agent,应该能够逐步完成:
接收测试任务。 理解需要检查的内容。 选择对应的接口测试工具。 调用工具执行校验。 获取实际执行结果。 根据执行结果生成测试结论。
两者最大的区别是什么?
前者主要是分析信息,后者开始具备了任务执行能力。
这也是我们接下来要实现 AI Test Agent 的原因。
二、先搞清楚:AI Agent 到底是什么?
在正式写代码之前,先明确一个概念。
Agent 并不是一个新的大模型,也不是简单地给 ChatGPT 加一个界面。
从工程实现角度来看,我们可以先把一个 AI Agent 理解为:
一个能够接收目标、理解任务、选择工具、执行操作,并根据执行结果继续完成任务的软件系统。
一个最基本的 Agent 通常涉及以下几个部分:
这里需要特别说明:
本篇先使用 Python 规则判断模拟任务理解,不使用真正的大模型。
这样做不是为了把规则判断当作最终方案,而是为了先把 Agent 的工程骨架搭建起来。
后面接入大模型时,我们只需要逐步替换任务理解和任务决策部分,而不需要推翻整个项目。
三、确定项目目标:我们到底要做什么?
这一系列统一使用一个项目:
ai-test-agent
技术选型先保持简单:
第一篇只使用 Python 标准库,不需要安装大模型 SDK,也不需要配置数据库。
3.1 第一阶段的功能范围
我们先实现一个简单的订单接口检查任务。
用户输入:
检查订单接口
Agent 完成以下操作:
识别这是一个订单接口检查任务。 找到已经注册的订单检查工具。 调用工具执行数据校验。 获取工具返回的执行结果。 生成一份测试摘要。
本篇暂时不做:
真正调用外部 HTTP 接口。 大模型自主规划任务。 多 Agent 协作。 自动修改代码或修复缺陷。 数据库持久化。
这些功能会在后续文章逐步增加。
3.2 项目执行流程
整个项目的最小执行流程如下:
flowchart TDA[测试人员输入任务] --> B[Agent 接收任务]B --> C[识别任务类型]C --> D[查找注册工具]D --> E[调用订单检查工具]E --> F[执行数据校验]F --> G[返回执行结果]G --> H[生成测试摘要]
从这个流程可以看出,Agent 并不只是一个接收输入、返回文字的函数。
它中间存在工具选择、实际执行和结果处理等环节。
四、动手搭建:从零实现第一个 AI Test Agent
接下来进入代码实践。
4.1 创建项目目录
创建项目:
mkdir ai-test-agentcd ai-test-agent
创建以下文件:
ai-test-agent/├── agent.py├── tools.py└── README.md
这次先不刻意拆分过多模块。一个小项目如果一开始就设计十几个目录,反而容易把简单问题复杂化。
4.2 编写测试工具
首先实现一个订单接口响应检查工具。
创建 tools.py:
from typing import Anydef check_order_response() -> dict[str, Any]:”””模拟订单接口响应检查。当前使用本地模拟数据。后续可以替换成真实 HTTP 接口调用。”””# 模拟订单接口返回的数据response = {”code”: 200,”message”: ”success”,”data”: {”order_id”: ”ORDER20261103001”,”amount”: 199.00,”status”: ”created”}}checks = []# 检查响应状态码checks.append({”name”: ”响应状态码检查”,”passed”: response.get(”code”) == 200,”message”: ”接口响应正常”if response.get(”code”) == 200else f”响应状态码异常:{response.get('code')}”})data = response.get(”data”, {})# 检查订单编号order_id = data.get(”order_id”)checks.append({”name”: ”订单编号检查”,”passed”: isinstance(order_id, str) and bool(order_id.strip()),”message”: ”订单编号存在”if isinstance(order_id, str) and order_id.strip()else ”订单编号缺失或为空”})# 检查订单金额amount = data.get(”amount”)checks.append({”name”: ”订单金额检查”,”passed”: (isinstance(amount, (int, float))and not isinstance(amount, bool)and amount > 0),”message”: ”订单金额正常”if (isinstance(amount, (int, float))and not isinstance(amount, bool)and amount > 0)else ”订单金额异常”})# 检查订单状态status = data.get(”status”)checks.append({”name”: ”订单状态检查”,”passed”: status in {”created”, ”paid”, ”cancelled”},”message”: ”订单状态合法”if status in {”created”, ”paid”, ”cancelled”}else f”订单状态异常:{status}”})passed_count = sum(1 for item in checks if item[”passed”])return {”tool”: ”check_order_response”,”success”: passed_count == len(checks),”total”: len(checks),”passed”: passed_count,”failed”: len(checks) - passed_count,”details”: checks}
这里我们没有直接返回一个简单的 True 或 False,而是返回结构化结果。
例如:
{”tool”: ”check_order_response”,”success”: true,”total”: 4,”passed”: 4,”failed”: 0}
为什么要这样设计?
因为 Agent 后续不只是需要知道工具是否执行成功,还需要知道:
一共执行了多少项检查? 哪些检查通过了? 哪些检查失败了? 失败的具体原因是什么?
如果工具只返回一个布尔值,后续分析和生成测试报告都会受到限制。
这里有一个工程上的设计原则:工具负责执行具体操作,并返回结构化结果;Agent 负责组织任务和处理结果。
4.3 实现 Agent 的工具注册机制
现在有了测试工具,但 Agent 还不知道这个工具的存在。
因此,我们需要一个简单的工具注册机制。
创建 agent.py:
from tools import check_order_responseclass AITestAgent:def __init__(self):# 工具注册表self.tools = {”check_order”: check_order_response}def understand_task(self, task: str) -> str:”””第一版使用规则识别任务。后续替换为大模型任务理解。”””if ”订单” in task:return ”check_order”return ”unknown”def execute_tool(self, tool_name: str):”””根据工具名称执行对应工具。”””tool = self.tools.get(tool_name)if tool is None:return {”success”: False,”error”: f”未找到工具:{tool_name}”}try:return tool()except Exception as e:return {”success”: False,”error”: str(e)}def run(self, task: str):”””Agent 主执行入口。”””print(f”\n收到测试任务:{task}”)# 第一步:理解任务tool_name = self.understand_task(task)print(f”任务识别结果:{tool_name}”)if tool_name == ”unknown”:print(”暂时无法识别该测试任务。”)return# 第二步:执行工具print(”开始调用测试工具...”)result = self.execute_tool(tool_name)# 第三步:处理执行结果print(”\n测试执行结果:”)for item in result.get(”details”, []):status = ”通过” if item[”passed”] else ”失败”print(f”[{status}] ”f”{item['name']}:{item['message']}”)# 第四步:生成测试摘要print(”\n测试摘要:”)if result.get(”success”):print(”订单接口检查全部通过。”)else:print(f”订单接口检查存在异常,”f”通过 {result.get('passed', 0)} 项,”f”失败 {result.get('failed', 0)} 项。”)if __name__ == ”__main__”:agent = AITestAgent()task = input(”请输入测试任务:”)agent.run(task)
这段代码实现了整个 Agent 的基础流程。
我们重点看三个地方。
第一,任务理解。
def understand_task(self, task: str) -> str:if ”订单” in task:return ”check_order”return ”unknown”
目前只是简单判断关键词。
例如输入:
检查订单接口
就会返回:
check_order
这显然还不够智能,但它已经明确了一个接口边界:任务理解模块负责将用户任务转换成可执行的工具标识。
第二,工具注册。
self.tools = {”check_order”: check_order_response}
这里使用字典维护工具名称与执行函数的对应关系。
以后增加登录检查、用户信息检查、日志分析等功能时,可以逐步注册新的工具,而不是把所有业务逻辑都写在 Agent 主流程中。
第三,Agent 执行入口。
def run(self, task: str):它负责将任务理解、工具执行和结果处理串联起来。
这就是我们第一版 Agent 的核心骨架。
五、运行项目:看看它是否真的能工作
代码完成后,直接执行:
python agent.py输入:
检查订单接口预期输出:
请输入测试任务:检查订单接口收到测试任务:检查订单接口任务识别结果:check_order开始调用测试工具...测试执行结果:[通过] 响应状态码检查:接口响应正常[通过] 订单编号检查:订单编号存在[通过] 订单金额检查:订单金额正常[通过] 订单状态检查:订单状态合法测试摘要:订单接口检查全部通过。
注意:这是根据当前代码和模拟数据推导出的预期输出,不是真实项目接口的测试报告。
到这里,我们已经完成了第一个可以运行的测试 Agent 原型。
六、再做一个失败场景:Agent 能不能发现异常?
如果只验证成功场景,其实很难说明这个工具有没有实际价值。
测试人员更关心的往往是:出现问题时,能不能准确发现?
现在我们修改 tools.py 中的模拟数据:
response = {”code”: 200,”message”: ”success”,”data”: {”order_id”: ””,”amount”: -10,”status”: ”unknown”}}
重新运行:
python agent.py预期输出中的检查结果将变成:
测试执行结果:[通过] 响应状态码检查:接口响应正常[失败] 订单编号检查:订单编号缺失或为空[失败] 订单金额检查:订单金额异常[失败] 订单状态检查:订单状态异常:unknown测试摘要:订单接口检查存在异常,通过 1 项,失败 3 项。
这个小实验其实很重要。
我们不只是让 Agent 执行了一个函数,而是让它通过统一的工具调用机制,拿到了具体的测试执行结果,并将结果组织成了测试摘要。
当然,目前摘要还是由固定规则生成的,并不是大模型自主分析的结果。
但这个结构已经为后续的智能分析留下了接口。
七、回过头看:第一版 Agent 还有哪些问题?
虽然项目已经能够运行,但距离真正可用于测试工程还有一定距离。
我认为至少存在以下几个问题:
这里我想强调一个观点:
不要把接入大模型当成 Agent 项目的第一步。
大模型可以帮助我们理解自然语言、进行任务判断和生成执行计划,但工具如何注册、如何调用、如何处理异常、如何保存执行结果,这些仍然属于工程问题。
如果这些基础设计没有做好,即使接入了能力很强的大模型,最终也可能只是一个能够生成测试建议的聊天机器人。
八、本篇总结:我们真正完成了什么?
这一篇虽然没有使用大模型,但我们已经搭建了 AI Test Agent 的第一版工程骨架。
目前实现了:
一个统一的 Agent 入口。 一个简单的任务理解模块。 一个基础工具注册机制。 一个订单接口检查工具。 一套结构化执行结果。 一个最小的任务执行闭环。
它还不是一个真正具备自主规划能力的智能体,而是一个采用确定性规则驱动的 Agent 原型。
这个区别需要明确。
我更倾向于先把系统结构跑通,再逐步引入智能能力。这样每次增加一个模块,我们都能明确知道它解决了什么问题,也能验证它到底有没有带来实际价值。














































































