Skip to content

Commit c4adb9b

Browse files
committed
feat: make sure the benchmark fixture can only be called once per bench
1 parent 22d4d33 commit c4adb9b

2 files changed

Lines changed: 35 additions & 7 deletions

File tree

src/pytest_codspeed/plugin.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -318,14 +318,20 @@ def __init__(self, request: pytest.FixtureRequest):
318318
self.extra_info: dict = {}
319319

320320
self._request = request
321-
322-
def __call__(self, func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
323-
config = self._request.config
324-
plugin = get_plugin(config)
325-
if plugin.is_codspeed_enabled:
326-
return _measure(plugin, self._request.node, config, func, *args, **kwargs)
321+
self._config = self._request.config
322+
self._plugin = get_plugin(self._config)
323+
self._called = False
324+
325+
def __call__(self, target: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
326+
if self._called:
327+
raise RuntimeError("The benchmark fixture can only be used once per test")
328+
self._called = True
329+
if self._plugin.is_codspeed_enabled:
330+
return _measure(
331+
self._plugin, self._request.node, self._config, target, *args, **kwargs
332+
)
327333
else:
328-
return func(*args, **kwargs)
334+
return target(*args, **kwargs)
329335

330336

331337
@pytest.fixture(scope="function")

tests/test_pytest_plugin.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,25 @@ def test_capsys(capsys):
338338
result.assert_outcomes(passed=1)
339339
result.stdout.no_fnmatch_line("*print to stdout*")
340340
result.stderr.no_fnmatch_line("*print to stderr*")
341+
342+
@pytest.mark.parametrize("mode", [*MeasurementMode])
343+
def test_benchmark_fixture_used_twice(
344+
pytester: pytest.Pytester, mode: MeasurementMode
345+
) -> None:
346+
"""Test that using the benchmark fixture twice in a test raises an error."""
347+
pytester.makepyfile(
348+
"""
349+
def test_benchmark_used_twice(benchmark):
350+
def foo():
351+
pass
352+
353+
benchmark(foo)
354+
benchmark(foo)
355+
"""
356+
)
357+
result = run_pytest_codspeed_with_mode(pytester, mode)
358+
assert result.ret == 1, "the run should have failed"
359+
result.stdout.fnmatch_lines(
360+
["*RuntimeError: The benchmark fixture can only be used once per test*"]
361+
)
362+

0 commit comments

Comments
 (0)