ChatGPT软件测试新手入门:从零搭建自动化测试框架

1次阅读
没有评论

共计 3236 个字符,预计需要花费 9 分钟才能阅读完成。

image.webp

为什么 ChatGPT API 测试与众不同

刚接触 ChatGPT API 测试时,我发现它和普通 HTTP 接口测试有三大差异点:

ChatGPT 软件测试新手入门:从零搭建自动化测试框架

  1. 对话状态维护 :每个对话都有上下文关联,就像人类聊天需要记住前面说过什么
  2. token 消耗动态计算 :每次请求的 token 使用量直接影响计费,需要特别监控
  3. 流式响应处理 :当 stream=True 时,数据是分块传输的,传统断言方式会失效

手工测试 vs 自动化测试

用 Postman 测试 ChatGPT 就像用筷子吃牛排——能行但不专业:

  • 手工测试优点:
  • 快速验证单次接口响应
  • 直观看到返回的 JSON 结构

  • 自动化测试优势:

  • 自动维护对话上下文
  • 批量执行边界值测试
  • 实时统计 token 消耗
  • 自动生成可追溯的测试报告

实战:搭建测试框架

1. API 调用封装

先安装必要依赖:

pip install requests pytest

核心封装代码(chatgpt_client.py):

import os
from typing import Iterator, Dict
import requests

class ChatGPTTestClient:
    def __init__(self, api_key: str):
        self.base_url = "https://api.openai.com/v1/chat/completions"
        self.headers = {"Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        # 初始化对话历史
        self.conversation_history = []

    def send_message(
        self,
        prompt: str,
        stream: bool = False
    ) -> Iterator[Dict] | Dict:
        """发送消息并处理流式 / 非流式响应"""
        self.conversation_history.append({"role": "user", "content": prompt})

        payload = {
            "model": "gpt-3.5-turbo",
            "messages": self.conversation_history,
            "stream": stream
        }

        response = requests.post(
            self.base_url,
            headers=self.headers,
            json=payload,
            timeout=30
        )

        if stream:
            return self._handle_stream_response(response)
        else:
            return self._handle_normal_response(response)

    def _handle_normal_response(self, response: requests.Response) -> Dict:
        """处理普通响应"""
        response.raise_for_status()
        data = response.json()
        assistant_reply = data["choices"][0]["message"]
        self.conversation_history.append(assistant_reply)
        return data

    def _handle_stream_response(self, response: requests.Response) -> Iterator[Dict]:
        """处理流式响应"""
        response.raise_for_status()
        for chunk in response.iter_lines():
            if chunk:
                yield json.loads(chunk.decode("utf-8").lstrip("data:"))

2. Pytest 测试用例设计

测试文件示例(test_chatgpt.py):

import pytest
from chatgpt_client import ChatGPTTestClient

@pytest.fixture(scope="module")
def client():
    """共享测试客户端"""
    return ChatGPTTestClient(os.getenv("OPENAI_API_KEY"))

# 参数化测试不同长度的输入
@pytest.mark.parametrize("prompt", [
    "你好",
    "请用 200 字介绍量子力学",
    "a" * 1000  # 边界值测试
])
def test_single_turn_chat(client, prompt):
    """测试单轮对话"""
    response = client.send_message(prompt)
    assert "choices" in response
    assert len(response["choices"][0]["message"]["content"]) > 0

# 测试上下文保持
def test_multi_turn_chat(client):
    """测试多轮对话记忆"""
    client.send_message("我的名字是张三")
    response = client.send_message("我刚才说我叫什么名字?")
    assert "张三" in response["choices"][0]["message"]["content"]

3. 对话上下文方案对比

方案 A:session_id 跟踪

  • 优点:服务端自动维护状态
  • 缺点:无法在测试中断后恢复对话

方案 B:内存缓存(示例代码采用)

  • 优点:
  • 完全掌控对话历史
  • 支持测试失败后重建上下文
  • 缺点:
  • 需要自行处理 token 限制
  • 大对话集占用内存

生产环境避坑指南

1. 异步调用超时设置

ChatGPT API 有时响应较慢,必须设置双重超时:

# 在 requests.post() 中设置
response = requests.post(
    url,
    timeout=(10, 30)  # 连接超时 10 秒,读取超时 30 秒
)

2. 敏感数据过滤

测试报告中的 API 密钥必须脱敏:

# 在 pytest 钩子中处理
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
    report = (yield).get_result()
    if report.failed:
        report.longrepr = str(report.longrepr).replace(os.getenv("OPENAI_API_KEY"), 
            "***"
        )

3. 测试幂等性设计

避免测试互相影响的方法:

  1. 每个测试用例使用独立对话 ID
  2. 测试前后清理历史记录
  3. 使用 pytest 的 tmpdir 处理测试数据
@pytest.fixture
def clean_client(client):
    """每次测试后清空历史"""
    yield client
    client.conversation_history = []

延伸思考

多轮对话断言机制

可以考虑:
1. 关键词命中检查
2. 语义相似度对比(使用 sentence-transformers)
3. 意图识别验证

模拟 API 限流

使用 unittest.mock 模拟 429 响应:

from unittest.mock import patch

def test_rate_limit():
    with patch("requests.post") as mock_post:
        mock_post.return_value.status_code = 429
        response = client.send_message("test")
        assert "rate limit" in response["error"]["message"]

总结建议

建议从简单测试用例开始,逐步增加:
1. 基础功能验证 → 2. 异常场景覆盖 → 3. 性能监控

可以结合 Jenkins 或 GitHub Actions 实现持续测试,每次代码提交都自动验证 ChatGPT 接口的兼容性。对于企业级应用,建议增加对话质量评估模块,用自动化手段检查回复的相关性和安全性。

正文完
 0
评论(没有评论)