查询天气交通的Agent工具的测试

1.单元测试

  • 目标 :验证每个函数/方法在隔离环境下的正确性。

  • 范围

    导入被测试模块

    from weather_traffic_agent import (
    LLMWeatherTrafficAgent,
    WeatherTool,
    TrafficTool,
    WeatherAPI,
    TrafficAPI,
    QueryType
    )

  • 特点 :不依赖真实网络,使用 Mock 完全模拟 API。

  • 优先级 :最高,必须全部通过才能继续。

|-------------------------------------------|---------------------------------------------------------|
| 测试内容 | 方法 |
| 环境变量缺失 | 模拟 os.getenv 返回 None ,断言抛出 ValueError |
| WeatherTool.execute 正常/异常 | Mock WeatherAPI.get_weather ,检查返回值格式 |
| TrafficTool.execute 正常/异常 | Mock TrafficAPI.get_traffic ,检查返回值格式 |
| LLMWeatherTrafficAgent._call_model 返回工具调用 | Mock client.chat.completions.create ,构造带 tool_calls 的响应 |
| LLMWeatherTrafficAgent.process 完整流程 | 模拟两次模型调用,验证最终回复内容包含工具结果 |
| 模型不调用工具 | 模拟直接文本回复,验证 process 直接返回该文本 |
| 工具执行失败 | 模拟工具返回 {"error":...} ,验证最终回复包含错误信息 |


2.集成测试

  • 目标 :验证 Agent 内部模块(解析 → 模糊处理 → 调用 API → 生成回复)之间的协作。
  • 范围
  • 完整流程:从用户输入到最终回复,使用 Mock API。
  • 错误传播:API 错误如何在整个链条中传递并返回给用户。
  • 上下文存储:检查 self.context 是否正确记录。
  • 特点 :测试 process 方法,但 API 仍用 Mock,避免外部依赖。

|-------------|-----------------------------------|
| 测试场景 | 描述 |
| 1. 天气查询 | 模拟模型返回 get_weather 工具调用,执行后生成最终回复 |
| 2. 交通查询 | 模拟模型返回 get_traffic 工具调用 |
| 3. 无工具调用 | 模拟模型直接回复(闲聊) |
| 4. 工具执行失败 | 模拟工具返回错误,验证最终回复包含错误信息 |
| 5. 未知工具 | 模拟模型请求未知工具,验证错误处理 |
| 6. 多轮对话(可选) | 模拟连续两次对话,验证上下文记忆(需要 Agent 支持) |
| 7. 环境变量缺失 | 已在单元测试中覆盖,不再重复 |


3.业务逻辑测试

  • 目标 :验证具体业务规则(如交通距离合理性、日期映射、多城市处理)是否符合需求。
  • 内容 :涵盖正常流程、异常边界、业务约束(如时间不能为负)。
  • 注意 :与集成测试有部分重叠,但更关注业务语义而非调用链。

mock版本+真实LLM

|----------|--------------------------------------------------------------------------------------------------|--------------------------------------|
| 分类 | 测试方法 | 验证行为 |
| 天气正常 | test_weather_beijing , test_weather_shanghai | 正确识别城市、调用工具、返回天气 |
| 天气异常 | test_weather_api_timeout , test_weather_invalid_date , test_weather_past_date | API 超时、无效日期、过去日期时,Agent 能转发错误并生成友好提示 |
| 天气边界 | test_weather_invalid_city , test_weather_fuzzy_only | 不存在城市(工具报错)和只问天气无城市(模型直接回复)的处理 |
| 交通正常 | test_traffic_bj_sh | 识别起终点、调用工具、返回交通信息 |
| 交通异常 | test_traffic_api_error , test_traffic_same_city , test_traffic_invalid_city | API 错误、相同城市、无效城市时的错误处理 |
| 交通边界 | test_traffic_missing_dest , test_traffic_missing_origin | 缺终点/起点时,Agent 要求补充信息(或自动补起点) |
| 联动 | test_joint_weather_and_traffic , test_joint_weather_ok_traffic_missing , test_joint_both_missing | 多工具调用、部分参数缺失、全部参数缺失时的综合处理 |


4.输入鲁棒性与安全性测试

  • 目标 :评估系统对各类非法、恶意、边界输入的承受能力。
  • 内容 :拼写错误、同义词、提示注入尝试(虽无 LLM,但测试解析器不受影响)、特殊字符、空输入、超长输入。
  • 目的 :确保系统不崩溃且返回合理提示。

