pytest标记的具体使用
作者:花花无缺
pytest的标记是一个非常强大和灵活的功能,允许你为测试用例“打标签”,从而实现分类、控制执行、修改行为等目的,下面就来详细的介绍一下,感兴趣的可以了解一下
标记通常搭配装饰器使用
pytest
的标记(Markers) 是一个非常强大和灵活的功能,允许你为测试用例“打标签”,从而实现分类、控制执行、修改行为等目的。- 可以使用
@pytest.mark.标记名
来装饰测试函数或测试类。
1、内置标记(Built-in Marks)
pytest
提供了一些开箱即用的内置标记:
标记 | 作用 | 示例 |
---|---|---|
@pytest.mark.skip(reason="...") | 无条件跳过该测试。 | @pytest.mark.skip(reason="临时禁用") |
@pytest.mark.skipif(condition, reason="...") | 条件跳过测试。 | @pytest.mark.skipif(sys.version_info < (3,8), reason="需要 Python 3.8+") |
@pytest.mark.xfail(reason="...") | 预期该测试会失败。如果失败,结果为 XFAIL;如果意外通过,结果为 XPASS。 | @pytest.mark.xfail(reason="已知缺陷") |
@pytest.mark.parametrize | 参数化测试,用不同数据多次运行同一测试。 | 见下文示例 |
@pytest.mark.usefixtures('fixture_name') | 在测试中使用 fixture,但不将其作为参数传入。 | @pytest.mark.usefixtures("db_cleaner") |
@pytest.mark.filterwarnings | 为测试函数添加警告过滤器。 | @pytest.mark.filterwarnings("ignore::DeprecationWarning") |
@pytest.mark.parametrize详解
这是最常用的标记之一,用于数据驱动测试。数据驱动测试 = 参数化测试+数据文件
基本语法
@pytest.mark.parametrize("参数名", [值1, 值2, ...]) def test_function(参数名): ...
示例
import pytest # 测试平方函数 @pytest.mark.parametrize("input,expected", [ (2, 4), (3, 9), (-2, 4), (0, 0), ]) def test_square(input, expected): assert input ** 2 == expected # 测试不同浏览器(字符串参数) @pytest.mark.parametrize("browser", ["chrome", "firefox", "safari"]) def test_login(browser): print(f"Testing login with {browser}") # 启动对应浏览器并测试登录 -- 运行结果会显示为多个独立的测试用例: test_square[2-4] PASSED test_square[3-9] PASSED test_square[-2-4] PASSED test_login[chrome] PASSED test_login[firefox] PASSED
2、自定义标记(Custom Marks)
可以创建自己的标记来分类测试,如 smoke
, integration
, e2e
, slow
等。
2.1 在配置文件中声明自定义标记
如果不声明,pytest
会发出警告(PytestUnknownMarkWarning
)。
在 pyproject.toml
中声明:
[tool.pytest.ini_options] markers = [ "smoke: 快速冒烟测试", "integration: 集成测试", "e2e: 端到端测试", "slow: 运行时间较长的测试", "db: 涉及数据库操作", "performance: 性能测试" ]
或在 pytest.ini
中:
[tool:pytest] markers = smoke: 快速冒烟测试 integration: 集成测试 slow: 运行时间较长的测试
2.2 使用自定义标记
import pytest @pytest.mark.smoke def test_login(): assert True @pytest.mark.integration @pytest.mark.db class TestUserAPI: def test_create_user(self): assert True @pytest.mark.performance def test_user_list_speed(self): assert True
2.3 使用标记来控制测试执行
标记的强大之处在于你可以选择性地运行或跳过测试。
命令 | 作用 |
---|---|
pytest -m "smoke" | 只运行标记为 smoke 的测试。 |
pytest -m "not smoke" | 运行未标记为 smoke 的测试。 |
pytest -m "integration and db" | 运行同时标记为 integration 和 db 的测试。 |
pytest -m "smoke or integration" | 运行标记为 smoke 或 integration 的测试。 |
pytest -m "not slow" | 跳过所有标记为 slow 的测试(常用于CI快速反馈)。 |
3、内置标记和自定义标记的区别
对比维度 | 内置标记 (Built-in Marks) | 自定义标记 (Custom Marks) |
---|---|---|
来源 | pytest 框架自带的功能。 | 由用户自己定义的标签。 |
功能 | 具有特定行为逻辑(如跳过、预期失败、参数化)。 | 默认无行为,仅用于分类和标记,行为由执行命令控制。 |
是否需要声明 | ❌ 不需要在配置文件中声明。 | ✅ 必须在 pyproject.toml 或 pytest.ini 中声明,否则会警告。 |
用途 | 控制测试的执行行为。 | 对测试进行分类、分组,便于选择性执行。 |
示例 | @pytest.mark.skip, @pytest.mark.parametrize | @pytest.mark.smoke, @pytest.mark.e2e |
4、类标记
- 类上的标记会应用到类中所有的测试方法。
- 可以在方法上添加额外的标记。
@pytest.mark.db class TestDatabase: def test_read(self): # 有 db 标记 pass @pytest.mark.write def test_write(self): # 有 db 和 write 两个标记 pass @pytest.mark.skip def test_delete(self): # 有 db 标记,但会被跳过 pass
5、查看所有已注册的标记
pytest --markers
输出示例:
@pytest.mark.smoke - 快速冒烟测试 @pytest.mark.integration - 集成测试 @pytest.mark.slow - 运行时间较长的测试 @pytest.mark.skip - skip this test unconditionally @pytest.mark.skipif - skip the given test if condition is True ...
6、实践
- 为自定义标记在配置文件中声明,避免警告。
- 使用有意义的标记名,如
smoke
,e2e
,ui
,api
。 - 结合 CI/CD 使用:例如,在快速流水线中只运行
smoke
测试,在完整流水线中运行所有测试。 - 避免过度标记:标记太多会增加管理成本。
- 利用
parametrize
+mark
:可以为参数化测试的特定数据点打标记。
总结
pytest
的标记系统是其灵活性和可扩展性的核心之一。通过标记,可以:
- 组织和分类测试用例。
- 控制执行流程(跳过、预期失败)。
- 实现参数化测试。
- 集成到自动化流程中(如只运行冒烟测试)。
到此这篇关于pytest标记的具体使用的文章就介绍到这了,更多相关pytest标记内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!