Python接口自动化测试脚本编写:基于requests库实战

方予
方予
发布时间:2026-10-28 | 7人浏览过
原创

本文基于Python的requests库,从基础调用、参数组织、响应断言到Session状态保持与模块化脚本封装,提供完整详实的接口自动化测试脚本实战指南。

接口自动化测试旨在通过编写程序替代人工点击,对服务端的应用程序接口(API)进行自动化调用与结果校验。Python的requests库因其简洁优雅的API设计,成为了编写HTTP接口测试脚本的首选基础库。本文将围绕requests库的核心功能,从环境准备、常用请求方法封装、测试用例断言编写,到会话保持与分层脚本设计,通过具体的代码示例逐步讲解如何完成一套实用的接口测试脚本。

一、自动化测试核心交互流程

在编写测试脚本前,需要明确自动化测试运行的生命周期。与浏览器行为类似,测试脚本充当HTTP客户端,构造请求报文发送至目标服务器,接收到响应报文后,解析状态码与数据体,并与预期结果进行比对,最终输出断言结论。

Python接口自动化测试脚本编写:基于requests库实战
图1:接口自动化脚本执行流水线

二、测试环境准备与基础调用

编写脚本前需安装requests模块。建议在Python虚拟环境中通过pip安装:

pip install requests

完成安装后,首先编写一个最简的GET请求,验证目标接口的基础连通性并检查响应内容:

import requests

# 目标接口地址(以公网回显测试接口为例)
base_url = "https://httpbin.org/get"

# 构造请求查询参数
query_params = {"category": "book", "page": 1}

# 发送GET请求并设置超时时间(单位:秒)
response = requests.get(url=base_url, params=query_params, timeout=5)

# 输出状态码与响应体
print("Status Code:", response.status_code)
print("Response JSON:", response.json())
注意事项:所有生产或测试脚本在调用requests.get()或requests.post()时,都必须显式指定timeout参数。如果不设置超时时间,当目标服务器挂起或网络故障时,脚本将一直阻塞,导致整个测试集运行卡死。

三、常见请求方法与传参差异对比

在接口自动化中,最常见的请求是GET与POST。许多初学者容易混淆params、data和json三个传参参数的区别。理解它们的HTTP报文差异是写出可靠自动化用例的关键:

  • params:用于将字典编码为查询字符串附加在URL后(如?k=v),主要用于GET请求。
  • data:用于向请求体提交表单数据(Content-Type: application/x-www-form-urlencoded)。
  • json:用于将Python字典自动序列化为JSON字符串,并自动设置头信息为Content-Type: application/json。当前大部分RESTful API均采用此格式。
Python接口自动化测试脚本编写:基于requests库实战
图2:requests三种核心传参方式与HTTP报文对应关系

下面演示发送POST请求提交JSON数据的完整写法:

payload = {
    "username": "tester_alice",
    "email": "alice@example.com",
    "role": "QA"
}
headers = {
    "User-Agent": "ApiTestBot/1.0"
}

response = requests.post(
    url="https://httpbin.org/post",
    json=payload,
    headers=headers,
    timeout=5
)
data = response.json()
print("服务端解析到的JSON:", data["json"])

四、自动化测试用例编写与多维度断言

自动化测试脚本与普通爬虫脚本的最大区别在于断言(Assertion)。脚本必须能够自动判断结果是否符合预期。在接口测试中,断言通常由外到内分为三个层级:

  1. HTTP状态码断言:确认HTTP连接与路由正常,如断言状态码为200、201或204。
  2. 业务状态码与消息断言:在响应JSON中确认业务字段,如code == 0或message == "success"。
  3. 业务实体数据精确断言:验证返回的数据内容与输入或数据库记录是否一致。

以下为一个完整的测试函数示例,模拟用户登录接口的断言检验:

def test_login_success():
    login_url = "https://httpbin.org/post"
    body = {
        "username": "admin",
        "password": "correct_password"
    }

    response = requests.post(login_url, json=body, timeout=5)

    # 1. 断言 HTTP 状态码
    assert response.status_code == 200, f"期望状态码200,实际返回: {response.status_code}"

    # 2. 解析 JSON
    result = response.json()

    # 3. 断言提交的业务参数完整性
    json_body = result.get("json", {})
    assert json_body.get("username") == "admin", "响应中用户名与提交不一致"
    
    # 4. 断言响应头信息
    assert "application/json" in response.headers.get("Content-Type", ""), "响应类型非JSON"
    
    print("test_login_success: 测试通过")

if __name__ == "__main__":
    test_login_success()

五、基于 Session 的上下文状态与鉴权保持

在真实的业务场景中,很多接口必须在登录后才能调用。如果每次都使用独立的requests.post()调用,每次连接都会创建新的TCP连接,且不会自动携带上一个请求返回的Cookie或Token。

requests.Session()对象提供了跨请求保持Cookie的能力,同时它还支持在Session级别配置公共Headers(如统一的Authorization头),避免在每个请求中重复传入。

Python接口自动化测试脚本编写:基于requests库实战
图3:Session在接口自动化测试中的鉴权维护与连接复用机制

Session的典型代码写法如下:

# 实例化会话对象
session = requests.Session()

# 配置全局通用请求头
session.headers.update({
    "User-Agent": "AutomationTestRunner/1.0",
    "Accept": "application/json"
})

# 1. 模拟登录,服务端返回 Set-Cookie
session.get("https://httpbin.org/cookies/set?token=secret_123456", timeout=5)

# 2. 访问受保护接口,Session 会自动携带上述 Cookie
profile_res = session.get("https://httpbin.org/cookies", timeout=5)
cookies_in_server = profile_res.json().get("cookies", {})

# 3. 校验状态保持
assert cookies_in_server.get("token") == "secret_123456", "Cookie 会话未成功保持"
print("会话保持验证成功!")

六、脚本工程化:模块化封装与实战演练

直接在测试脚本中散落编写requests.get或硬编码URL,会导致测试代码重复度高、后期维护困难。当接口地址发生变动或鉴权方式升级时,修改成本极高。工程化的做法是将接口调用逻辑封装为客户端类(Client),测试用例只负责构造测试数据和执行断言。

Python接口自动化测试脚本编写:基于requests库实战
图4:接口自动化测试分层结构设计模型

下面是一个可直接用于实际项目的轻量级封装示例:

import requests

class BaseApiClient:
    """通用接口基础类,维护 Session 和基础 URL"""
    def __init__(self, base_url: str):
        self.base_url = base_url.rstrip("/")
        self.session = requests.Session()
        self.session.headers.update({"Accept": "application/json"})

    def request(self, method: str, endpoint: str, **kwargs) -> requests.Response:
        url = f"{self.base_url}/{endpoint.lstrip('/')}"
        # 设置默认超时时间 5 秒
        kwargs.setdefault("timeout", 5)
        response = self.session.request(method=method, url=url, **kwargs)
        return response

class UserApiClient(BaseApiClient):
    """业务接口类,封装具体业务方法"""
    def create_user(self, name: str, job: str) -> requests.Response:
        return self.request("POST", "/post", json={"name": name, "job": job})

    def get_user_list(self, page: int = 1) -> requests.Response:
        return self.request("GET", "/get", params={"page": page})

# --- 测试用例函数 ---
def test_user_lifecycle():
    client = UserApiClient(base_url="https://httpbin.org")

    # 执行创建用户接口测试
    create_res = client.create_user(name="Bob", job="Engineer")
    assert create_res.status_code == 200, f"创建用户失败,状态码: {create_res.status_code}"
    
    json_data = create_res.json().get("json", {})
    assert json_data.get("name") == "Bob", "返回的姓名不符合预期"
    assert json_data.get("job") == "Engineer", "返回的岗位不符合预期"

    # 执行获取用户列表测试
    list_res = client.get_user_list(page=2)
    assert list_res.status_code == 200
    assert list_res.json().get("args", {}).get("page") == "2"

    print("用户全生命周期接口测试通过!")

if __name__ == "__main__":
    test_user_lifecycle()

七、常见问题排查与编写注意事项

1. JSONDecodeError 异常:当接口返回的不是合法 JSON(例如服务器报 502 错误返回 HTML 页面,或返回空响应体)时,调用 response.json() 会直接抛出异常。编写脚本时应先校验 response.status_code == 200,或者在断言前检查返回的 Content-Type。

2. 字典键不存在 KeyError:在解析嵌套较深的 JSON 结构时,直接使用 data['a']['b'] 容易在字段缺失时导致测试脚本崩溃。推荐使用 dict.get('key', default) 获取字段并进行判断,给出明确的错误提示。

3. HTTPS 证书校验问题:在内网测试环境中,如果使用的是自签名证书,requests 可能会抛出 SSLError。可通过在请求中设置 verify=False 忽略证书校验,但需注意在生产环境应保持默认的安全校验。

通过本文的实战演练,从底层的HTTP请求组装,到Session层面的连接和状态维护,再到业务对象的面向对象封装,读者可以建立起编写Python接口测试脚本的完整体系。后续可进一步结合pytest测试框架实现测试用例自动发现、参数化驱动以及测试报告生成。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表