如何为单个测试禁用pytest插件

Jov*_*vik 13 python plugins pytest python-3.x

我已经安装了新的pytest插件(pytest-catchlog==1.2.2),并且我喜欢它,它打破了我对日志模块的单元测试(例如ValueError: I/O operation on closed file).

我想为test_logging.py文件(甚至是类或方法)禁用该插件,但我找不到任何关于它的信息.

到目前为止,我发现的唯一选项是执行两次pytest:第一次用于test_logging.py,只有catchlog disabled(py.test -p no:catchlog test_logging.py),第二次用于所有其他测试文件.

如果我错过了pytest装饰器,或者在运行时禁用插件的任何其他方式,请告诉我.

Ser*_*yev 7

您无法有选择地禁用所选测试的任意插件.插件在更早的阶段加载 - 当pytest开始时.插件实际上定义了pytest的作用和方式(即命令行选项,测试集合,过滤等).

换句话说,在进行测试执行时重新定义pytest的内部结构为时已晚.

确实,最好的情况是用你的测试标记@pytest.mark.nocatchlog,并分别执行:

pytest -m 'nocatchlog' -p no:catchlog  # problematic tests with no plugin
pytest -m 'not nocatchlog`             # all other tests
Run Code Online (Sandbox Code Playgroud)

如果那些测试不在你的控制范围内,即如果你不能添加标记,那么你只能通过像-k test_logging或者表达式来过滤-k 'not test_logging'(即通过它们的节点id的一部分).


特别是对于这个pytest-catchlog插件,你可以创建相同的钩子,并从根记录器中删除它的日志处理程序(假设没有明确使用其他记录器):

conftest.py:

import pytest

def _disable_catchlog(item):
    logger = logging.getLogger()
    if item.catch_log_handler in logger.handlers:
        logger.handlers.remove(item.catch_log_handler)

@pytest.hookimpl(hookwrapper=True, trylast=True)
def pytest_runtest_setup(item):
    _disable_catchlog(item)
    yield

@pytest.hookimpl(hookwrapper=True, trylast=True)
def pytest_runtest_call(item):
    _disable_catchlog(item)
    yield

@pytest.hookimpl(hookwrapper=True, trylast=True)
def pytest_runtest_teardown(item):
    _disable_catchlog(item)
    yield
Run Code Online (Sandbox Code Playgroud)

  • 这太烦人了,就像你安装了 pytest-django 一样,它期望为所有测试运行配置,即使是不使用 Django 的测试 (3认同)