-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Starter property-based test suite #1972
Conversation
6c02f79
to
6df5cd3
Compare
Ping @fmaussion / @shoyer - would love your opinions on this, including high-value targets to test. (btw Appveyor had an internal error; build is otherwise green) |
This looks like a great start to me -- thank you! It's impressive that it's possible to break every plotting type with matplotlib :). |
You're welcome! Same questions as above though, plus "is there anything else you need in this initial PR?". If not, can we merge it
As much as I love matplotlib, it's a steaming pile of hacks and I want to avoid it more than I want it cleaned up 😥 (entirely because the process is dysfunctional, not the code) |
One thing that comes to mind is organization... would it make sense to put this alongside the current xarray tests, e.g., have I guess one downside of this would be that it could change how we need to invoke py.test by default, if we don't want to trigger all the property based tests. |
What do the failing data sets look like? Does it get easier or harder to find failures if you go up to 10x10? What sort of exceptions are you getting? You can shove a fair amount of configuration in to |
@shoyer - that depends mostly on whether you want to run these tests as part of a standard run. A test-time dependency on Hypothesis is very cheap compared to the other dev dependencies, so I'd think more about the impact on eg CI resources than contributors. Upside is more power and coverage of edge-cases with odd data; downside is that they take a lot longer by virtue of trying hundreds of examples, and in this case also having to generate arrays takes a while (~log(elements) average via sparse filling). @tacaswell - I would be delighted to write a test suite like this for matplotlib! The only reason I haven't is because I thought it would be rude to report so many bugs that I don't have time to help fix. If we can get a group project going though I'd be very enthusiastic 😄
I didn't keep the exact tracebacks, but I remember seeing many come from overflow in tick spacing calculations. Again, happy to write a test suite and make more detailed reports upstream if people want to fix this - in which case let's open an issue there! |
If we don't want to trigger by default, we can do something like this and require passing this to run them:
|
As pointed out on the matplotlib gitter: If you run import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
for i in range(200):
xr.DataArray(np.array([[0, 0], [0, 0]], dtype=np.uint8)).plot.pcolormesh() at step 165 you will get:
Why? Because you have made a plot that if it displays looks like: Are you sure your test isn't doing something similar? At some point there just isn't room for more colorbars! Adding a Its also is possible you are hitting floating point overflows with your test. At some point Matplotlib needs to be able to manipulate the data that comes in, and if you operate near the maximum number your data type can handle, you'll have problems. Just like you would if you just did a = 2*xr.DataArray(np.array([[0, 0], [0, 1e308]])) you will get:
So maybe your hypothesis tester could be constrained to stay away from floating point overflows? Matplotlib indeed has flaws and quirks, but if you are finding bugs it would be good to isolate them. |
...that also explains why I was having trouble reproducing the error, whoops. I'll see how it goes with those problems excluded later tonight! |
@jklymak - I'm getting (I'm also getting Zarr errors, but I assume those will go away soon as I didn't cause them) |
Set the backend to Agg on travis as you don't have a xserever running. You probably want to manually force a draw as well. |
properties/test_plotting.py
Outdated
|
||
import matplotlib | ||
matplotlib.use('Agg') | ||
import matplotlib.pyplot as plt |
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.
E402 module level import not at top of file
properties/test_plotting.py
Outdated
matplotlib.use('Agg') | ||
import matplotlib.pyplot as plt | ||
|
||
from hypothesis import given, settings |
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.
E402 module level import not at top of file
properties/test_plotting.py
Outdated
import matplotlib.pyplot as plt | ||
|
||
from hypothesis import given, settings | ||
import hypothesis.strategies as st |
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.
E402 module level import not at top of file
properties/test_plotting.py
Outdated
|
||
from hypothesis import given, settings | ||
import hypothesis.strategies as st | ||
import hypothesis.extra.numpy as npst |
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.
E402 module level import not at top of file
properties/test_plotting.py
Outdated
import hypothesis.strategies as st | ||
import hypothesis.extra.numpy as npst | ||
|
||
import xarray as xr |
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.
E402 module level import not at top of file
properties/test_plotting.py
Outdated
two_dimensional_array = st.sampled_from([ | ||
dict(dtype=npst.unsigned_integer_dtypes() | npst.integer_dtypes()), | ||
dict(dtype=npst.floating_dtypes(), elements=st.floats(-2.**100, 2.**100)), | ||
# Then, we "flatmap" this into an arrays strategy - ie create a strategy using |
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.
E122 continuation line missing indentation or outdented
properties/test_plotting.py
Outdated
dict(dtype=npst.unsigned_integer_dtypes() | npst.integer_dtypes()), | ||
dict(dtype=npst.floating_dtypes(), elements=st.floats(-2.**100, 2.**100)), | ||
# Then, we "flatmap" this into an arrays strategy - ie create a strategy using | ||
# the kwargs above and a shape, then draw a value from that. |
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.
E122 continuation line missing indentation or outdented
properties/test_plotting.py
Outdated
# Then, we "flatmap" this into an arrays strategy - ie create a strategy using | ||
# the kwargs above and a shape, then draw a value from that. | ||
]).flatmap(lambda kwargs: npst.arrays( | ||
**kwargs, shape=st.tuples(st.integers(2, 5), st.integers(2, 5)), |
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.
E999 SyntaxError: invalid syntax
a7a7876
to
7c89212
Compare
properties/test_plotting.py
Outdated
dict(dtype=npst.unsigned_integer_dtypes() | npst.integer_dtypes()), | ||
dict(dtype=st.sampled_from(['float32', 'float64']), | ||
elements=st.floats(-2.**50, 2.**50)), | ||
# Then, we "flatmap" this into an arrays strategy - ie create a strategy using |
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.
E122 continuation line missing indentation or outdented
properties/test_plotting.py
Outdated
dict(dtype=st.sampled_from(['float32', 'float64']), | ||
elements=st.floats(-2.**50, 2.**50)), | ||
# Then, we "flatmap" this into an arrays strategy - ie create a strategy using | ||
# the kwargs above and a shape, then draw a value from that. |
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.
E122 continuation line missing indentation or outdented
properties/test_plotting.py
Outdated
# Then, we "flatmap" this into an arrays strategy - ie create a strategy using | ||
# the kwargs above and a shape, then draw a value from that. | ||
]).flatmap(lambda kwargs: npst.arrays( | ||
**kwargs, shape=st.tuples(st.integers(2, 5), st.integers(2, 5)), |
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.
E999 SyntaxError: invalid syntax
properties/test_plotting.py
Outdated
|
||
import matplotlib | ||
matplotlib.use('Agg') | ||
import matplotlib.pyplot as plt |
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.
E402 module level import not at top of file
a18d973
to
47e0258
Compare
properties/test_plotting.py
Outdated
dict(dtype=st.sampled_from(['float32', 'float64']), | ||
elements=st.floats(-2.**50, 2.**50)), | ||
]).flatmap(lambda kwargs: npst.arrays( | ||
shape=st.tuples(st.integers(2, 5), st.integers(2, 5)), **kwargs, |
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.
E999 SyntaxError: invalid syntax
47e0258
to
1db77e6
Compare
@shoyer & @fmaussion - I've just given up on the plotting tests as being more effort than they're worth. Are there any:
|
This looks pretty good to me in its current state. I would say we should merge it now and iterate in future PRs.
Almost anywhere where we currently make heavy use of
|
Merge away then! |
Thanks @Zac-HD ! |
This is a small property-based test suite, to give two examples of the kinds of tests that we could write for Xarray using Hypothesis.
(Contributing a very small feature to matplotlib was shockingly painful, so I'm not planning to take a similar suite upstream myself unless something changes)
Things that I would like to know: