Python+Requests零基础系统掌握接口自动化测试---youkeit.xyz/1008/
在当今的软件开发世界里,前后端分离、微服务架构已成为主流。API(应用程序编程接口)不再是后端的附属品,而是整个系统的核心枢纽。无论是 Web 前端、移动 App 还是微信小程序,它们都通过 API 与服务器进行数据交互。因此,高效、精准的接口测试,是保障产品质量、提升研发效率的关键。
Python 语言凭借其简洁的语法和强大的生态,加上 requests 这个“人手必备”的 HTTP 库,成为了接口自动化测试领域的绝对王者。本文将为你铺设一条从新手到专家的进阶之路,让你不仅能玩转 requests,更能构建起覆盖多端业务的自动化测试体系。
第一阶段:入门篇——发送你的第一个请求
这个阶段的目标是熟悉 requests 的基本用法,能够对单个接口进行请求和断言。
1. 安装与环境准备
首先,确保你已经安装了 Python。然后,通过 pip 安装 requests 库:
bash
复制
pip install requests
2. 核心四步曲:GET、POST、PUT、DELETE
HTTP 协议中最常见的四种请求方法,requests 都提供了对应的方法。
代码示例:GET 请求(获取数据)
python
复制
import requests
# 目标URL(这里以一个公共的测试API为例)
url = "https://jsonplaceholder.typicode.com/posts/1"
# 发送GET请求
response = requests.get(url)
# 打印响应结果
print(f"状态码: {response.status_code}")
print(f"响应头: {response.headers}")
print(f"响应内容 (JSON): {response.json()}")
print(f"响应内容 (文本): {response.text}")
代码示例:POST 请求(创建数据)
python
复制
import requests
import json
url = "https://jsonplaceholder.typicode.com/posts"
# 请求体数据
payload = {
'title': 'foo',
'body': 'bar',
'userId': 1
}
# 发送POST请求,headers指定内容类型为JSON
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(payload), headers=headers)
# 或者更简洁地使用 json 参数,requests 会自动序列化并设置 Content-Type
# response = requests.post(url, json=payload)
print(f"状态码: {response.status_code}")
print(f"创建的资源ID: {response.json()['id']}")
PUT(更新)和 DELETE(删除) 的用法与 POST 类似,只需调用 requests.put() 和 requests.delete() 即可。
3. 响应处理与断言
测试的核心在于“断言”,即验证结果是否符合预期。
代码示例:添加断言
python
复制
import requests
url = "https://jsonplaceholder.typicode.com/posts/1"
response = requests.get(url)
# --- 断言开始 ---
# 1. 断言状态码是否为 200
assert response.status_code == 200, f"期望状态码为200,但实际为 {response.status_code}"
# 2. 断言响应头中的 Content-Type
assert 'application/json' in response.headers['Content-Type']
# 3. 断言响应体中的数据
response_data = response.json()
assert response_data['userId'] == 1
assert 'sunt aut facere' in response_data['title']
print("所有断言通过!")
第一阶段结束时,你应该能: 独立完成对任何已知接口的请求,并能编写基本的断言来验证其正确性。
第二阶段:进阶篇——处理真实世界的复杂性
真实世界的接口测试远比上面复杂。你需要处理认证、动态参数、文件上传、异常情况等。
1. 处理认证:Cookie、Session、Token
- Cookie/Session 认证:
requests的Session对象能自动处理 Cookie,非常方便。
python
复制
import requests
# 创建一个Session对象,它会跨请求保持Cookie
s = requests.Session()
# 1. 登录接口,Session会自动保存返回的Cookie
login_data = {'username': 'testuser', 'password': 'password123'}
s.post("https://example.com/login", data=login_data)
# 2. 访问需要登录才能访问的接口,无需手动携带Cookie
response = s.get("https://example.com/user/profile")
print(response.json()) # 成功获取到用户信息
- Token 认证 (Bearer Token) :是目前 API 最主流的认证方式,通常放在请求头中。
python
复制
import requests
# 假设这是通过登录获取到的token
auth_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
headers = {
'Authorization': f'Bearer {auth_token}'
}
response = requests.get("https://api.example.com/secure/data", headers=headers)
print(response.json())
2. 处理动态参数与关联
接口测试中,一个接口的输出往往是另一个接口的输入。例如,创建订单后,需要用返回的订单ID去查询订单详情。
代码示例:接口关联
python
复制
import requests
# 1. 创建订单
create_order_url = "https://api.example.com/orders"
order_data = {"productId": 123, "quantity": 2}
create_response = requests.post(create_order_url, json=order_data)
# 从响应中提取订单ID
order_id = create_response.json()['orderId']
print(f"订单创建成功,ID: {order_id}")
# 2. 使用订单ID查询订单详情
get_order_url = f"https://api.example.com/orders/{order_id}"
get_response = requests.get(get_order_url)
# 断言订单详情
assert get_response.json()['productId'] == 123
print("订单详情查询并断言成功!")
3. 文件上传与下载
- 文件上传
python
复制
import requests
url = "https://api.example.com/upload"
# 'files' 参数接收一个字典,key是表单字段名,value是文件对象
files = {'file': open('report.pdf', 'rb')}
response = requests.post(url, files=files)
print(response.status_code)
- 文件下载
python
复制
import requests
url = "https://example.com/somefile.zip"
response = requests.get(url, stream=True) # stream=True 对于大文件很重要
with open('downloaded_file.zip', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print("文件下载完成!")
第二阶段结束时,你应该能: 轻松应对各种认证方式,自如地处理接口间的数据依赖,并能进行文件相关的测试。
第三阶段:精通篇——构建自动化测试框架
单个脚本的测试能力有限,我们需要一个框架来组织用例、管理配置、生成报告,实现真正的自动化。
1. 框架设计思想
一个基础的测试框架应包含:
- 配置管理:将环境地址、账号密码等可变信息抽离到配置文件。
- 用例组织:将测试数据和测试逻辑分离,方便维护和扩展。
- 断言封装:提供更丰富、更易读的断言方法。
- 报告生成:自动生成可视化测试报告。
2. 实战:基于 Pytest 的轻量级框架
pytest 是 Python 最强大的测试框架之一,与 requests 结合堪称完美。
项目结构:
复制
api_test_project/
├── config/
│ └── settings.py # 配置文件
├── test_data/
│ └── user_data.json # 测试数据
├── utils/
│ └── api_client.py # 封装的API客户端
├── test_cases/
│ └── test_user_api.py # 测试用例
└── requirements.txt # 项目依赖
代码实现:
config/settings.py
python
复制
# 开发环境
DEV = {
'base_url': 'https://dev-api.example.com'
}
# 生产环境
PROD = {
'base_url': 'https://api.example.com'
}
# 默认使用开发环境
config = DEV
utils/api_client.py(封装一个 BaseClient)
python
复制
import requests
from config.settings import config
class BaseClient:
def __init__(self):
self.base_url = config['base_url']
self.session = requests.Session()
self.token = None
def login(self, username, password):
"""登录并获取token"""
login_data = {"username": username, "password": password}
response = self.session.post(f"{self.base_url}/login", json=login_data)
response.raise_for_status() # 如果请求失败,抛出异常
self.token = response.json()['token']
self.session.headers.update({'Authorization': f'Bearer {self.token}'})
def get(self, endpoint, **kwargs):
return self.session.get(f"{self.base_url}{endpoint}", **kwargs)
def post(self, endpoint, **kwargs):
return self.session.post(f"{self.base_url}{endpoint}", **kwargs)
test_cases/test_user_api.py(使用 pytest 编写用例)
python
复制
import pytest
from utils.api_client import BaseClient
# pytest 的 Fixture,用于创建和销毁客户端实例
@pytest.fixture(scope="module")
def api_client():
client = BaseClient()
# 假设所有用例都需要登录
client.login("testuser", "password123")
yield client
# 这里可以添加清理代码,比如 client.logout()
def test_get_user_profile(api_client):
"""测试获取用户信息"""
response = api_client.get("/user/profile")
assert response.status_code == 200
assert response.json()['username'] == "testuser"
def test_update_user_profile(api_client):
"""测试更新用户信息"""
update_data = {"nickname": "New Nickname"}
response = api_client.post("/user/profile", json=update_data)
assert response.status_code == 200
# 验证更新是否成功
response = api_client.get("/user/profile")
assert response.json()['nickname'] == "New Nickname"
- 运行测试并生成报告
bash
复制
# 安装依赖
pip install requests pytest pytest-html
# 运行测试并生成HTML报告
pytest --html=report.html
第三阶段结束时,你应该能: 独立搭建一个结构清晰、易于维护的接口自动化测试框架,并能持续集成到 CI/CD 流程中。
第四阶段:宗师篇——打通多端接口联动测试
这是接口测试的终极挑战:模拟一个完整的用户业务流,这个流程可能跨越 Web 端、App 端和小程序,它们调用不同的后端微服务,但数据是互联互通的。
1. 场景:用户在 App 下单,然后在 Web 端查看订单
这个流程涉及:
- App 端:调用“用户认证”微服务 -> 调用“商品”微服务 -> 调用“订单”微服务。
- Web 端:调用“用户认证”微服务 -> 调用“订单”微服务。
2. 测试策略:业务流驱动
我们的测试不再是按 API 划分,而是按“用户故事”或“业务流”来组织。
代码示例:模拟跨端下单-查看流程
python
复制
import pytest
from utils.api_client import BaseClient
# 我们可以扩展 BaseClient 或创建不同的客户端来模拟不同端
# 这里为了简化,仍使用一个客户端,但逻辑上区分端
@pytest.fixture(scope="module")
def app_client():
"""模拟App客户端"""
client = BaseClient()
# App端可能使用不同的登录方式或client_id
client.login("app_user", "password")
client.session.headers.update({'X-Client-Platform': 'App'}) # 添加平台标识
yield client
@pytest.fixture(scope="module")
def web_client():
"""模拟Web客户端"""
client = BaseClient()
client.login("web_user", "password") # 可能是同一个账号
client.session.headers.update({'X-Client-Platform': 'Web'})
yield client
def test_cross_platform_order_flow(app_client, web_client):
"""
测试完整的跨端业务流:
1. App端用户下单
2. Web端用户查看该订单
"""
# --- 步骤1: App端下单 ---
order_payload = {"productId": "prod-001", "quantity": 1}
app_order_response = app_client.post("/orders", json=order_payload)
assert app_order_response.status_code == 201
order_id = app_order_response.json()['orderId']
print(f"App端下单成功,订单ID: {order_id}")
# --- 步骤2: Web端查看订单 ---
# 注意:这里假设App和Web登录的是同一个账号,所以能看到订单
web_order_response = web_client.get(f"/orders/{order_id}")
assert web_order_response.status_code == 200
order_detail = web_order_response.json()
assert order_detail['productId'] == "prod-001"
assert order_detail['status'] == 'CREATED'
print(f"Web端成功查到订单,状态: {order_detail['status']}")
# --- 步骤3: App端支付订单 ---
pay_response = app_client.post(f"/orders/{order_id}/pay")
assert pay_response.status_code == 200
print("App端支付成功")
# --- 步骤4: Web端再次查看,验证状态更新 ---
web_order_response_after_pay = web_client.get(f"/orders/{order_id}")
assert web_order_response_after_pay.json()['status'] == 'PAID'
print("Web端验证订单状态已更新为'已支付'")
引用
3. 核心思想
- 数据驱动:测试数据(如用户账号、商品ID)应外部化,支持不同场景的切换。
- 状态管理:清晰地知道每一步操作后,系统的数据状态应该是什么,并用下一个操作去验证它。
- 环境隔离:确保测试在独立的环境中运行,避免与开发或生产数据混淆。
- Mock 与 Stub:当依赖的第三方服务不可用或不稳定时,使用 Mock 技术模拟其响应,保证测试的稳定性。
第四阶段结束时,你已经不再是“接口测试工程师”,而是“API 质量保障专家”。 你能够站在用户和业务的视角,设计和执行端到端的复杂场景测试,为整个系统的稳定性和一致性提供最高级别的保障。
结语
从 requests.get() 的一行代码,到驱动多端业务联动的自动化框架,这条路是每一位优秀测试工程师的成长缩影。requests 是你手中最锋利的剑,而 Python 的生态则是你坚实的后盾。掌握它们,你便拥有了洞察系统内部运作、保障产品质量的强大能力。不断实践,持续思考,你将在 API 测试的道路上走得更远,成为团队中不可或缺的核心力量。