requests接口自动化测试

一、Requests 库核心函数 (HTTP 请求)

用于发送各种类型的 HTTP 请求,是接口测试的基础。

1. 顶层请求函数

函数名 用途 常用参数说明
requests.get() 发送 GET 请求 url, params(查询参数字典), headers, cookies, timeout
requests.post() 发送 POST 请求 url, data(表单字典), json(JSON 字典), files(上传文件), headers
requests.put() 发送 PUT 请求 通常用于更新资源,参数同 post (json 最常用)
requests.delete() 发送 DELETE 请求 通常用于删除资源
requests.request() 通用请求方法 method='GET', url, ... (可动态指定任意 HTTP 方法)

💡 关键区别

  • params: 自动拼接到 URL 后 (?key=value),用于 GET。
  • data: 提交 application/x-www-form-urlencoded 格式,用于 POST 表单。
  • json: 提交 application/json 格式,自动序列化字典为 JSON 字符串并设置 Header,用于 POST/PUT JSON 数据。
  • files: 用于文件上传,需配合 open(..., 'rb') 使用。

2. Response 响应对象属性与方法

请求返回的对象(如 resp = requests.get(...)),包含以下核心成员:

成员 类型 说明与用法
resp.status_code int 获取 HTTP 状态码 (200, 404, 500 等)
resp.json() dict/list 最常用。将响应体解析为 JSON 格式 (Python 字典或列表)
resp.text str 获取响应的文本内容 (自动根据编码解码)
resp.content bytes 获取响应的字节流下载图片/文件/视频时必须用此属性
resp.headers dict 获取响应头信息 (如 Content-Type, Set-Cookie)
resp.cookies RequestsCookieJar 获取响应中的 Cookie 对象
resp.url str 获取最终请求的 URL (若发生重定向,此为跳转后的地址)
resp.encoding str 查看或手动设置响应编码 (如 resp.encoding = 'utf-8')

二、Session 会话管理 (保持登录状态)

场景 :当接口之间存在依赖(如:先登录获取 Token/Cookie,再调用业务接口),必须使用 Session 对象来自动维护状态。

1. 核心方法与用法 (基于图片内容)

(1) 创建 Session 对象
复制代码
import requests
session = requests.Session()
(2) 使用 Session 发送请求

与普通 requests 用法一致,但自动携带该 Session 中保存的 Cookie 和 Header。

复制代码
# 第一次请求:登录,Session 自动保存返回的 Cookie
res_login = session.post(url_login, json={"user": "admin", "pwd": "123"})

# 第二次请求:业务操作,自动带上登录时的 Cookie,无需手动传
res_business = session.get(url_business)
(3) 共享/更新请求头 (全局设置)

重要函数session.headers.update()

用于在 Session 级别统一设置 Header(如 Token),后续所有请求自动生效。

复制代码
# 提取 token
token = res_login.json().get("token")

# 全局更新 Header
session.headers.update({
    "Authorization": f"Bearer {token}",
    "User-Agent": "Custom User Agent",  # 自定义 UA
    "Content-Type": "application/json"
})
(4) 关闭 Session
复制代码
session.close()

三、PyMySQL 数据库操作 (数据准备与校验)

用于测试前的数据构造 (插入测试数据)和测试后的结果验证 (查询数据库落库情况)或环境清理

1. 连接数据库 (基于图片内容)

复制代码
import pymysql

conn = pymysql.connect(
    host="192.168.1.100",   # 数据库服务器地址
    user="root",            # 登录用户名
    password="123456",      # 密码
    database="test_db",     # 要连接的数据库名称
    port=3306,              # 端口号 (默认 3306)
    charset="utf8"          # 字符集 (建议 utf8 或 utf8mb4)
)

2. 获取游标与执行 SQL

复制代码
cursor = conn.cursor()  # 获取游标对象

# 执行单条 SQL
sql = "SELECT * FROM users WHERE id = 1"
cursor.execute(sql)

# 执行带参数的 SQL (防注入)
sql_insert = "INSERT INTO users (name, age) VALUES (%s, %s)"
cursor.execute(sql_insert, ("ZhangSan", 18))

3. 获取查询结果 (基于图片内容)

方法 说明 返回值示例
cursor.fetchone() 获取1 行数据 ('ZhangSan', 18) (元组) 或 None
cursor.fetchmany(size) 获取指定行数数据 (元组列表)
cursor.fetchall() 获取全部数据 (元组列表)

4. 事务控制 (增删改必做)

复制代码
conn.commit()   # ✅ 提交事务:执行 INSERT/UPDATE/DELETE 后必须调用,否则不生效
conn.rollback() # ❌ 回滚事务:发生异常时调用,撤销操作

5. 关闭资源

复制代码
cursor.close()
conn.close()

四、JSON Schema 校验 (响应结构验证)

用于严格校验接口返回的 JSON 数据结构、字段类型、必填项是否符合契约,比简单的 assert 更强大。

1. 安装

复制代码
pip install jsonschema

2. 定义 Schema 规则

复制代码
schema = {
    "type": "object",
    "required": ["code", "msg", "data"],  # 必填字段
    "properties": {
        "code": {"type": "integer"},      # code 必须是整数
        "msg": {"type": "string"},        # msg 必须是字符串
        "data": {
            "type": "object",
            "properties": {
                "id": {"type": "integer"},
                "name": {"type": "string"}
            }
        }
    }
}

3. 执行校验

复制代码
import jsonschema

try:
    # instance: 实际响应数据 (resp.json())
    # schema: 定义的规则
    jsonschema.validate(instance=response.json(), schema=schema)
    print("✅ 结构校验通过")
except jsonschema.exceptions.ValidationError as e:
    print(f"❌ 结构校验失败: {e.message}")

五、RPC 接口测试 (Dubbo & Telnet)

针对非 HTTP 协议(如 Dubbo)的接口测试方法。

1. Telnet 命令 (手动测试)

适用于支持 Telnet 协议的 Dubbo 服务端。

复制代码
# 1. 连接
telnet <IP> <Port>

# 2. 常用命令
ls                # 查看服务列表
ps                # 查看提供者和消费者详情
invoke com.example.UserService.getUserById(1)  # 调用方法 (直接写 Java 方法调用形式)

2. dubboclient 库 (Python 自动化)

安装pip install dubbo-client

核心函数

复制代码
from dubbo_client import Client

# 1. 初始化客户端 (直连提供者 IP:Port 或 注册中心)
client = Client(['192.168.1.100:20880'])

# 2. 调用远程方法 (invoke)
result = client.invoke(
    interface='com.example.UserService',  # 接口全限定名
    method='getUserById',                 # 方法名
    args=[1],                             # 参数列表
    version='1.0.0',                      # 版本号 (可选)
    group='dubbo'                         # 分组 (可选)
)

print(result) # 输出反序列化后的 Python 对象

六、Pytest 框架集成与数据驱动

1. 核心装饰器与断言

名称 类型 说明
@pytest.mark.parametrize() 装饰器 数据驱动核心。传入参数名和参数值列表,自动生成多条用例。
assert 关键字 断言。例:assert resp.status_code == 200
setup_method() 特殊方法 每个 test_ 方法执行前运行 (常用于登录获取 Token)。
teardown_method() 特殊方法 每个 test_ 方法执行后运行 (常用于清理数据)。
pytest.main() 函数 在脚本内部启动测试。例:pytest.main(["-s", "test_api.py"])

2. 数据驱动示例

复制代码
import pytest
import requests

@pytest.mark.parametrize("username, pwd, expect_code", [
    ("admin", "123456", 200),
    ("user", "wrong", 500),
    ("", "123456", 400)
])
def test_login(username, pwd, expect_code):
    url = "http://api.com/login"
    resp = requests.post(url, json={"username": username, "password": pwd})
    assert resp.status_code == expect_code

