在 Python 自动化测试领域,unittest、pytest、Robot Framework 是三大主流框架。其中 pytest 凭借语法简洁、插件生态丰富、扩展性强等优势,成为了 GUI 自动化测试的首选工具之一。本文将从基础概念出发,带你一步步掌握 pytest 的核心用法,并结合 GUI 自动化测试场景给出实践建议。
一、为什么选 pytest?三大主流框架横向对比
先通过一张表格,快速看清 pytest 和其他框架的差异,帮你理解它的优势所在:
表格
| 维度 | unittest(Python 内置) | pytest | Robot Framework |
|---|---|---|---|
| 安装方式 | 无需安装(Python 标准库) | pip install pytest |
pip 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) |
| 适用场景 | 简单项目或遗留系统维护 | 复杂项目、高扩展性需求 | 团队协作、非技术人员参与 |
pytest 最核心的优势,就是用最少的代码实现最强的功能:
- 不用写复杂的类继承,直接写函数就能跑测试;
- 原生支持
assert断言,不用记一堆专用方法; - 丰富的插件可以轻松扩展报告、并发执行、失败重跑等功能;
- 完美兼容 Selenium、Pywinauto、Appium 等 GUI 自动化工具,是 GUI 自动化的 "黄金搭档"。
二、pytest 快速安装与环境准备
1. 版本选择与安装
pytest 8.3.2 是目前稳定性和兼容性平衡得很好的版本,要求 Python 3.8 及以上。如果你的 Python 版本较低,可以参考下方的版本适配表:
| pytest 版本 | 最低 Python 版本 |
|---|---|
| 8.0+ | 3.8+ |
| 7.1+ | 3.7+ |
| 6.2 - 7.0 | 3.6+ |
| 5.0 - 6.1 | 3.5+ |
| 3.3 - 4.6 | 2.7, 3.4+ |
推荐直接安装和我一致的版本,避免兼容性问题:
python
pip install pytest==8.3.2
安装成功后,在终端输入pytest --version,能看到版本信息就说明安装完成了。

2. 第一个 pytest 测试用例
安装 pytest 前后,写测试代码的体验完全不同:
未安装 pytest 时(传统写法)
需要手动写main函数调用用例,代码冗余:
python
import requests
def test_baidu():
r = requests.get(url="https://www.baidu.com")
print(r.status_code)
if __name__ == "__main__":
test_baidu()
安装 pytest 后(简洁写法)
只要方法名符合规则,pytest 就能自动识别并运行,无需额外代码:

运行时直接在终端输入pytest,就能看到用例自动执行并输出结果。

三、pytest 核心规则:用例识别与命名规范
pytest 采用自动发现机制收集测试用例,必须遵循以下命名规则,否则用例会被忽略:
- 文件名:必须以test_开头或_test结尾(如test_login.py、login_test.py);
- 测试类:必须以Test开头,并且不能有__init__方法;
- 测试方法 / 函数:必须以test_开头。
⚠️ 重要提醒:测试类中不能定义__init__方法,否则 pytest 无法正确收集用例。因为 pytest 会自动实例化测试类并调用其中的test_开头的方法,__init__方法会干扰这个过程,甚至导致用例执行异常。
如果需要做初始化操作,推荐使用后面会讲到的setup_class、setup_method或fixture来实现。
四、pytest 常用命令行参数:灵活控制测试执行
pytest 提供了丰富的命令行选项,帮你精准控制测试的执行方式,以下是 GUI 自动化测试中最常用的几个:
表格
| 命令 | 描述 | 场景示例 |
|---|---|---|
pytest |
在当前目录及其子目录中搜索并运行所有符合规则的测试 | 快速执行项目中所有用例 |
pytest -v |
增加输出的详细程度,显示每个用例的执行结果 | 排查用例执行失败问题 |
pytest -s |
显示测试中的print语句,方便调试 GUI 自动化中的日志 |
查看 GUI 操作中的关键步骤输出 |
pytest test_module.py |
运行指定的测试模块文件 | 单独调试某个 GUI 功能的用例文件 |
pytest test_dir/ |
运行指定目录下的所有测试 | 执行某个模块的所有 GUI 自动化用例 |
pytest -k <keyword> |
只运行测试名包含指定关键字的测试 | 只执行所有login相关的 GUI 用例 |
pytest -m <marker> |
只运行标记为指定标记的测试 | 只执行标记为smoke的冒烟测试用例 |
pytest --html=report.html |
生成 HTML 格式的测试报告(需安装pytest-html插件) |
生成 GUI 自动化测试的结果报告 |
实用示例
-
详细打印并显示
print内容 :调试 GUI 自动化用例时,经常需要看print输出,直接用:pythonpytest -s -v # 也可以简写为 pytest -sv -
指定文件 / 用例执行 :调试单个 GUI 用例时,直接指定文件和方法:

