You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨文件参数化场景下pytest_dependency依赖失效问题排查

pytest_dependency跨文件参数化依赖失效问题

问题现象

使用pytest_dependency时,仅满足以下任一条件依赖功能正常:

  • 参数化测试依赖同一文件内的参数化测试
  • 非参数化测试依赖不同文件的测试

但参数化测试依赖不同文件的参数化测试时,依赖功能完全失效:即便前置测试执行成功,关联的所有测试用例(如test_c)仍会被全部跳过。

目录结构

tests/
  - common.py
  - test_0.py
  - test_1.py

代码文件

common.py

import numpy as np

ints = [1, 2, 3]
strs = ['a', 'b']
pars = list(zip(np.repeat(ints, 2), np.tile(strs, 3)))

test_0.py

import numpy as np
import pytest
from pytest_dependency import depends

from common import pars

def idfr0(val):
    if isinstance(val, (int, np.int32, np.int64)):
        return f"n{val}"

def idfr1(val):
    return "n{}-{}".format(*val)

# 批量参数化标记
perm_mk = pytest.mark.parametrize('num, lbl', pars, ids=idfr0)

# 6次执行中2次失败
@perm_mk
@pytest.mark.dependency(scope="session")
def test_a(num, lbl):
    if num == 2:
        assert False
    else:
        assert True

# 依赖参数化fixture,参考官方文档实现
@pytest.fixture(params=pars, ids=idfr1)
def perm_fixt(request):
    return request.param

@pytest.fixture()
def dep_perms(request, perm_fixt):
    depends(request, ["test_a[n{}-{}".format(*perm_fixt)])
    return perm_fixt

# 本文件内的参数化依赖,功能正常
@pytest.mark.dependency(scope="session")
def test_b(dep_perms):
    pass

# 非参数化独立测试
@pytest.mark.dependency(scope="session")
def test_1():
    pass

@pytest.mark.xfail()
@pytest.mark.dependency(scope="session")
def test_2():
    assert False

test_1.py

import pytest
from pytest_dependency import depends

from common import pars

def idfr2(val):
    return "n{}-{}".format(*val)

@pytest.fixture(params=pars, ids=idfr2)
def perm_fixt(request):
    return request.param

@pytest.fixture()
def dep_perms(request, perm_fixt):
    depends(request, ["test_0.py::test_a[n{}-{}".format(*perm_fixt)])
    return perm_fixt

# 跨文件参数化依赖,功能失效
@pytest.mark.dependency(scope="session")
def test_c(dep_perms):
    num, lbl = dep_perms
    assert True

# 跨文件非参数化依赖,功能正常
@pytest.mark.dependency(scope="session", depends=["test_0.py::test_1"])
def test_3():
    pass

@pytest.mark.dependency(scope="session", depends=["test_0.py::test_2"])
def test_4():
    pass

执行与结果

执行命令

pytest --tb=no -rpfxs ./test_0.py ./test_1.py

预期结果

  • test_a:6次参数化执行,4次通过、2次失败
  • test_b:4次通过、2次跳过
  • test_c:4次通过、2次跳过
  • test_1:通过;test_2:标记xfail;test_3:通过;test_4:被跳过

实际结果

除test_c全部被跳过外,其余均符合预期。即使输出明确显示test_0.py::test_a[n1-a]已通过,test_c[n1-a]仍因依赖该测试被跳过。

问题原因与修复

核心原因

pytest_dependency匹配跨文件参数化测试时,依赖名称必须严格对应测试节点的完整ID。你在test_1.py中构造的依赖名称是test_0.py::test_a[n{}-{}],但test_a的参数化ID是由test_0.py中的idfr0生成的——每个参数对应的ID是n1、n1、n2、n2、n3、n3,而非n1-a这类包含标签的格式。

错误的依赖名称导致pytest_dependency无法找到对应的前置测试节点,因此判定依赖未满足,直接跳过了所有test_c用例。

修复方案

修改test_1.py中dep_perms fixture的依赖名称构造逻辑,匹配test_a的参数化ID格式:

@pytest.fixture()
def dep_perms(request, perm_fixt):
    num, lbl = perm_fixt
    # 使用test_a对应的ID生成规则
    depends(request, [f"test_0.py::test_a[n{num}]"])
    return perm_fixt

修改后,test_c就能正确匹配test_a的对应参数化用例,依赖功能恢复正常,符合预期结果。


内容的提问来源于stack exchange,提问作者Ajean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:14:53