当我们想要skip一个pytest用例时,习惯去使用@pytest.mark.skipif,我有一个需求是要用命令行参数来跳过用例,我这样写:
# conftest.py
def pytest_addoption(parser):
parser.addoption(
"--mode", action="store", default="fast", help="mode: fast or slow"
)
# 通过某种方法把命令行参数储存下来
Baseconfig.mode = request.config.getoption("--mode")
# test.py
@pytest.mark.skipif(Baseconfig.mode == slow, reason="do not support")
class TestFast:
...
当我运行test.py时,发现用例并没有跳过,我猜测skipif是在用例收集阶段完成的,还没有进行命令行参数复制,所以Baseconfig.mode为空(默认值是空),所以我改了一下:
@pytest.mark.skipif(Baseconfig.mode == '', reason="do not support")
这样用例果然跳过了,这也印证了我的猜想。
在网上搜索之后发现有两种方法来解决这个问题:
1. 使用pytest_collection_modifyitems钩子
这是一个可以在用例收集阶段改变用例的钩子,我在conftest里这样写:
# conftest.py
def pytest_collection_modifyitems(config, items):
slow_skip = pytest.mark.skip(reason="do not support slow")
if config.getoption('--mode') == 'slow':
for item in items:
if "slow" in item.name:
item.add_marker(slow_skip)
items就是每一个用例,这段代码的意思就是如果–mode是slow,则会跳过所有用例名称里带slow的case。
2. 在用例执行过程中skip
# test.py
def test_slow():
if Baseconfig.mode == "slow":
pytest.skip()
不过这样相当于也要执行用例的前置操作了。