Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the first, instead of the last result in benchmark fixture #222

Open
jvesely opened this issue Aug 4, 2022 · 1 comment
Open

Comments

@jvesely
Copy link

jvesely commented Aug 4, 2022

The current behaviour is to return the last result of multiple iterations. This makes testing stateful functions difficult.
For example:

import pytest

class foo():
    def __init__(self):
        self.x = 0

    def inc(self):
        self.x = self.x + 1
        return self.x


@pytest.mark.benchmark
def test_inc(benchmark):
    f = foo()

    res = benchmark(f.inc)
    assert res == 1

The above snippet only passes with --benchmark-disable and fails with benchmarks enabled.
I know it's possible to get the number of executions from the benchmark object, but the expected result might not be as easy to calculate as above.

one alternative is:

res = f.inc()
assert res == 1
if (benchmark.enabled):
   benchmark(f.inc)

but that complains/warns that the benchmark fixture is unused so the correct workaround would be

res = f.inc()
assert res == 1
if (benchmark.enabled):
   benchmark(f.inc)
else:
   benchmark(lambda :None)
@Jwely
Copy link

Jwely commented Aug 25, 2022

I encountered this problem when benchmarking a function which mutates its own input arguments. The first run, this mutation had a side effect, but on subsequent runs, the mutation wasn't necessary, and so the side effect was not observed.

Workaround is to encpasulate this function in a wrapper that deepcopies any initial state and provides the copy to the stateful function to mutate.

use the benchmark_safe wrapper on the benchmark call instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants