以下是从0到1学习pytest
接口自动化测试的教程,包含环境搭建、核心概念、实战案例及项目落地,适合零基础入门。
一、前期准备:明确学习目标
1. 为什么选择pytest?
- 简洁灵活:语法简单,比unittest更易上手,支持丰富的插件扩展。
- 功能强大:支持参数化、 fixtures(前置后置处理)、标记(mark)、测试用例分组等。
- 社区生态好:可集成
requests
(接口请求)、Allure
(报告生成)、Jenkins
(持续集成)等工具。
2. 学习路径
基础环境搭建 → 接口测试基础 → pytest核心语法 → 接口自动化实战 → 项目优化与集成
二、环境搭建
1. 安装Python
- 下载:从Python官网下载3.6+版本(建议3.8+)。
- 验证:命令行输入
python --version
,显示版本号即成功。 - 虚拟环境(可选):
# 创建虚拟环境 python -m venv myenv # 激活环境(Windows) myenv\Scripts\activate # 激活环境(macOS/Linux) source myenv/bin/activate
2. 安装pytest和requests
pip install pytest requests # requests用于发送HTTP请求
3. 工具推荐
- 编辑器:VS Code(安装Python插件)或PyCharm。
- 接口调试工具:Postman/Charles(辅助调试接口)。
三、接口测试基础
1. 什么是接口测试?
- 定义:测试系统组件间的接口,验证数据交互、逻辑正确性(如HTTP接口的
GET/POST
请求)。 - 核心关注点:
- 请求参数(Query、Body、Header)是否正确。
- 响应状态码(如200成功、400参数错误、500服务器错误)。
- 响应数据(JSON/XML格式是否符合预期)。
2. HTTP协议基础
- 常见请求方法:
GET
(查询)、POST
(创建)、PUT
(更新)、DELETE
(删除)。 - 响应状态码:
- 2xx:成功(如200 OK)。
- 4xx:客户端错误(如404 Not Found)。
- 5xx:服务器错误(如500 Internal Server Error)。
- 工具实践:用Postman发送请求,观察响应结果(先手动调试,再自动化)。
四、pytest核心语法入门
1. 第一个pytest测试用例
步骤:
- 创建测试文件
test_api.py
。 - 编写测试函数(以
test_
开头)。 - 使用
assert
断言验证结果。
示例:测试百度首页状态码
import requests
def test_baidu_status_code():
# 发送GET请求
response = requests.get("https://www.baidu.com")
# 断言状态码为200
assert response.status_code == 200
运行测试:
pytest test_api.py -v # -v显示详细日志
2. 断言(assert)的使用
- 常用断言:
assert response.status_code == 200 # 状态码断言 assert "success" in response.json() # JSON数据包含关键词 assert response.json()["code"] == 0 # 验证JSON字段值
3. fixtures:处理测试前置/后置条件
-
作用:复用测试前置逻辑(如登录获取Token、连接数据库),避免代码重复。
-
示例:登录fixture
import pytest import requests @pytest.fixture def login(): # 前置:登录获取Token url = "https://api.example.com/login" data = {"username": "test", "password": "123456"} response = requests.post(url, json=data) token = response.json()["token"] yield token # 返回Token供测试用例使用 # 后置:可选清理操作(如登出) # requests.post("https://api.example.com/logout")
-
在测试用例中使用fixture:
def test_get_user_info(login): # 使用fixture返回的token headers = {"Authorization": f"Bearer {login}"} response = requests.get("https://api.example.com/user/info", headers=headers) assert response.status_code == 200 assert response.json()["username"] == "test"
-
fixture作用域:
@pytest.fixture(scope="module") # module作用域:整个模块只执行一次
scope
可选值:function
(默认,每个测试用例执行一次)、class
、module
、session
。
4. 参数化测试:@pytest.mark.parametrize
- 作用:用不同参数运行同一测试用例,覆盖多种场景。
- 示例:测试登录接口的不同参数
import pytest @pytest.mark.parametrize("username, password, expected_code", [ ("valid_user", "valid_pwd", 200), # 正常场景 ("", "valid_pwd", 400), # 用户名为空 ("valid_user", "", 400), # 密码为空 ]) def test_login_parametrized(username, password, expected_code): url = "https://api.example.com/login" data = {"username": username, "password": password} response = requests.post(url, json=data) assert response.status_code == expected_code
五、接口自动化实战:模拟电商平台
1. 项目需求
测试一个简化的电商接口,包含:
- 登录接口(POST
/login
,返回Token)。 - 获取用户信息接口(GET
/user/info
,需Token认证)。 - 创建订单接口(POST
/order/create
,需Token和订单参数)。
2. 项目结构设计
project/
├── config/ # 配置文件
│ └── settings.py # 存储URL、环境变量等
├── utils/ # 工具类
│ └── request_utils.py # 封装请求方法
├── test_cases/ # 测试用例
│ ├── conftest.py # 存储fixtures(全局可用)
│ └── test_order.py # 具体测试文件
├── reports/ # 测试报告
└── requirements.txt # 依赖清单
3. 代码实现
3.1 配置文件:config/settings.py
BASE_URL = "https://api.example.com" # 基础URL
TEST_ACCOUNT = {
"username": "test_user",
"password": "test_pwd"
}
3.2 工具类:utils/request_utils.py
import requests
from config.settings import BASE_URL
class RequestUtils:
@staticmethod
def send_request(method, url, headers=None, json=None):
"""封装通用请求方法"""
full_url = f"{BASE_URL}{url}"
response = requests.request(
method=method,
url=full_url,
headers=headers,
json=json
)
response.raise_for_status() # 自动抛出4xx/5xx错误
return response
3.3 fixtures:test_cases/conftest.py
import pytest
from utils.request_utils import RequestUtils
from config.settings import TEST_ACCOUNT
@pytest.fixture(scope="session")
def login_token():
"""全局登录fixture,获取Token"""
url = "/login"
data = TEST_ACCOUNT
response = RequestUtils.send_request("POST", url, json=data)
return response.json()["token"]
3.4 测试用例:test_cases/test_order.py
import pytest
from utils.request_utils import RequestUtils
def test_get_user_info(login_token):
"""测试获取用户信息接口"""
url = "/user/info"
headers = {"Authorization": f"Bearer {login_token}"}
response = RequestUtils.send_request("GET", url, headers=headers)
assert response.json()["username"] == TEST_ACCOUNT["username"]
@pytest.mark.parametrize("product_id, quantity, expected_price", [
(1, 2, 200), # 正常购买2件商品
(2, 1, 150), # 购买单个商品
])
def test_create_order(login_token, product_id, quantity, expected_price):
"""测试创建订单接口"""
url = "/order/create"
headers = {"Authorization": f"Bearer {login_token}"}
data = {
"product_id": product_id,
"quantity": quantity
}
response = RequestUtils.send_request("POST", url, headers=headers, json=data)
assert response.json()["total_price"] == expected_price
assert response.json()["status"] == "pending"
六、生成测试报告:Allure集成
1. 安装Allure
pip install allure-pytest # pytest插件
# 下载Allure命令行工具:https://github.com/allure-framework/allure2/releases
# 配置环境变量:将allure可执行文件路径添加到PATH
2. 运行测试并生成报告
pytest test_cases/ -v --alluredir=reports/temp # 生成原始报告数据
allure generate reports/temp -o reports/html --clean # 生成HTML报告
allure open reports/html # 打开报告(自动弹出浏览器)
七、持续集成(CI):自动运行测试
1. 使用GitHub Actions
在项目根目录创建.github/workflows/ci.yml
:
name: Run Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.10
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run pytest
run: |
pytest test_cases/ --alluredir=reports/temp
- name: Generate Allure report
uses: allure-framework/allure-action@v2
with:
report-path: reports/temp
每次代码推送至GitHub时,自动运行测试并生成报告。
八、常见问题与最佳实践
1. 常见问题
- 路径错误:使用绝对路径或
sys.path
添加项目根目录。 - 断言失败:打印响应内容调试(
print(response.text)
)。 - 接口依赖:通过fixture传递状态(如Token),避免测试用例强耦合。
2. 最佳实践
- 分层设计:分离配置、工具、测试用例,提高可维护性。
- 日志记录:使用
logging
模块记录请求和响应详情,方便排查问题。 - 异常处理:在工具类中捕获请求异常,避免测试用例冗余代码。
- 版本控制:用
requirements.txt
锁定依赖版本(pip freeze > requirements.txt
)。
九、进阶学习资源
- 官方文档:
- 书籍:《Python测试实战》《pytest实战》。
- 项目实战:参与开源项目测试模块,或模拟电商、OA系统接口。
总结
通过以上步骤,你已掌握从环境搭建到项目落地的全流程。关键在于:
- 多练习:从简单接口开始,逐步挑战复杂场景(如文件上传、分页查询)。
- 读源码:学习pytest和requests的源码,理解底层逻辑。
- 跟社区:关注pytest官方博客和技术论坛(SegmentFault、Stack Overflow)。
坚持每周完成一个小项目,3个月内可具备独立开展接口自动化测试的能力!