我继承了一些实现pytest.mark.skipif
的代码以进行一些测试。通过阅读pytest文档,我知道我可以添加条件,可能检查环境变量,或者使用pytest.mark
的更高级功能一起控制测试组。不幸的是,到目前为止,文档中似乎没有任何东西可以解决我的问题。
我希望简单地关闭所有跳过测试的功能,但不修改测试的任何源代码。我只想在不接受任何测试跳过指标的模式下运行pytest。 pytest是否存在这样的解决方案?
答案 0 :(得分:2)
使用以下内容创建conftest.py:
import pytest
import _pytest.skipping
def pytest_addoption(parser):
parser.addoption(
"--no-skips",
action="store_true",
default=False, help="disable skip marks")
@pytest.hookimpl(tryfirst=True)
def pytest_cmdline_preparse(config, args):
if "--no-skips" not in args:
return
def no_skip(*args, **kwargs):
return
_pytest.skipping.skip = no_skip
即使在使用--no-skip
装饰器的某些测试用例中,也可以在命令行中使用pytest.mark.skip
运行所有测试用例
答案 1 :(得分:1)
好的,实现不允许对此进行零修改。您需要一个自定义标记。将以下内容添加到您的conftest.py
中,然后将所有skipif
标记更改为custom_skipif
。使用pytest --no-skips
。
import pytest
from _pytest.mark.evaluate import MarkEvaluator
def pytest_addoption(parser):
parser.addoption(
"--no-skips", action="store_true", default=False, help="disable custom_skip marks"
)
@hookimpl(tryfirst=True)
def pytest_runtest_setup(item):
if item.config.getoption('--no-skips'):
return
# Check if skip or skipif are specified as pytest marks
item._skipped_by_mark = False
eval_skipif = MarkEvaluator(item, "custom_skipif")
if eval_skipif.istrue():
item._skipped_by_mark = True
pytest.skip(eval_skipif.getexplanation())
for skip_info in item.iter_markers(name="custom_skip"):
item._skipped_by_mark = True
if "reason" in skip_info.kwargs:
pytest.skip(skip_info.kwargs["reason"])
elif skip_info.args:
pytest.skip(skip_info.args[0])
else:
pytest.skip("unconditional skip")
item._evalxfail = MarkEvaluator(item, "xfail")
check_xfail_no_run(item)
该实现是从skiptest.py中的pytest本身复制和修改的。
答案 2 :(得分:1)
一种忽略跳过标记的解决方法是以编程方式删除它们。创建一个包含以下内容的conftest.py
:
def pytest_collection_modifyitems(items):
for item in items:
for node in reversed(item.listchain()):
node.own_markers = [m for m in node.own_markers if m.name not in ('skip', 'skipif')]
但是,这与pytest
的内部结构混淆,很容易在pytest
更新时中断;忽略跳过的正确方法应该是定义您的自定义跳过机制,例如:
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_setup(item):
mark = item.get_closest_marker(name='myskip')
if mark:
condition = next(iter(mark.args), True)
reason = mark.kwargs.get('reason', 'custom skipping mechanism')
item.add_marker(pytest.mark.skipif(not os.getenv('PYTEST_RUN_FORCE_SKIPS', False) and condition, reason=reason), append=False)
用@pytest.mark.myskip
而不是@pytest.mark.skip
和@pytest.mark.myskip(condition, reason)
而不是@pytest.mark.skipif(condition, reason)
注释测试:
@pytest.mark.myskip
def test_skip():
assert True
@pytest.mark.myskip(1 == 1, reason='my skip')
def test_skipif():
assert True
在常规运行中,myskip
的行为与pytest.mark.skip
/ pytest.mark.skipif
相同。设置PYTEST_RUN_FORCE_SKIPS
将禁用它:
$ PYTEST_RUN_FORCE_SKIPS=1 pytest -v
...
test_spam.py::test_skip PASSED
test_spam.py::test_skipif PASSED
...
当然,您不应该再使用pytest.mark.skip
/ pytest.mark.skipif
,因为它们不会受到PYTEST_RUN_FORCE_SKIPS
环境变量的影响。
答案 3 :(得分:1)
一个简单的解决方法是在您的pytest.mark.skipif
中修补conftest.py
:
import pytest
old_skipif = pytest.mark.skipif
def custom_skipif(*args, **kwargs):
return old_skipif(False, reason='disabling skipif')
pytest.mark.skipif = custom_skipif