跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

Python pytest 自动化测试框架入门指南

pytest 是一个流行的 Python 测试框架,支持函数式和面向对象风格。 pytest 的优点、安装方法、用例运行规则及命令参数。内容涵盖配置文件编写、前后置操作(fixture)、断言方式以及参数化测试实现。通过 pytest 可简化测试用例编写,提升自动化测试效率,适用于 Web、接口及 App 自动化场景。

活在当下发布于 2026/3/30更新于 2026/5/2226 浏览
Python pytest 自动化测试框架入门指南

一、pytest 介绍

pytest 是一个非常流行且高效的 Python 测试框架,提供丰富功能和灵活用法,让测试用例的编写与运行变得简单高效。

官方文档地址:https://docs.pytest.org/en/stable/getting-started.html

1.1 pytest 的优点
  • 简单易用:语法简洁清晰,对编写测试用例非常友好,上手速度快;
  • 强大的断言库:内置丰富断言库,可轻松判断测试结果;
  • 支持参数化测试:允许用不同参数多次运行同一个测试函数,大幅提升测试效率;
  • 丰富的插件生态系统:可通过插件扩展多种功能(如覆盖率测试、测试报告生成、失败用例重复执行等),还支持与 selenium、requests、appium 等结合,实现 Web 自动化、接口自动化、App 自动化测试;
  • 灵活的测试控制:允许跳过指定用例,或标记预期失败的用例,支持重复执行失败用例。
1.2 主流 Python 接口自动化框架对比
维度unittest(Python 内置)pytestRobot Framework
安装方式无需安装(Python 标准库)pip install pytestpip install robotframework
语法风格基于类(需继承 TestCase)函数式或面向对象(无需样板代码)关键字驱动(表格化用例)
断言方法self.assertEqual() 等原生 assert 表达式关键字断言(如 Should Be Equal)
参数化支持需 subTest 或第三方库内置(@pytest.mark.parametrize)数据驱动(Test Template)
插件生态少(依赖扩展库如 HTMLTestRunner)丰富(如 pytest-html、pytest-xdist、allure-pytest 等)一般(需安装额外库如 RequestsLibrary)
测试报告需插件生成报告支持多格式报告(HTML、Allure 等)自带详细日志和报告
学习曲线中等(需熟悉 xUnit 模式)低(语法简洁)高(需掌握关键字和语法)
BDD 支持不支持支持(通过 pytest-bdd 插件)支持(通过 robotframework-bdd)
适用场景简单项目或遗留系统维护复杂项目、高扩展性需求团队协作、非技术人员参与

二、安装

安装命令:

pip install pytest 

安装成功验证:

安装完成后,可通过 pip list 命令查看当前项目下 pytest 包是否安装成功。同时需确认 PyCharm 中 Python 解释器已更新,安装 pytest 前后的代码运行差异如下:

  • 未安装 pytest:需编写 main 函数手动调用测试用例;
  • 安装 pytest:测试方法名前会出现直接运行标志,无需手动编写调用代码。

三、用例运行规则

要让 pytest 自动发现并运行测试用例,需遵循以下命名规则:

  1. 文件名必须以 test_开头或者 _test结尾;
  2. 测试类必须以 Test开头,并且不能有 __init__ 方法;
  3. 测试方法必须以 test开头。

运行示例:

满足规则后,可通过命令行执行 pytest 命令直接运行符合条件的用例。

注意事项: Python 测试类中不可添加 __init__ 方法,否则 pytest 会抛出 pytest_collectionWarning 警告,无法收集该测试类。原因是 pytest 采用自动发现机制收集测试用例,会自动实例化测试类并调用其 test 开头的方法,若存在 __init__ 方法,可能掩盖测试逻辑并引入额外副作用,影响测试结果准确性。

若测试类需初始化操作,可使用 setUp() 和 tearDown() 方法、类属性或 fixture 函数替代。

四、pytest 命令参数

4.1 常见参数

pytest 提供丰富的命令行选项控制测试执行,常用参数及说明如下:

命令描述备注
pytest在当前目录及其子目录中搜索并运行测试-
pytest -v增加输出的详细程度-
pytest -s显示测试中的 print 语句-
pytest test_module.py运行指定的测试模块-
pytest test_dir/运行指定目录下的所有测试-
pytest -k只运行测试名包含指定关键字的测试-
pytest -m只运行标记为指定标记的测试-
pytest -q减少输出的详细程度-
pytest --html=report.html生成 HTML 格式的测试报告需要安装 pytest-html 插件
pytest --cov测量测试覆盖率需要安装 pytest-cov 插件
4.2 命令使用示例

