【问题标题】:Automatically wrap / decorate all pytest unit tests自动包装/装饰所有 pytest 单元测试
【发布时间】:2021-04-09 22:54:42
【问题描述】:

假设我有一个非常简单的日志装饰器:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"{func.__name__} ran with args: {args}, and kwargs: {kwargs}")
        result = func(*args, **kwargs)
        return result
    return wrapper

我可以将这个装饰器单独添加到每个 pytest 单元测试中:

@my_decorator
def test_one():
    assert True

@my_decorator
def test_two():
    assert 1

如何自动将此装饰器添加到每个 pytest 单元测试中,这样我就不必手动添加它了?如果我想将它添加到文件中的每个单元测试怎么办?还是在一个模块中?

我的用例是用 SQL 分析器包装每个测试函数,因此低效的 ORM 代码会引发错误。使用 pytest 夹具应该可以工作,但我有数千个测试,所以自动应用包装器而不是将夹具添加到每个测试中会很好。此外,可能有一两个模块我不想分析,因此能够选择加入或退出整个文件或模块会很有帮助。

【问题讨论】:

  • 你能提供一些关于你的用例的信息吗? pytest 中的标准方法是使用自动使用的夹具,但也许您想做一些使用夹具无法完成的事情?
  • @MrBeanBremen 刚刚用我的用例更新了上面的问题

标签: python pytest


【解决方案1】:

如果您可以将逻辑移动到夹具中,如问题中所述,您可以只使用在顶级 conftest.py 中定义的自动使用夹具。

要增加退出某些测试的可能性,您可以定义一个标记,该标记将添加到不应使用夹具的测试中,并检查夹具中的该标记,例如像这样:

conftest.py

import pytest

def pytest_configure(config):
    config.addinivalue_line(
        "markers",
        "no_profiling: mark test to not use sql profiling"
    )

@pytest.fixture(autouse=True)
def sql_profiling(request):
    if not request.node.get_closest_marker("no_profiling"):
        # do the profiling
    yield

test.py

import pytest

def test1():
    pass # will use profiling

@pytest.mark.no_profiling
def test2():
    pass # will not use profiling

正如@hoefling 所指出的,您还可以通过添加以下内容来禁用整个模块的固定装置:

pytestmark = pytest.mark.no_profiling

在模块中。这会将标记添加到所有包含的测试中。

【讨论】:

  • 不错的答案 - 这也允许通过添加模块 var pytestmark = pytest.mark.no_profiling 来关闭整个模块的固定装置。因此根本不需要自定义装饰器!
  • 我收到以下错误:ValueError: unknown configuration value: 'no_profiling' - 但是一旦我删除了pytest_configure,一切正常。谢谢!
  • 啊,抱歉 - 我在标记注册语法中犯了一个错误,现在更正它。否则,您会收到有关未知标记的警告。
猜你喜欢
  • 2018-01-09
  • 2016-12-30
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 2016-03-29
相关资源
最近更新 更多