使用pytest-dependency与pytest-ordering时测试用例被跳过问题
pytest-dependency跨文件依赖测试用例被跳过问题
问题背景
在不同Python测试文件中集成pytest-dependency和pytest-ordering插件时,出现依赖测试用例被无故跳过的情况。即使将测试类合并到同一文件,或在依赖类中初始化前置测试类,问题依然存在。
测试代码
test_mod_01.py
import pytest from pages.Page1 import LaunchPage @pytest.mark.usefixtures("setup") class TestPage1: @pytest.mark.dependency() @pytest.mark.run(order=1) def test_page1(self): self.lp = LaunchPage(self.driver) self.lp.clickButton1()
test_mod_02.py
import pytest import softest from flaky import flaky from pages.Page2 import TalentPage from pages.Page3 import CVPage @pytest.mark.usefixtures("setup") class TestPage2_3(softest.TestCase): @flaky(max_runs=3, min_passes=2) @pytest.mark.dependency(depends=["testcases/test_mod_01.py::TestPage1::test_page1"], scope="session") @pytest.mark.run(order=2) def test_page2(self): self.tp = TalentPage(self.driver) self.tp.scroll_down() self.tp.clickButton2() self.tp.clickButton3() @flaky(max_runs=3, min_passes=2) @pytest.mark.dependency(depends=["TestPage2_3::test_BuildCV_page_2"], scope="session") @pytest.mark.run(order=3) def test_page3(self): self.cvp = CVPage(self.driver) self.cvp.clickButton4() self.cvp.clickButton5() self.cvp.clickButton6() self.cvp.clickButton7()
conftest.py
import pytest from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.edge.service import Service as EdgeService from webdriver_manager.microsoft import EdgeChromiumDriverManager from selenium.webdriver.firefox.service import Service as FirefoxService from webdriver_manager.firefox import GeckoDriverManager @pytest.fixture() def setup(request, browser): if browser == "chrome": options = webdriver.ChromeOptions() options.add_argument("--disable-notifications") driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) elif browser == "firefox": options = webdriver.FirefoxOptions() options.add_argument("--disable-notifications") driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()), options=options) elif browser == "edge": options = webdriver.EdgeOptions() options.add_argument("--disable-notifications") driver = webdriver.Edge(service=EdgeService(EdgeChromiumDriverManager().install()), options=options) driver.get("https://example.com/") driver.maximize_window() request.cls.driver = driver yield request.cls.driver request.cls.driver.quit() def pytest_addoption(parser): parser.addoption("--browser") @pytest.fixture(scope="session", autouse=True) def browser(request): return request.config.getoption("--browser")
错误信息
(venv) xxxx % pytest -v -s --browser chrome testcases =============================================================== test session starts =============================================================== platform darwin -- Python 3.11.4, pytest-7.4.3, pluggy-1.3.0 -- xxxx cachedir: .pytest_cache rootdir: xxxx plugins: flaky-3.7.0, dependency-0.5.1, ordering-0.6 collected 3 items testcases/test_mod_01.py::TestPage1::test_page1 PASSED testcases/test_mod_02.py::TestPage2_3::test_page2 SKIPPED (test_page2 depends on testcases/test_...) testcases/test_mod_02.py::TestPage2_3::test_page3 SKIPPED (test_page3 depends on TestP...) ========================================================== 1 passed, 2 skipped in 14.66s ==========================================================
问题分析
- 依赖名称未明确指定:
test_page1的@pytest.mark.dependency()未设置name参数,跨文件引用时pytest-dependency无法准确匹配依赖目标。 - 依赖目标名称错误:
test_page3的依赖写为test_BuildCV_page_2,但实际测试函数名是test_page2,名称不匹配导致依赖校验失败。 - Scope不匹配:
setupfixture的scope是默认的function,但依赖标记使用scope="session",不同scope下的测试状态无法被正确识别。 - 节点ID路径错误:
test_page2的依赖路径写为testcases/test_mod_01.py::TestPage1::test_page1,但执行命令时已指定testcases为测试目录,rootdir是项目根目录,节点ID不需要前缀testcases/。
修复方案
1. 明确指定依赖名称
给每个测试用例的dependency标记添加name参数,简化跨文件引用:
修改test_mod_01.py
@pytest.mark.dependency(name="test_page1") @pytest.mark.run(order=1) def test_page1(self): self.lp = LaunchPage(self.driver) self.lp.clickButton1()
修改test_mod_02.py
@flaky(max_runs=3, min_passes=2) @pytest.mark.dependency(name="test_page2", depends=["test_page1"], scope="class") @pytest.mark.run(order=2) def test_page2(self): # 原代码保留
@flaky(max_runs=3, min_passes=2) @pytest.mark.dependency(name="test_page3", depends=["test_page2"], scope="class") @pytest.mark.run(order=3) def test_page3(self): # 原代码保留
2. 调整Fixture Scope一致性
将setup fixture的scope改为class,确保每个测试类复用同一个driver实例,同时依赖标记的scope也设为class:
修改conftest.py
@pytest.fixture(scope="class") def setup(request, browser): # 原代码逻辑保留
3. 修正节点ID(可选)
如果不想用name参数,可直接使用正确的节点ID(去掉testcases/前缀):
@pytest.mark.dependency(depends=["test_mod_01.py::TestPage1::test_page1"], scope="class")
内容的提问来源于stack exchange,提问作者Taiwan004
相关产品推荐
相关产品推荐

