-
-
Notifications
You must be signed in to change notification settings - Fork 28
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
RFC: refactor benchmarks setups and customize pytest's discovery rule to enable running benchmarks through pytest #116
base: main
Are you sure you want to change the base?
Conversation
bff6fcc
to
9531a80
Compare
Ok I resolved the test pollution issue by switching from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Hopefully setup_method
doesn't mean anything special to asv
...
Maybe Zach can take this branch for a spin to be sure?
9531a80
to
c6dd80e
Compare
I do start to wonder sometimes whether the benchmarks shouldn't just be part of our normal test suite - they are just tests that we happen to monitor the execution time for. In principle we could even monitor the execution time of all our tests in the regular test suite! (but obviously the ones here are designed to be more consistent/minimal in what they measure) |
Some are stress test that can significantly lengthen CI run time (which @neutrinoceros tried hard to cut down recently). |
I guess cron is acceptable... 🤔 |
Mostly unrelated to this PR, just bringing it to benchmarking-interested people's attention... https://docs.codspeed.io + pytest-benchmark. |
c6dd80e
to
84a744d
Compare
I finished tweaking discovery rules to get (almost) every benchmark running with pytest. I'm explicitly excluding 3/238 benchmarks that pytest chokes on, but all 235 others run fine. |
Re: #116 (comment) -- @nstarman , please open a new issue so your idea doesn't get buried here. Thanks! |
Done in #117 |
Just to be clear, I'm not saying they would be enabled by default - more that they could live alongside the regular tests albeit have a special marker/decorator to ensure they are not run by default. |
Can you please rebase to pick up #119 by @astrofrog ? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good so far! Just to put the idea on the table, we could always have a base class that defines:
class BaseBenchmarks:
def setup_method(self, *args, **kwargs):
sefl.setup(*args, **kwargs)
Also, does this PR work with parametrized tests? (see e.g. #118)
EDIT: oh I see it doesn't, because that's what's failing in cosmology
pytest.ini
Outdated
# customize test discovery to treat benchmarks as tests | ||
python_files = *.py | ||
python_classes = Time *Benchmarks | ||
python_functions = time_* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future-proofness, we might want to support these different asv benchmark types:
https://asv.readthedocs.io/en/stable/benchmarks.html
specifically time_*
, timeraw_*
, mem_*
, peakmem_*
, and track_*
although the latter might not work because I think pytest doesn't like tests that return things.
A possible solution to parametrization might be to make use of |
84a744d
to
ff413fe
Compare
rebased and took the first batch of comments into account. Looking at parametrization now. |
Sorry, I just merged #118 so this will need another rebase to pick that up too. Thanks for your patience! |
Just to put it on the table, another completely different idea to enable coverage is to run asv with the coverage tool although we will need to configure things so that subprocesses work. But just in case parametrization ends up not working. |
regarding parametrization, I think this is how you'd do it: def pytest_generate_tests(metafunc):
if metafunc.cls is None or not hasattr(metafunc.cls, "params"):
return
name = metafunc.fixturenames[0]
values = metafunc.cls.params
metafunc.parametrize(name, values) However, it still won't work with
I don't know if we can work around this or how. This might be a dead end. |
… to enable running benchmarks through pytest
ff413fe
to
3bde28c
Compare
I rebased again just in case we don't just close this |
I also opened #120, suggesting we use pytest as the manager for benchmarking, using the pytest ecosystem like |
As suggested in #115 (comment), this is a first step towards enabling code coverage for benchmarks.
When run locally I get 4 failures that are only reproduced when the all suite is run, which seems indicative of some test pollution. I'd like to get to the bottom of this before I undraft this PR.