-
Notifications
You must be signed in to change notification settings - Fork 56
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
Convert unittest to pytest #478
Conversation
Original testing output via
Converted to pytest output via
All original tests are maintained with some added to keep the original structure Additional warnings will be addressed as part of #477 |
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 good! I've left a few comments below. Also, I think we should be able to remove the flags: unittests
line in .github/workflows/ci.yml
since everything should be pure pytest now.
495130c
to
cbe2354
Compare
|
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.
In summary from our convo:
- fixtures that just create class variables can likely be eliminated by just creating these variables in the class
- fixtures that read in data from files should be kept and provide these variables with return or yield instead of assigning to the class
- set ups with dask client creation should be pulled into their own fixtures and only provided to the tests that require them instead of lumping them in with an
autouse=True
fixture.
Additionally, where possible I think we should use more descriptive function names for these fixtures where possible.
Improved runtime from 240s -> 140s with new fixtures
|
Further fixtures for files I/O continue to improve runtime (from 140s -> 135s) from the original 240s
|
I've made a branch off of this one that shows the type of changes I'm looking for on My formatter took over and made some additional changes, but I hope it's still possible to see the substantive changes over the formatting differences. |
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 for the changes! I've included one last request here and then I think we'll be good to go.
test/test_interpolation.py
Outdated
@pytest.fixture(scope="class") | ||
def test_input(self): | ||
return xr.load_dataset( | ||
gdf.get("netcdf_files/interpolation_test_input_data.nc")) | ||
|
||
cls.test_output = xr.load_dataset( | ||
@pytest.fixture(scope="class") | ||
def test_output(self): | ||
return xr.load_dataset( | ||
gdf.get("netcdf_files/interpolation_test_output_data.nc")) | ||
|
||
cls.data_in = cls.test_input['normal'] | ||
cls.data_out = cls.test_output['normal'] | ||
|
||
cls.lat_in = cls.data_in['lat'].values | ||
cls.lat_out = cls.data_out['lat'].values | ||
cls.lon_in = cls.data_in['lon'].values | ||
cls.lon_out = cls.data_out['lon'].values | ||
|
||
cls.data_in_nan = cls.test_input['nan'] | ||
cls.data_out_nan = cls.test_output['nan'] | ||
|
||
cls.data_in_nan_2 = cls.test_input['nan_2'] | ||
cls.data_out_nan_2 = cls.test_output['nan_2'] | ||
|
||
cls.data_in_missing = cls.test_input['missing'] | ||
cls.data_out_missing = cls.test_output['missing'] | ||
|
||
cls.data_in_mask = cls.test_input['mask'] | ||
cls.data_out_mask = cls.test_output['mask'] | ||
|
||
def test_float32(self): | ||
np.testing.assert_almost_equal( | ||
self.data_out.values.astype(np.float32), | ||
interp_multidim(xr.DataArray(self.data_in.values.astype(np.float32), | ||
dims=['lat', 'lon'], | ||
coords={ | ||
'lat': self.lat_in, | ||
'lon': self.lon_in, | ||
}), | ||
self.lat_out, | ||
self.lon_out, | ||
cyclic=True).values, | ||
decimal=7) | ||
|
||
def test_float64(self): | ||
@pytest.fixture(scope="class") | ||
def data_in(self, test_input): | ||
return test_input['normal'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_out(self, test_output): | ||
return test_output['normal'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_in_nan(self, test_input): | ||
return test_input['nan'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_out_nan(self, test_output): | ||
return test_output['nan'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_in_nan_2(self, test_input): | ||
return test_input['nan_2'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_out_nan_2(self, test_output): | ||
return test_output['nan_2'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_in_missing(self, test_input): | ||
return test_input['missing'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_out_missing(self, test_output): | ||
return test_output['missing'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_in_mask(self, test_input): | ||
return test_input['mask'] | ||
|
||
@pytest.fixture(scope="class") | ||
def data_out_mask(self, test_output): | ||
return test_output['mask'] |
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.
I think we can reduce the number of fixtures here. Unlike in other places where the slicing is non-obvious and creating named fixtures improved readability, here the fixtures are largely just named after the index and variable, which we could access directly from tests. Since these fixtures request all the original test_input
and test_output
, separating them shouldn't give us any significant performance improvements.
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.
Looks good, thanks for that last change! This should be good to merge after #495 to clear the link check failure!
Oh! Also just noting that this should be moved to the next release section of |
PR Summary
Closes #462
PR Checklist
General
closes #XXX
to the PR description where XXX is the number of the issue.docs/release-notes.rst
in a relevant section for the next unreleased release. Possible sections include: Documentation, New Features, Bug Fixes, Internal Changes, Breaking Changes/Deprecatedprecommit
. To set up on your local, runpre-commit install
from the top level of the repository. To manually run pre-commits, usepre-commit run --all-files
and re-add any changed files before committing again and pushing.