[英]Automatically wrap / decorate all pytest unit tests
Let's say I have a very simple logging decorator:假设我有一个非常简单的日志装饰器:
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
I can add this decorator to every pytest unit test individually:我可以将这个装饰器单独添加到每个 pytest 单元测试中:
@my_decorator
def test_one():
assert True
@my_decorator
def test_two():
assert 1
How can I automatically add this decorator to every single pytest unit test so I don't have to add it manually?如何自动将此装饰器添加到每个 pytest 单元测试中,这样我就不必手动添加它了? What if I want to add it to every unit test in a file?
如果我想将它添加到文件中的每个单元测试怎么办? Or in a module?
还是在一个模块中?
My use case is to wrap every test function with a SQL profiler, so inefficient ORM code raises an error.我的用例是用 SQL 分析器包装每个测试 function,因此效率低下的 ORM 代码会引发错误。 Using a pytest fixture should work, but I have thousands of tests so it would be nice to apply the wrapper automatically instead of adding the fixture to every single test.
使用 pytest 夹具应该可以工作,但我有数千个测试,所以自动应用包装器而不是将夹具添加到每个测试中会很好。 Additionally, there may be a module or two I don't want to profile so being able to opt-in or opt-out an entire file or module would be helpful.
此外,可能有一两个模块我不想分析,因此能够选择加入或退出整个文件或模块会很有帮助。
Provided you can move the logic into a fixture, as stated in the question, you can just use an auto-use fixture defined in the top-level conftest.py
.如果您可以将逻辑移动到夹具中,如问题中所述,您只需使用顶级
conftest.py
中定义的自动使用夹具。
To add the possibility to opt out for some tests, you can define a marker that will be added to the tests that should not use the fixture, and check that marker in the fixture, eg something like this:为了增加选择退出某些测试的可能性,您可以定义一个标记,该标记将添加到不应使用夹具的测试中,并检查夹具中的该标记,例如:
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测试.py
import pytest
def test1():
pass # will use profiling
@pytest.mark.no_profiling
def test2():
pass # will not use profiling
As pointed out by @hoefling, you could also disable the fixture for a whole module by adding:正如@hoefling 所指出的,您还可以通过添加以下内容来禁用整个模块的固定装置:
pytestmark = pytest.mark.no_profiling
in the module.在模块中。 That will add the marker to all contained tests.
这会将标记添加到所有包含的测试中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.