|---------|-----------------------|---------------|
| 类别 | 测试用例 | 验证点 |
| 鲁棒性 | 拼写错误、同音字、中英混合 | 能正确识别城市 |
| | 特殊字符、超长输入 | 不崩溃,友好提示 |
| | 矛盾/隐含否定 | 正确提取意图 |
| | 非常规日期 | 识别并提示无效 |
| | 重复城市名、无关关键词 | 正确提取城市或询问 |
| 安全性 | 提示注入、获取系统提示、获取API Key | 不执行注入,不泄露敏感信息 |
| | 跨城市越权(不存在的城市) | 合理拒绝或引导 |


5.性能与并发测试

  • 目标 :测量响应时间、并发处理能力和长时间运行的稳定性。

|----------------|----------|----------|-----------|
| 指标 | 串行(1并发) | 并发 5 | 并发 10 |
| 请求总数 | 40 | 20 | 30 |
| 成功数 | 40 | 20 | 30 |
| 成功率 | 100% | 100% | 100% |
| 平均耗时 (秒) | 2.831 | 2.723 | 2.633 |
| 中位数 (秒) | 2.884 | 2.650 | 2.608 |
| 最小值 (秒) | 1.839 | 1.939 | 2.133 |
| 最大值 (秒) | 3.741 | 3.404 | 3.260 |
| 标准差 (秒) | 0.414 | 0.398 | 0.253 |
| 95%分位数 (秒) | 3.584 | 3.404 | 3.218 |
| 99%分位数 (秒) | 3.741 | 3.404 | 3.260 |


6.可观测性与配置测试

  • 目标 :验证日志记录、上下文存储、配置变更后的行为。

|----------|------------|----|---------------------------------------------------------------|
| 测试类别 | 测试项 | 状态 | 关键验证点 |
| 可观测性 | 天气查询后上下文存储 | 通过 | context 存在,raw_input 正确记录,query_type 为 UNKNOWN (LLM Agent 特性) |
| 可观测性 | 交通查询后上下文存储 | 通过 | context 存在,raw_input 正确记录,query_type 为 UNKNOWN |
| 可观测性 | 日志输出 | 通过 | AGENT_VERBOSE=1 生效,控制台输出调试信息 |
| 配置 | 默认城市(上海) | 通过 | 未指定城市时,回复非空,context 存在 |
| 配置 | 默认城市(广州) | 通过 | 同上 |
| 配置 | 模型参数传递 | 通过 | 自定义 model 、api_key 、base_url 正确传递到 OpenAI 客户端 |
| 配置 | 超时处理 | 通过 | 工具超时时,Agent 生成友好的错误提示(非崩溃) |

7.提示词测试

提示词测试其实已经在测试中覆盖,根据测试结果不断优化提示词。

|-----------------------|--------------------------------------------------------------------|
| 测试维度 | 覆盖用例 |
| 指令遵循 (调用正确工具) | test_tool_call_weather , test_tool_call_traffic , test_joint_tools |
| 边界表达 (日期解析) | test_relative_date |
| 对抗鲁棒性 (注入拒绝) | test_prompt_injection |
| 拒绝模拟调用 (无工具时直接回复) | test_no_tool_for_greeting , test_fuzzy_weather |


8.回归测试

  • 目标 :确保所有修改未破坏已有功能。
  • 方法 :将上述所有测试固化为自动化套件,每次提交后全部运行。

|------------|--------------------------------------------------|------------------------|
| 测试维度 | 测试文件 | 关键验证点 |
| 核心逻辑 | test_unit.py | 解析、模糊处理、回复生成、工具执行 |
| 流程集成 | test_integration.py | 完整流程、错误传播、上下文存储 |
| 业务场景 | test_e2e_mock.py | 正常、异常、边界、联动(Mock LLM) |
| 真实 LLM | test_e2e_functional_weather.py 、test_real_llm.py | 真实模型下的天气/交通查询、异常、模糊、联动 |
| 鲁棒性 | test_robustness_security.py | 拼写错误、特殊字符、提示注入、敏感信息泄露 |
| 性能 | test_performance_concurrency.py | 响应时间、并发成功率 |
| 可观测性 | test_observability_config.py | 日志、上下文、配置参数、超时处理 |