# 指定文件 pytest cases/test_login.py # 指定测试类中的某个方法 pytest cases/test_login.py::TestLogin::test_login_success
五、pytest 配置文件:告别冗长命令
每次都敲一长串命令很麻烦,pytest 支持通过pytest.ini配置文件,把常用参数统一管理,放在项目根目录即可生效。
常用配置参数说明
| 参数 | 解释 |
|---|---|
addopts |
指定在命令行中默认包含的选项,比如-vs、--html=report.html |
testpaths |
指定搜索测试用例的目录,比如./cases |
python_files |
指定发现测试模块时的文件匹配模式,比如test_*.py |
python_classes |
指定发现测试类时的类名前缀,比如Test* |
python_functions |
指定发现测试函数时的函数名前缀,比如test_* |
markers |
自定义测试标记,用于分类执行用例 |
配置示例:GUI 自动化项目通用配置
python
[pytest]
addopts = -vs --html=./reports/report.html --self-contained-html
testpaths = ./cases
python_files = test_*.py
python_classes = Test*
python_functions = test_*
markers =
smoke: 冒烟测试用例
regression: 回归测试用例
配置完成后,直接在终端输入pytest,就会自动读取配置,执行./cases目录下所有符合规则的用例,同时生成带日志的 HTML 报告。

pytest.ini ⽂件通常位于项⽬的根⽬录下。通过在pytest.ini 中定义配置项,可以覆盖 pytest 的默认⾏为,以满⾜项⽬的需求。
六、前后置操作:优雅管理 GUI 自动化的测试环境
GUI 自动化测试中,每个用例都需要打开应用、初始化驱动
执行后还要关闭应用、清理环境
这就需要前后置操作。
pytest 提供了三种实现方式,分别适用于不同场景:
1. setup_method 和 teardown_method:每个测试方法前后执行
适合每个 GUI 用例都需要独立初始化环境的场景,比如每个用例都要重新打开应用:
python
class TestLogin:
def setup_method(self):
print("setup_method: 打开应用,初始化GUI驱动")
# 这里写打开应用、初始化驱动的代码
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def teardown_method(self):
print("teardown_method: 关闭应用,清理环境")
# 这里写关闭驱动、清理数据的代码
self.driver.quit()
def test_login_success(self):
print("执行登录成功用例")
# 这里写登录的GUI操作代码
def test_login_fail(self):
print("执行登录失败用例")
# 这里写登录失败的GUI操作代码
执行结果:每个test_开头的方法,都会先执行setup_method,
再执行用例,
最后执行teardown_method。
2. setup_class 和 teardown_class:整个测试类前后执行
适合同一个测试类中的多个用例共享同一个环境的场景,比如多个登录相关用例复用同一个浏览器实例:
python
class TestLogin:
def setup_class(self):
print("setup_class: 打开应用,初始化GUI驱动(整个类只执行一次)")
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def teardown_class(self):
print("teardown_class: 关闭应用,清理环境(整个类只执行一次)")
self.driver.quit()
def test_login_success(self):
print("执行登录成功用例")
def test_login_fail(self):
print("执行登录失败用例")
执行结果:setup_class在类中所有用例执行前执行一次,
teardown_class在所有用例执行后执行一次
3. fixture:pytest 推荐的灵活前后置方案
fixture 是 pytest 中最强大的前后置方案,支持作用域控制(函数、类、模块、会话级)、参数化、依赖注入等功能,是 GUI 自动化测试的首选方式,后续会专门写一篇文章详细讲解。
七、总结
pytest 凭借简洁的语法、丰富的插件生态和灵活的扩展性,成为了 Python GUI 自动化测试的最佳搭档。本文从框架对比、安装配置、核心规则、命令行参数、前后置操作、断言验证等方面,带你快速入门了 pytest 的核心用法,并结合 GUI 自动化场景给出了实践建议。
后续我们会深入讲解 pytest 的fixture、参数化、标记、Allure 报告等高级功能,帮你打造一套稳定、高效的 GUI 自动化测试框架。