3. JSON 文件驱动 (进阶)

将测试数据写在 .json 文件中,通过工具函数读取并传给 parametrize

复制代码
# 读取 JSON 并转换为列表 
def load_data():
    import json
    with open("data.json", "r", encoding="utf-8") as f:
        data = json.load(f)
    return [(item['user'], item['pwd'], item['code']) for item in data]

@pytest.mark.parametrize("user,pwd,code", load_data())
def test_login_dynamic(user, pwd, code):
    # 测试逻辑...
    pass

七、辅助工具函数汇总

模块 函数 用途
random random.randint(a, b) 生成随机整数 (如随机手机号、合同号)
time time.time() 获取当前时间戳 (浮点数)
组合 str(int(time.time())) 生成基于时间的唯一字符串 ID
json json.load(f) / json.dump() 读取/写入 JSON 配置文件
os/sys os.getcwd() 获取当前工作目录 (用于构建文件绝对路径)
内置 open(file, 'rb'/'wb') 二进制读写文件 (上传/下载必备)

🚀 综合实战流程示例

复制代码
import requests
import pymysql
import pytest
import random
import time

# 1. 前置准备 (Setup)
class TestContract:
    def setup_method(self):
        # A. 数据库连接 (准备数据)
        self.conn = pymysql.connect(host="...", user="...", password="...", database="...", charset="utf8")
        self.cursor = self.conn.cursor()
        
        # B. 登录获取 Token (Session 保持)
        self.session = requests.Session()
        login_data = {"user": "admin", "pwd": "123456"}
        resp = self.session.post("http://api.com/login", json=login_data)
        token = resp.json().get("token")
        self.session.headers.update({"Authorization": f"Bearer {token}"})

    def test_upload_contract(self):
        # C. 构造动态数据
        contract_no = f"HT{random.randint(10000, 99999)}_{int(time.time())}"
        
        # D. 发送请求 (文件上传)
        files = {"file": ("contract.pdf", open("contract.pdf", "rb"), "application/pdf")}
        params = {"contractNo": contract_no}
        
        resp = self.session.post("http://api.com/upload", params=params, files=files)
        
        # E. 断言
        assert resp.status_code == 200
        assert resp.json().get("code") == 200
        
        # F. 数据库校验 (验证是否落库)
        sql = "SELECT count(*) FROM contracts WHERE no = %s"
        self.cursor.execute(sql, (contract_no,))
        count = self.cursor.fetchone()[0]
        assert count == 1, "数据未成功写入数据库"

    def teardown_method(self):
        # G. 清理资源
        self.conn.rollback() # 测试数据回滚,保持环境干净
        self.cursor.close()
        self.conn.close()
        self.session.close()

if __name__ == "__main__":
    pytest.main(["-s", __file__])
相关推荐
Yuer20253 小时前
EDCA OS体系下的:QAS v0.1 实验框架(Python 版)
python·ai量化·edca os
一招定胜负3 小时前
【实战】Python + 讯飞语音识别 + 通义千问:课堂视频自动转结构化教学数据
python·音视频·语音识别
小陈工3 小时前
Docker容器化部署Python应用——从开发到生产的全流程
运维·开发语言·python·docker·云原生·容器·数据挖掘
代码方舟3 小时前
Java金融风控实战:集成天远二手车估值API构建车贷抵押资产核验系统
java·开发语言·python·自动化
码踏樱花3 小时前
PyCharm专业版Win/mac/Linux 2017-2025多版本安装教程【长期使用】
ide·python·pycharm
2401_846341653 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
困死,根本不会3 小时前
Windows下模拟树莓派:使用ble-serial创建虚拟串口实现手机蓝牙通信
windows·python·单片机·嵌入式硬件·树莓派
钱多多_qdd3 小时前
第一次使用mac,安装java相关的东西
java·python·macos
小小小米粒3 小时前
CSV 是什么?
python