指定文件/测试用例运行:

详细打印并显示 print 内容(-s 和 -v 可连写为 -sv):

运行符合规则的用例(不显示 print 内容):

五、pytest 配置文件

当需要频繁使用复杂命令参数时,可将配置统一写入 pytest.ini 文件(项目根目录下创建),避免重复输入。

5.1 常见配置选项
参数解释
addopts指定在命令行中默认包含的选项
testpaths指定搜索测试的目录
python_files指定发现测试模块时使用的文件匹配模式
python_classes指定发现测试类时使用的类名前缀或模式
python_functions指定发现测试函数和方法时使用的函数名前缀或模式
norecursedirs指定在搜索测试时应该避免递归进入的目录模式
markers定义测试标记,用于标记测试用例
5.2 配置示例

配置 pytest.ini 文件,实现详细输出 cases 包下文件名以 test_开头、类名以 Test开头的所有用例:

[pytest]
addopts = -vs
testpaths = cases
python_files = test03.py

配置完成后,命令行直接执行 pytest 命令即可,无需额外指定参数。

六、前后置操作

前后置操作用于在测试用例执行前后完成环境设置、数据准备、资源清理等工作,pytest 提供三种实现方式:

6.1 setup_method 和 teardown_method

用于类中每个测试方法的前置和后置操作,每个测试方法执行前都会触发 setup_method,执行后触发 teardown_method。

示例代码:

import pytest

class TestExample:
    def setup_method(self):
        print("Setup: Before each test")

    def teardown_method(self):
        print("Teardown: After each test")

    def test_example1(self):
        print("Running test_example1")

    def test_example2(self):
        print("Running test_example2")
6.2 setup_class 和 teardown_class

用于整个测试类的前置和后置操作,测试类中所有方法执行前触发一次 setup_class,所有方法执行后触发一次 teardown_class。

示例代码:

class TestExample:
    def setup_class(cls):
        print("Setup: Before all test")

    def teardown_class(cls):
        print("Teardown: After all test")

    def test_example1(self):
        print("Running test_example1")

    def test_example2(self):
        print("Running test_example2")

七、断言

断言(assert)是一种调试辅助工具,用于检查程序状态是否符合预期,若断言失败(条件为假),Python 解释器会抛出 AssertionError 异常。pytest 支持使用标准 Python assert 语句验证预期值与实际值。

基本语法:

assert 条件,错误信息
  • 条件:必须是布尔表达式;
  • 错误信息:条件为假时显示的提示信息(可选)。

断言示例:

7.1 基本数据类型断言:
# 断言整数
a = 1
b = 2
assert a == b, "a 和 b 不相等"

# 断言字符串
str_val = "hello"
assert "hello" == str_val
7.2 数据结构断言:
def test():
    # 断言列表
    expect_list = [1, 'apple', 3.14]
    actual_list = [1, 'apple', 3.14]
    # 断言元组
    expect_tuple = (1, 'apple', 3.14)
    actual_tuple = (1, 'apple', 3.14)
    # 断言字典
    expect_dict = {'name': 'Alice', 'age': 25}
    actual_dict = {'name': 'Alice', 'age': 25}
    # 断言集合
    expect_set = {1, 2, 3, 'apple'}
    actual_set = {1, 2, 3, 'apple'}
    assert expect_list == actual_list
    assert expect_tuple == actual_tuple
    assert expect_dict == actual_dict
    assert expect_set == actual_set
7.3 函数断言:
def divide(a, b):
    assert b != 0, "除数不能为 0"
    return a / b

# 正常情况
print(divide(10, 2))  # 输出 5.0

# 触发断言
print(divide(10, 0))  # 抛出 AssertionError: 除数不能为 0
7.4 接口返回值断言:
import requests
from jsonschema.validators import validate

