Skip to content

Convert test decorators to pytest fixtures #7973

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

Merged
merged 3 commits into from
Feb 1, 2017

Conversation

QuLogic
Copy link
Member

@QuLogic QuLogic commented Jan 28, 2017

I'm pre-opening this PR to verify that tests continue to build correctly. However, it still depends on #7935.

This PR converts the test decorators @cleanup and @switch_backend into a single pytest fixture that does both things at the same time. In order to set a different style or backend, tests must be marked with @pytest.mark.style('name') or @pytest.mark.backend('name').

Due to the way matplotlib.testing.setup works, it turns out that 'default' is the style used for any tests not decorated. Since this fixture uses 'classic', some additional tests needed to be marked by the 'default' style.

Additionally, because switch_backend calls matplotlib.testing.setup, the PGF tests (which use @cleanup('classic') do not actually use that style, so they've been set to 'default' here.

@QuLogic QuLogic added this to the 2.1 (next point release) milestone Jan 28, 2017
@QuLogic
Copy link
Member Author

QuLogic commented Jan 28, 2017

So I've been thinking, instead of backend and style, should the markers be called mpl_backend and mpl_style? This seems to mesh a bit more with the naming in pytest-mpl and maybe could be used there. Thoughts, @astrofrog?

@@ -1476,7 +1476,6 @@ def _jupyter_nbextension_paths():
default_test_modules = [
'matplotlib.tests.test_png',
'matplotlib.tests.test_units',
'matplotlib.tests.test_widgets',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's happening there?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When switching to the automatic fixture and dropping any @cleanups, the tests fail with nose because they don't get that setup done. However, see next comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being dense, but why does this variable even exist? Why do we have a default whitelist of tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used for matplotlib.test(); in the next PR I just set it to the top-level modules.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to keep matplotlib.test()? Even if we do, can we just make matplotlib.test() fully rely on pytest's test discovery?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why I pass only the top-level modules; but we still need to pass something because this works on the installed version and we need to hit both matplotlib and mpl_toolkits. I wouldn't be against deprecating matplotlib.test() and the top-level tests.py.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it.

After the general conversion, do we expect nosetests to correctly run the tests?

  • If the answer is yes, I give up (I appreciate your efforts in making this work but conversion to a test suite that supports two runners is way too hard for me to follow properly).
  • If the answer is no, we already broke one way of running the tests. I honestly cannot imagine why we would need to keep backcompat for another one, and would thus just kill matplotlib.test() (... and tests.py at the same time).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer to the first question is no as far as our own tests are concerned. But matplotlib.test() and tests.py will work with pytest in #7974. I have no idea how many people may or may not be using that method, so I don't know whether we should remove it or not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we already broke backcompat on our tests by having a requirement on pytest, and by making it not possible to run the test suite by running nosetests. I simply do not understand why we can't just break it a bit more to get rid of old warts... that we're planning to get rid of anyways.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm not against it, but I think this discussion really belongs on #7974 where that code is actually changed.

@QuLogic
Copy link
Member Author

QuLogic commented Jan 29, 2017

So while I was out, I've been thinking about this PR, and I think it might be a bit of a bear, maintenance-wise. Removing all the @cleanup makes this conflict a lot with 2.0.x, so I've thought up an alternate plan:

  1. Keep using the new fixture.
  2. Replace switch_backend with a pytest marker as in this PR. There are not too many users and they are already completely different from 2.0.x, so the conflicts already exist.
  3. Turn cleanup into a no-op when run from pytest. Initially, I didn't think this was possible, but I think I've come up with a way to get it to work on Python 2.
  4. Closer to the release of 2.1, properly finalize the conversion by removing the @cleanup as in this PR right now.

This gives us a slight reduction on conflicts when writing and backporting tests, with the downside that @cleanup does nothing on master, but this could be a small price to pay for the easier maintenance.

This is in these two branches, pytest-fixture2 and pytest2. What do people think?

@@ -83,8 +82,8 @@ def create_figure():

# test compiling a figure to pdf with xelatex
@needs_xelatex
@cleanup(style='classic')
@switch_backend('pgf')
@pytest.mark.style('default')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @QuLogic
This is the place were I noticed that we were changing stylesheet. Can you confirm this is not normal?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or explain to me why it runs fine :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so @dopplershift explained it to me, and I now understand.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For those reading along at home, the outer decorator that was here was being ignored and the last time we generated the images for these test we accidentally switched to the default style.

This was 'fixed' as part of the pytest migration so we need to switch the mark to 'default' style.

@tacaswell
Copy link
Member

I am am 👍 on just dropping cleanup, we have alot of conflicts anyway and that is an easy one to resolve.

@QuLogic
Copy link
Member Author

QuLogic commented Jan 30, 2017

In that case, I believe this requires a small rebase to delete some new @cleanup on master.

Any non-default styles can be specified with
`@pytest.mark.style('name')`.
Non default backends can be specified by marking test functions with
`@pytest.mark.backend('backend')`.

Note that because switch_backend calls `matplotlib.testing.setup`, and
it appears _below_ the previous `@cleanup` decorator in the PGF tests,
the specified 'classic' style is not actually used for those tests.
@tacaswell
Copy link
Member

To move things along I am going to merge this.

@tacaswell tacaswell merged commit f858cc5 into matplotlib:master Feb 1, 2017
@QuLogic QuLogic deleted the pytest-fixture branch February 1, 2017 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants