1.@pytest.mark.xfail()

这个测试用例预期是会失败的(expected to fail)

  • 如果它真的失败了:pytest 报告为 XFAIL(预期失败),不算真正的错误。

  • 如果它反而成功了:pytest 报告为 XPASS(意外成功),提醒你代码逻辑可能已经修复,但测试标记没更新。

import pytest

@pytest.mark.xfail(reason="功能还没实现")
def test_future_feature():
    assert 1 == 2

执行时会显示为 XFAIL,而不是 ERROR/FAIL。

也可以在 pytest.ini 配置文件 标注:

[pytest]

xfail_strict=true

1.1实际场景

  • 某功能还没开发好,测试先写,但标记为 xfail

  • 某些平台/环境下有已知 bug,等修复后去掉 xfail

  • 需要提醒团队:“这个地方还没准备好,失败是正常的”。

2.pytest.xfail()

@pytest.mark.xfail装饰器形式,而 pytest.xfail()函数调用形式,它可以在测试运行过程中动态地标记某个测试为「预期失败」。

import pytest

def test_runtime_xfail():
    if True:  # 某些条件
        pytest.xfail("暂时还没修复的 bug")
    assert 1 == 2
  • pytest 在运行时执行到 pytest.xfail() 就会立刻把这个测试标记为 XFAIL,后续断言不会导致 FAIL。

  • 报告里会显示 XFAIL (reason: 暂时还没修复的 bug)

2.1 使用场景

条件复杂,不能在装饰器里提前写清楚
比如依赖运行时数据、外部环境,或者需要先运行一段逻辑才能决定。

def test_need_network():
    if not has_internet():
        pytest.xfail("网络不可用,预期失败")
    assert fetch_data() == "hello"
def test_dynamic():
    value = get_runtime_value()
    if value is None:
        pytest.xfail("运行时环境不满足条件,预期失败")
    assert value > 0

3.总结

  • @pytest.mark.xfail → 静态(编写测试时就能确定条件)。

  • pytest.xfail("reason") → 动态(运行时才能判断)。