# 断言接口返回值完整字段和值
def test1():
    url = "http://jsonplaceholder.typicode.com/posts/1"
    r = requests.get(url=url)
    expect_data = {
        "userId": 1,
        "id": 1,
        "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    }
    print(r.json())
    assert r.json() == expect_data
    assert r.json()['userId'] == 1

# 断言接口返回值重要字段
def test2():
    url = "http://jsonplaceholder.typicode.com/comments?postId=1"
    r = requests.get(url=url)
    print(r.json())
    assert r.json()[1]['id'] == 1

# 断言接口 HTML 返回值
def test3():
    url = "http://jsonplaceholder.typicode.com/"
    r = requests.get(url=url)
    assert "Use your own data" in r.text

八、参数化

参数化设计可让测试用例通过不同参数多次运行,提高测试效率和覆盖度,pytest 通过 @pytest.mark.parametrize 装饰器实现参数化,支持在测试函数、类、模块级别使用。

8.1 测试函数参数化

示例代码:

import pytest

@pytest.mark.parametrize("test_input, expected", [
    ("3+5", 8),
    ("2+4", 6),
    ("6*9", 42)
])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

装饰器定义了三组 (test_input, expected) 元组,test_eval 函数会依次使用每组参数运行三次。

8.2 测试类参数化

示例代码:

import pytest

@pytest.mark.parametrize("n, expected", [(1, 2), (3, 4)])
class TestClass:
    def test_simple_case(self, n, expected):
        assert n + 1 == expected

    def test_weird_simple_case(self, n, expected):
        assert (n * 1) + 1 == expected

参数集将作用于类中所有测试方法,每个方法都会使用每组参数运行。

8.3 模块级别参数化

通过给 pytestmark 全局变量赋值,实现模块内所有测试的参数化:

import pytest

pytestmark = pytest.mark.parametrize("n, expected", [(1, 2), (3, 4)])

class TestClass:
    def test_simple_case(self, n, expected):
        assert n + 1 == expected

    def test_weird_simple_case(self, n, expected):
        assert (n * 1) + 1 == expected
8.4 自定义参数化数据源

示例代码:

def data_provider():
    return ["a", "b"]

# 定义测试函数,依赖自定义数据源
@pytest.mark.parametrize("data", data_provider())
def test_data(data):
    assert data is not None
    print(f"Testing with data provider: {data}")

除了使用 @parametrize 添加参数外,pytest.fixture() 允许对 fixture 函数进行参数化。

目录

  1. 一、pytest 介绍
  2. 1.1 pytest 的优点
  3. 1.2 主流 Python 接口自动化框架对比
  4. 二、安装
  5. 三、用例运行规则
  6. 四、pytest 命令参数
  7. 4.1 常见参数
  8. 4.2 命令使用示例
  9. 五、pytest 配置文件
  10. 5.1 常见配置选项
  11. 5.2 配置示例
  12. 六、前后置操作
  13. 6.1 setupmethod 和 teardownmethod
  14. 6.2 setupclass 和 teardownclass
  15. 七、断言
  16. 7.1 基本数据类型断言:
  17. 断言整数
  18. 断言字符串
  19. 7.2 数据结构断言:
  20. 7.3 函数断言:
  21. 正常情况
  22. 触发断言
  23. 7.4 接口返回值断言:
  24. 断言接口返回值完整字段和值
  25. 断言接口返回值重要字段
  26. 断言接口 HTML 返回值
  27. 八、参数化
  28. 8.1 测试函数参数化
  29. 8.2 测试类参数化
  30. 8.3 模块级别参数化
  31. 8.4 自定义参数化数据源
  32. 定义测试函数,依赖自定义数据源
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 自然语言处理在医疗健康领域的应用与实战
  • Django REST Framework 企业级 API 架构实战
  • Copilot Cowork 核心逻辑解析:基于 Kotlin 构建 AI Agent
  • Vue Router 实战:子路由与动态路径参数
  • 七款主流大模型英文降重能力横向测评
  • 基于 Rust+Tauri 构建 OpenClaw 安全沙箱清理技能实战
  • Reasoning Models Generate Societies of Thought 论文解读
  • 纯前端开源 PDF 压缩工具:Vue3+TypeScript 实现方案
  • 利用快马平台ai快速构建imtoken钱包交互原型,验证核心交易流程
  • OpenClaw 部署实战:本地 AI 数字员工搭建与安全配置
  • YOLO12 WebUI 体验:拖拽图片即可完成目标检测
  • AI 写作实战:自动写作助手的设计与实现
  • AI Coding 入门指南:工具选择与实战技巧
  • Stable Diffusion WebUI Forge 模型评估实战指南:三大核心指标解析
  • 从 Java 8 升级到 Java 21:核心新特性对比与实战指南
  • C++11 新特性:可变参数模板、类功能、STL 变化与包装器
  • 数据结构详解:堆的实现与应用
  • 前端实战:拦截右键菜单并实现自定义弹窗逻辑
  • Kotlin 实现 WebView 动态注入 JS 修改 iframe 样式
  • Python 核心语法实战:变量、流程控制与函数详解

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online