1. Pytest 框架基础
定义 :Python 第三方的单元测试框架,用于编写和管理自动化测试脚本。
核心特点:
- 自动发现并执行测试用例。
- 提供简单灵活的断言机制 (
assert)。 - 支持参数化测试。
- 丰富的插件生态(如生成 Allure 报告)。
🚀 快速上手
- 安装 :
pip install pytest - 用例规则 (必须遵守):
- 文件 :以
test_开头或_test.py结尾(如test_add.py)。 - 类 :以
Test开头(如class TestAdd),且不能包含__init__方法。 - 方法 :以
test_开头(如def test01_add)。
- 文件 :以
- 执行方式 :
-
命令行 (推荐):
pytest -s 测试文件.py(-s用于打印 console 输出)。 -
代码执行 :
if __name__ == '__main__': pytest.main(["-s", "test_add.py"])
-
⚙️ 配置文件 (pytest.ini)
在项目根目录创建 pytest.ini,统一管理执行策略:
[pytest]
addopts = -s --alluredir report # 默认参数:显示print输出,生成报告到report目录
testpaths = ./scripts # 测试用例搜索路径
python_files = test*.py # 匹配的文件名
python_classes = Test* # 匹配的类名
python_functions = test* # 匹配的方法名
2. 断言 (Assertions)
作用 :替代人工判断,验证"实际结果"与"预期结果"是否一致。
语法 :直接使用 Python 原生的 assert 关键字。
| 场景 | 代码示例 | 说明 |
|---|---|---|
| 相等 | assert actual == expected |
最常用,左边实际,右边预期 |
| 不相等 | assert a != b |
验证两者不同 |
| 包含 | assert "sub" in "string" |
验证子串是否存在 |
| 不包含 | assert "x" not in "list" |
验证元素是否不存在 |
| 为真 | assert value |
等价于 value == True |
| 为假 | assert not value |
等价于 value == False |
💡 最佳实践:一个测试方法中可以写多个断言,只要有一个失败,该用例即标记为失败。
3. 前后置操作 (Setup & Teardown)
作用:在测试执行前进行环境初始化(如打开浏览器、连接数据库),执行后进行资源清理(如关闭浏览器、删除数据)。
Pytest 支持两种粒度的控制:
A. 方法级别 (Method Level)
触发时机 :每个 测试方法执行前后各运行一次。
适用场景:每个用例都需要独立的环境(如每条用例都需重新登录)。
class TestDemo:
def setup_method(self): # 或者简写为 setup
print("【前置】每个用例前执行:打开页面/初始化数据")
def teardown_method(self): # 或者简写为 teardown
print("【后置】每个用例后执行:清理数据/截图")
def test_case_1(self):
pass
def test_case_2(self):
pass
# 执行顺序:setup -> test1 -> teardown -> setup -> test2 -> teardown
B. 类级别 (Class Level)
触发时机 :整个类 的所有测试方法执行前运行一次,全部结束后再运行一次。
适用场景:耗时的初始化操作(如启动浏览器),所有用例可共用。
class TestDemo:
def setup_class(self):
print("【前置】类开始前执行一次:启动浏览器")
def teardown_class(self):
print("【后置】类结束后执行一次:关闭浏览器")
def test_case_1(self):
pass
def test_case_2(self):
pass
# 执行顺序:setup_class -> test1 -> test2 -> teardown_class
4. Fixture 机制 (高级前后置)
定义 :Pytest 特有的强大固定装置,用于替代传统的 setup/teardown,实现更灵活的前后置管理和资源共享。
核心文件 :通常配合 conftest.py 使用(自动被发现,无需导入)。
核心特性
-
作用域控制 (
scope):function(默认):每个函数/方法执行前后。class:每个类执行前后。module:每个.py文件执行前后。session:整个测试会话(所有文件)执行前后一次。
-
自动执行 (
autouse):- 设置
autouse=True后,无需在测试函数中传入 fixture 名称,会自动在对应作用域内执行。
- 设置
-
返回值传递:
- fixture 函数中的
return值可以直接作为参数传递给测试函数。
- fixture 函数中的
代码示例 (conftest.py)
import pytest
# 定义一个 fixture
@pytest.fixture(scope="class", autouse=True)
def browser_env():
print("\n--- [Fixture] 启动浏览器 (类级别,自动执行) ---")
driver = "Chrome Driver Instance" # 模拟对象
yield driver # yield 之前是前置,之后是后置
print("\n--- [Fixture] 关闭浏览器 ---")
# 测试文件 test_demo.py
class TestLogin:
# 即使不传参,因为 autouse=True,也会自动执行上面的 browser_env
def test_login_success(self, browser_env):
# 如果需要用到 fixture 的返回值,则在参数中声明
print(f"使用 {browser_env} 进行登录测试")
assert True
💡 Fixture vs Setup/Teardown
| 特性 | Setup/Teardown | Fixture |
|---|---|---|
| 灵活性 | 低,仅限当前类 | 高,可跨文件共享 (conftest.py) |
| 作用域 | 仅支持 方法级/类级 | 支持 function/class/module/session |
| 数据传递 | 不支持直接返回数据 | 支持通过 yield 或 return 传递数据给用例 |
| 复用性 | 差,代码易重复 | 强,一次定义多处调用 |
5. 测试报告 (Allure)
为了生成可视化的测试报告:
- 安装插件 :
pip install allure-pytest - 配置 pytest.ini :添加
--alluredir report参数。 - 执行测试 :运行
pytest生成原始数据到report文件夹。 - 查看报告 :
- 临时查看:
allure serve report - 生成静态文件:
allure generate report -o html_report --clean
- 临时查看:
静态文件
# 1.导包
import os
# 2.配置cmd下执行命令(生成allure执行命令)
run_cmd = "allure generate ./report -o ./new_report --clean"
# 通过os.system(命令)方法运行终端命令(相当于在终端运行上述命令)
os.system(run_cmd)
# allure generate :生成allure测试报告的命令
# ./report :allure :运行生成的临时报告文件路径
# -o ./new_report :输出HTML的报告到report路径下
# --clean :清除报告目录下原有的历史数据