pytest.mark
是 pytest 测试框架中用于标记测试函数或测试类的工具,通过它可以为测试添加额外的属性或行为,从而实现更灵活的测试管理和执行。以下是关于 pytest.mark
的详细说明,包括它的常用功能和使用方法。
1. pytest.mark
的基本概念
pytest.mark
是一个装饰器工厂,可以生成用于标记测试的装饰器。这些标记可以用于以下目的:
- 分类测试:根据功能、模块或优先级对测试进行分类。
- 控制测试执行:跳过某些测试、标记预期失败的测试或仅运行特定的测试。
- 参数化测试:为测试函数提供多组输入参数。
2. 内置的 pytest.mark
标记
2.1 skip
无条件跳过测试用例。
import pytest
@pytest.mark.skip(reason="此测试用例暂不执行")
def test_skip():
assert False
2.2 skipif
根据条件跳过测试用例。如果条件为 True
,则跳过测试。
import pytest
@pytest.mark.skipif(condition=2 > 1, reason="当 2 > 1 时跳过此测试用例")
def test_skip_if():
assert True
2.3 xfail
标记测试用例为预期失败。如果测试失败,不会导致整个测试套件失败;如果测试通过,则标记为 XPASS
。
import pytest
@pytest.mark.xfail(reason="已知此测试用例存在问题")
def test_xfail():
assert False
2.4 parametrize
对测试用例进行参数化,允许使用多组不同的参数来运行同一个测试函数。
import pytest
@pytest.mark.parametrize("a, b, expected", [
(1, 2, 3),
(4, 5, 9),
(0, 0, 0)
])
def test_add(a, b, expected):
assert a + b == expected
3. 自定义标记
除了内置的标记,pytest 还允许开发者定义自己的标记,用于分类和筛选测试。
3.1 定义自定义标记
在 pytest.ini
文件中定义自定义标记:
[pytest]markers =
smoke: 标记为冒烟测试
regression: 标记为回归测试
3.2 使用自定义标记
import pytest
@pytest.mark.smoke
def test_smoke():
assert True
@pytest.mark.regression
def test_regression():
assert True
3.3 运行特定标记的测试
使用 -m
参数运行带有特定标记的测试:
bash复制
pytest -m smoke *# 只运行标记为 smoke 的测试*
pytest -m "not smoke" *# 运行未标记为 smoke 的测试*
pytest -m "smoke or regression" *# 运行标记为 smoke 或 regression 的测试*
4. 组合标记
可以同时使用多个标记来标记一个测试用例。
import pytest
@pytest.mark.smoke
@pytest.mark.regression
def test_both():
assert True
5. 动态标记
可以在运行时动态添加标记,例如根据环境变量或配置文件动态跳过测试。
import pytest
import os
@pytest.mark.skipif(os.getenv("SKIP_SLOW_TESTS", "false").lower() == "true", reason="跳过慢测试")
def test_slow():
assert True
6. 使用 pytest.mark
的好处
- 灵活性:可以根据不同的需求对测试进行分类和筛选。
- 可维护性:通过标记清晰地表达测试的意图,便于团队理解和维护。
- 可扩展性:自定义标记可以根据项目需求灵活扩展。
7. 示例:完整的测试文件
以下是一个完整的测试文件示例,展示了如何使用 pytest.mark
的多种功能:
Python复制
import pytest
*# 自定义标记*
@pytest.mark.smoke
def test_smoke():
assert True
*# 参数化测试*
@pytest.mark.parametrize("a, b, expected", [
(1, 2, 3),
(4, 5, 9),
(0, 0, 0)
])
def test_add(a, b, expected):
assert a + b == expected
*# 跳过测试*
@pytest.mark.skip(reason="此测试用例暂不执行")
def test_skip():
assert False
*# 预期失败*
@pytest.mark.xfail(reason="已知此测试用例存在问题")
def test_xfail():
assert False
*# 动态跳过测试*
@pytest.mark.skipif(os.getenv("SKIP_SLOW_TESTS", "false").lower() == "true", reason="跳过慢测试")
def test_slow():
assert True
通过合理使用 pytest.mark
,可以显著提升测试的可管理性和灵活性,帮助团队更高效地进行测试开发和维护。