获取测试套件中每个测试的 SQL 查询计数概览
Get overview of SQL query count for every test in a test suite
我有一个大型 Django 应用程序,其中包含大量需要 SQL 查询优化的测试。
我正在使用 pytest-django 运行 我的测试。
我不想为每个测试单独添加 assertNumQueries
或 django-assert-num-queries
,而是生成一个关于 中每个测试有多少 SQL 查询的概览所有 的测试都在触发,以了解最需要优化的代码,如下所示:
test | number of queries
------------------------------------------------
test_a.py::test_my_function1 | 5
test_a.py::test_my_function3 | 2
test_a.py::test_my_function5 | 7
是否可以在 conftest.py 中配置一个 pytest 挂钩,它计算每个(数据库)测试的 SQL 查询的数量并在结果中显示它们 - 而无需修改源代码我的测试(比如添加装饰器)?
我天真的方法是使用这些挂钩,并以某种方式在每次测试前后访问数据库连接:
def pytest_runtest_call(item):
pass
def pytest_runtest_teardown(item, nextitem):
return True
为了记录查询计数,自动使用装置就足够了。在下面的示例中,我将计数存储在配置对象下的 queries_count
字典中:
@pytest.fixture(autouse=True)
def record_query_count(request):
from django.test.utils import CaptureQueriesContext
from django.db import connection
with CaptureQueriesContext(connection) as context:
yield
num_performed = len(context)
if not hasattr(request.config, "query_counts"):
request.config.query_counts = dict()
request.config.query_counts[request.node.nodeid] = num_performed
为了输出结果,我在 pytest_terminal_summary
挂钩的自定义实现中添加了一个自定义部分。将以下代码放在项目或测试根目录中名为 conftest.py
的文件中:
import os
def pytest_terminal_summary(terminalreporter, exitstatus, config):
content = os.linesep.join(
f'{nodeid:40} | {num_queries}'
for nodeid, num_queries in config.query_counts.items()
)
terminalreporter.ensure_newline()
terminalreporter.section('number of queries', sep='-', bold=True)
terminalreporter.line(content)
运行 测试现在将产生:
tests/test_db.py ... [100%]
----------------------------------- number of queries ------------------------------------
tests/test_db.py::test_add_entry | 2
tests/test_db.py::test_remove_entry | 2
tests/test_db.py::test_no_entries | 1
=================================== 3 passed in 0.26s ====================================
我有一个大型 Django 应用程序,其中包含大量需要 SQL 查询优化的测试。
我正在使用 pytest-django 运行 我的测试。
我不想为每个测试单独添加 assertNumQueries
或 django-assert-num-queries
,而是生成一个关于 中每个测试有多少 SQL 查询的概览所有 的测试都在触发,以了解最需要优化的代码,如下所示:
test | number of queries
------------------------------------------------
test_a.py::test_my_function1 | 5
test_a.py::test_my_function3 | 2
test_a.py::test_my_function5 | 7
是否可以在 conftest.py 中配置一个 pytest 挂钩,它计算每个(数据库)测试的 SQL 查询的数量并在结果中显示它们 - 而无需修改源代码我的测试(比如添加装饰器)?
我天真的方法是使用这些挂钩,并以某种方式在每次测试前后访问数据库连接:
def pytest_runtest_call(item):
pass
def pytest_runtest_teardown(item, nextitem):
return True
为了记录查询计数,自动使用装置就足够了。在下面的示例中,我将计数存储在配置对象下的 queries_count
字典中:
@pytest.fixture(autouse=True)
def record_query_count(request):
from django.test.utils import CaptureQueriesContext
from django.db import connection
with CaptureQueriesContext(connection) as context:
yield
num_performed = len(context)
if not hasattr(request.config, "query_counts"):
request.config.query_counts = dict()
request.config.query_counts[request.node.nodeid] = num_performed
为了输出结果,我在 pytest_terminal_summary
挂钩的自定义实现中添加了一个自定义部分。将以下代码放在项目或测试根目录中名为 conftest.py
的文件中:
import os
def pytest_terminal_summary(terminalreporter, exitstatus, config):
content = os.linesep.join(
f'{nodeid:40} | {num_queries}'
for nodeid, num_queries in config.query_counts.items()
)
terminalreporter.ensure_newline()
terminalreporter.section('number of queries', sep='-', bold=True)
terminalreporter.line(content)
运行 测试现在将产生:
tests/test_db.py ... [100%]
----------------------------------- number of queries ------------------------------------
tests/test_db.py::test_add_entry | 2
tests/test_db.py::test_remove_entry | 2
tests/test_db.py::test_no_entries | 1
=================================== 3 passed in 0.26s ====================================