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

Refactor xfail tests to avoid storing baseline images #603

Merged
merged 10 commits into from
Oct 15, 2020

Conversation

seisman
Copy link
Member

@seisman seisman commented Sep 12, 2020

Description of proposed changes

This PR refactors the xfail/fail tests to let the tests pass and avoid storing baseline images.

The baseline images are generated by calling the same modules using plain text or grid files are input, and using single-character arguments.

Address #451.

Remaining issues:

  • The two xfailing tests in test_config are not refactored. There is no easy way to generate references images for them.

TODOs for future PRs:

  • Tests that are passing are not refactored. These tests still use the images in the pygmt/test/baselines directory as baselines.
  • Images of those xfailing/failing tests are no longer needed, but this PR doesn't delete them from the repository.

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If adding new functionality, add an example to docstrings or tutorials.

Comment on lines 65 to 67
fig_ref = Figure()
with Session() as lib:
lib.call_module("basemap", "-R0/360/0/1000 -JP6i -Bafg")
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 reference image is created by directly calling the low-level API function call_module.

Copy link
Member

@weiji14 weiji14 Sep 12, 2020

Choose a reason for hiding this comment

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

I like the concept in general (testing against the low level GMT API), but this can get complicated real fast for some modules that output to a file (see e.g. @liamtoney's example at #364 (comment) for grdgradient). Though to be honest, that's probably not what this PR is about.

Should we have a convenience function to wrap around this low-level API better? E.g. something like pygmt.gmt(module="basemap", arg_str="-R0/360/0/1000 -JP6i -Bafg") that removes the with` statement.

Copy link
Member Author

Choose a reason for hiding this comment

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

but this can get complicated real fast for some modules that output to a file (see e.g. @liamtoney's example at #364 (comment) for grdgradient).

Most tests are simple, testing only one aspect of functions. #364 (comment) example may be the most complicated one, but we won't use virtual files for the references images.

Should we have a convenience function to wrap around this low-level API better? E.g. something like pygmt.gmt(module="basemap", arg_str="-R0/360/0/1000 -JP6i -Bafg") that removes the with` statement.

I believe @leouieda is against it (#122 (comment)).

Copy link
Member

Choose a reason for hiding this comment

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

Most tests are simple, testing only one aspect of functions. #364 (comment) example may be the most complicated one, but we won't use virtual files for the references images.

True, but as you mentioned, this way of testing isn't very Pythonic or new contributor friendly. We can definitely think of a better solution that doesn't involve clib here, just need a bit more time, and maybe have a look around some other projects like GMT.jl and matplotlib to see how they do it.

I believe @leouieda is against it (#122 (comment)).

Ah yes, I thought I saw this somewhere before, thanks for linking. Definitely hold on the pygmt.gmt/fig.rawcommand feature then.

@weiji14 weiji14 assigned weiji14 and unassigned weiji14 Sep 17, 2020
@weiji14 weiji14 added the maintenance Boring but important stuff for the core devs label Sep 17, 2020
Comment on lines 62 to 67
fig_test = Figure()
fig_test.basemap(R="0/360/0/1000", J="P6i", B="afg")

fig_ref = Figure()
with Session() as lib:
lib.call_module("basemap", "-R0/360/0/1000 -JP6i -Bafg")
Copy link
Member

Choose a reason for hiding this comment

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

Just as a throwaway idea, what about testing that the long aliases and list-to-str conversion works? I.e. have fig_test use long aliases like region, and have fig_ref use the short alias like R.

Suggested change
fig_test = Figure()
fig_test.basemap(R="0/360/0/1000", J="P6i", B="afg")
fig_ref = Figure()
with Session() as lib:
lib.call_module("basemap", "-R0/360/0/1000 -JP6i -Bafg")
fig_test = Figure()
fig_test.basemap(region=[0, 360, 0, 1000], projection="P6i", frame="afg")
fig_ref = Figure()
fig_ref.basemap(R="0/360/0/1000", J="P6i", B="afg")

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds a clever idea. I believe we are confident that arguments like R="0/360/0/1000", J="P6i", B="afg" will be converted to "-R0/360/0/1000 -JP6i -Bafg", thus, fig_ref.basemap(R="0/360/0/1000", J="P6i", B="afg") is the same as lib.call_module("basemap", "-R0/360/0/1000 -JP6i -Bafg").

Copy link
Member

Choose a reason for hiding this comment

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

Cool, if you want to update this PR to fix the failing 'polar', 'logo' (as mentioned at #451 (comment)) tests, and any other ones that pop up (I saw a few more upstream GMT changes already...), I'll review it later.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK. I'll work on this PR.

@seisman seisman changed the title Example showing how to fully avoid storing the baseline images Refactor xfail tests to avoid storing baseline images Oct 15, 2020
@seisman seisman force-pushed the reffig_by_call_module branch from 20b0730 to 23494f0 Compare October 15, 2020 06:47
@seisman seisman force-pushed the reffig_by_call_module branch from 23494f0 to cc7c6b3 Compare October 15, 2020 06:57
@seisman seisman marked this pull request as ready for review October 15, 2020 07:00
@seisman seisman force-pushed the reffig_by_call_module branch from cc7c6b3 to db18f4b Compare October 15, 2020 14:10
@seisman seisman requested a review from weiji14 October 15, 2020 14:30
@seisman seisman added this to the 0.2.1 milestone Oct 15, 2020
Copy link
Member

@weiji14 weiji14 left a comment

Choose a reason for hiding this comment

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

A lot to review, but it's looking good! Just a couple of comments.

The two xfailing tests in test_config are not refactored. There is no easy way to generate references images for them.

Images of those xfailing/failing tests are no longer needed, but this PR doesn't delete them from the repository.

Yes, will need to remember to do these in the future as separate PRs.

pygmt/tests/test_grdcontour.py Outdated Show resolved Hide resolved
pygmt/tests/test_plot.py Outdated Show resolved Hide resolved
@seisman seisman merged commit 203e647 into master Oct 15, 2020
@seisman seisman deleted the reffig_by_call_module branch October 15, 2020 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Boring but important stuff for the core devs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants