通过 **DeepSeek** 辅助生成接口测试用例
在接口测试中,测试工程师通常需要根据开发提供的接口文档手动编写测试用例。这种方式不仅耗时,还容易遗漏边界场景。通过 **DeepSeek** 模型的语义理解能力,可以自动从接口文档中生成详细的接口测试用例,并结合 pytest 和 YAML 测试框架,打造一套高效、易于维护、可扩展的接口测试解决方案。
目标
1. **快速生成接口测试用例**:
- 根据开发提供的接口文档,自动生成接口测试用例,覆盖正常场景、异常场景和边界值。
2. **构建 pytest + YAML 测试框架**:
- 通过 YAML 文件定义测试数据,实现测试数据与代码分离。
3. **具备实战价值**:
- 支持动态用例生成,易扩展,适合不同项目场景。
4. **实现自动化测试**:
- 自动调用接口并校验返回值,生成详细的测试报告。
---
方案设计
### **1. DeepSeek 的作用**
通过本地部署的 DeepSeek 模型,解析输入的接口文档,生成接口测试用例。DeepSeek 的具体作用包括:
- **语义理解**:自动提取接口文档中的参数、方法、请求示例和响应示例。
- **用例生成**:生成包括正常、异常、边界值等场景的接口测试用例。
### **2. pytest + YAML 测试框架**
- **测试数据驱动**:测试用例和测试数据存储在 YAML 文件中,代码只需读取并执行,降低维护成本。
- **高复用性**:通过 pytest 的参数化功能,动态加载 YAML 文件中的用例。
- **易扩展**:支持多接口、多用例的管理和执行。
---
## **接口文档示例**
以下是开发提供的接口文档示例(`api_doc.md`):
markdown
### 接口:用户登录
- URL: `/api/v1/login`
- 方法: `POST`
- 请求参数:
- `username` (string): 用户名,必填
- `password` (string): 密码,必填
- 响应示例:
```json
{
"status": "success",
"data": {
"user_id": 12345,
"token": "abc123"
}
}
```
### 接口:获取用户信息
- URL: `/api/v1/user`
- 方法: `GET`
- 请求参数:
- `user_id` (integer): 用户 ID,必填
- `token` (string): 访问令牌,必填
- 响应示例:
```json
{
"status": "success",
"data": {
"user_id": 12345,
"username": "test_user",
"email": "test_user@example.com"
}
}
---
通过 DeepSeek 生成接口测试用例**
### **调用 DeepSeek 推理服务**
以下代码使用 DeepSeek 模型解析接口文档并生成接口测试用例。
import requests
# 本地 Ollama DeepSeek 推理服务地址
DEESEEK_API_URL = "http://localhost:11434/api/generate"
def generate_test_cases_from_docs(api_doc_path):
"""
调用 DeepSeek,根据接口文档生成测试用例
"""
with open(api_doc_path, "r", encoding="utf-8") as f:
api_doc = f.read()
# 构造 DeepSeek 请求
payload = {
"model": "deepseek-r1:1.5b",
"prompt": f"根据以下接口文档生成接口测试用例(包含正常场景、异常场景和边界值):\n\n{api_doc}"
}
headers = {"Content-Type": "application/json"}
try:
# 调用 DeepSeek API
response = requests.post(DEESEEK_API_URL, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
return result.get("response", "")
except requests.exceptions.RequestException as e:
print(f"调用 DeepSeek API 失败: {e}")
return None
# 示例接口文档路径
api_doc_path = "api_doc.md"
generated_test_cases = generate_test_cases_from_docs(api_doc_path)
# 保存生成的测试用例到 YAML 文件
if generated_test_cases:
with open("test_cases.yml", "w", encoding="utf-8") as f:
f.write(generated_test_cases)
print("测试用例已生成并保存到 test_cases.yml")
else:
print("未能生成测试用例,请检查 DeepSeek 服务状态或输入文档格式。")
生成的 YAML 测试用例**
DeepSeek 生成的 `test_cases.yml` 文件示例如下:
```yaml
- api: /api/v1/login
method: POST
test_cases:
- name: 正常登录
request:
username: test_user
password: test_password
expected_response:
status: success
- name: 用户名为空
request:
username: ""
password: test_password
expected_response:
status: error
error_message: "用户名不能为空"
- name: 密码为空
request:
username: test_user
password: ""
expected_response:
status: error
error_message: "密码不能为空"
- api: /api/v1/user
method: GET
test_cases:
- name: 正常获取用户信息
request:
user_id: 12345
token: valid_token
expected_response:
status: success
data:
user_id: 12345
username: test_user
email: test_user@example.com
- name: 用户 ID 无效
request:
user_id: -1
token: valid_token
expected_response:
status: error
error_message: "用户 ID 无效"
- name: Token 无效
request:
user_id: 12345
token: invalid_token
expected_response:
status: error
error_message: "Token 无效"
```
---
基于 pytest + YAML 实现测试框架**
### **1. 测试框架代码**
以下是基于 pytest 和 YAML 的接口测试框架代码:
```python
import pytest
import requests
import yaml
# 加载 YAML 测试用例
def load_test_cases(file_path):
with open(file_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
# 测试数据驱动
test_cases = load_test_cases("test_cases.yml")
@pytest.mark.parametrize("api_test", test_cases)
def test_api(api_test):
"""
使用 pytest 执行接口测试
"""
base_url = "http://localhost:8000" # 替换为实际的接口服务地址
# 遍历接口的测试用例
for case in api_test["test_cases"]:
name = case["name"] # 测试用例名称
request_data = case["request"] # 请求数据
expected_response = case["expected_response"] # 期望响应
# 打印测试用例名称
print(f"执行测试用例: {name}")
# 根据方法调用接口
if api_test["method"] == "POST":
response = requests.post(base_url + api_test["api"], json=request_data)
elif api_test["method"] == "GET":
response = requests.get(base_url + api_test["api"], params=request_data)
else:
pytest.fail(f"未支持的 HTTP 方法: {api_test['method']}")
# 验证响应
assert response.status_code == 200, f"HTTP 状态码错误: {response.status_code}"
actual_response = response.json()
for key, value in expected_response.items():
assert actual_response.get(key) == value, f"响应字段 {key} 校验失败,期望: {value},实际: {actual_response.get(key)}"
```
### **2. 运行测试**
运行以下命令执行测试:
pytest -v test_api.py
---
## **框架优势与扩展性**
1. **测试数据驱动**:
- 测试数据存储在 YAML 文件中,便于维护和扩展。
- 修改测试用例无需修改代码,降低维护成本。
2. **支持多接口多用例**:
- YAML 文件可以包含多个接口的测试用例,框架会自动加载并执行。
3. **易于扩展**:
- 可以扩展支持更多 HTTP 方法(如 PUT、DELETE)。
- 集成到 CI/CD 流程中,实现自动化接口测试。
4. **异常场景覆盖**:
- 通过 DeepSeek 自动生成异常场景测试用例,覆盖更多边界值。