Skip to content

Commit 3f8a33b

Browse files
authored
Converted integration/root tests to pytest (#6840)
* converted test_climatology * fixed climatology tmp_path * converted test_cube * converted test_Datums * converted test_ff * ruff test_mask_cube * ruff test_netcdf__ * converted test_new_axis * converted test_PartialDateTime * converted test_pickle * converted test_pp * converted test_pp_constrained * converted test_regrid_equ * mostly converted test_regridding * converted test_subset * converted test_traj * review comments (minus one) * fixed cml asserts * refreshed cmls
1 parent cca67e7 commit 3f8a33b

21 files changed

+452
-755
lines changed

lib/iris/tests/_shared_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
#: Basepath for test results.
8282
_RESULT_PATH = os.path.join(os.path.dirname(__file__), "results")
83+
MIN_PICKLE_PROTOCOL = 4
8384

8485

8586
def _assert_masked_array(assertion, a, b, strict, **kwargs):

lib/iris/tests/integration/test_Datums.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,17 @@
44
# See LICENSE in the root of the repository for full licensing details.
55
"""Integration tests for :class:`iris.coord_systems` datum support."""
66

7-
# Import iris.tests first so that some things can be initialised before
8-
# importing anything else.
9-
import iris.tests as tests # isort:skip
10-
117
import cartopy.crs as ccrs
128
import numpy as np
9+
import pytest
1310

1411
from iris.coord_systems import GeogCS, LambertConformal
12+
from iris.tests import _shared_utils
1513

1614

17-
class TestDatumTransformation(tests.IrisTest):
18-
def setUp(self):
15+
class TestDatumTransformation:
16+
@pytest.fixture(autouse=True)
17+
def _setup(self):
1918
self.x_points = np.array([-1.5])
2019
self.y_points = np.array([50.5])
2120

@@ -48,4 +47,4 @@ def test_transform_points_datum(self):
4847
self.start_crs, self.x_points, self.y_points
4948
)
5049

51-
self.assertArrayEqual(expected, actual)
50+
_shared_utils.assert_array_equal(expected, actual)

lib/iris/tests/integration/test_PartialDateTime.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,20 @@
44
# See LICENSE in the root of the repository for full licensing details.
55
"""Integration tests for :class:`iris.time.PartialDateTime`."""
66

7-
# Import iris.tests first so that some things can be initialised before
8-
# importing anything else.
9-
import iris.tests as tests # isort:skip
10-
117
import iris
8+
from iris.tests import _shared_utils
129
from iris.time import PartialDateTime
1310

1411

15-
class Test(tests.IrisTest):
16-
@tests.skip_data
12+
class Test:
13+
@_shared_utils.skip_data
1714
def test_cftime_interface(self):
1815
# The `netcdf4` Python module introduced new calendar classes by v1.2.7
1916
# This test is primarily of this interface, so the
2017
# final test assertion is simple.
21-
filename = tests.get_data_path(("PP", "structured", "small.pp"))
18+
filename = _shared_utils.get_data_path(("PP", "structured", "small.pp"))
2219
cube = iris.load_cube(filename)
2320
pdt = PartialDateTime(year=1992, month=10, day=1, hour=2)
2421
time_constraint = iris.Constraint(time=lambda cell: cell < pdt)
2522
sub_cube = cube.extract(time_constraint)
26-
self.assertEqual(sub_cube.coord("time").points.shape, (1,))
27-
28-
29-
if __name__ == "__main__":
30-
tests.main()
23+
assert sub_cube.coord("time").points.shape == (1,)

lib/iris/tests/integration/test_climatology.py

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,20 @@
44
# See LICENSE in the root of the repository for full licensing details.
55
"""Integration tests for loading and saving netcdf files."""
66

7-
# Import iris.tests first so that some things can be initialised before
8-
# importing anything else.
9-
import iris.tests as tests # isort:skip
10-
117
from os.path import dirname
12-
from os.path import join as path_join
138
from os.path import sep as os_sep
14-
import shutil
15-
import tempfile
9+
10+
import pytest
1611

1712
import iris
18-
from iris.tests import stock
13+
from iris.tests import _shared_utils, stock
1914
from iris.tests.stock.netcdf import ncgen_from_cdl
2015

2116

22-
class TestClimatology(tests.IrisTest):
17+
class TestClimatology:
2318
reference_cdl_path = os_sep.join(
2419
[
25-
dirname(tests.__file__),
20+
dirname(iris.tests.__file__),
2621
(
2722
"results/integration/climatology/TestClimatology/"
2823
"reference_simpledata.cdl"
@@ -51,29 +46,25 @@ def _load_sanitised_cube(filepath):
5146
cube.var_name = None
5247
return cube
5348

54-
@classmethod
55-
def setUpClass(cls):
49+
@pytest.fixture(autouse=True, scope="class")
50+
def _setup(self, request, tmp_path_factory):
5651
# Create a temp directory for temp files.
57-
cls.temp_dir = tempfile.mkdtemp()
58-
cls.path_ref_cdl = path_join(cls.temp_dir, "standard.cdl")
59-
cls.path_ref_nc = path_join(cls.temp_dir, "standard.nc")
52+
cls = request.cls
53+
cls.temp_dir = tmp_path_factory.mktemp("temp")
54+
cls.path_ref_cdl = cls.temp_dir / "standard.cdl"
55+
cls.path_ref_nc = cls.temp_dir / "standard.nc"
6056
# Create reference CDL and netcdf files (with ncgen).
6157
ncgen_from_cdl(
6258
cdl_str=cls._simple_cdl_string(),
6359
cdl_path=cls.path_ref_cdl,
6460
nc_path=cls.path_ref_nc,
6561
)
6662

67-
cls.path_temp_nc = path_join(cls.temp_dir, "tmp.nc")
63+
cls.path_temp_nc = cls.temp_dir / "tmp.nc"
6864

6965
# Create reference cube.
7066
cls.cube_ref = stock.climatology_3d()
7167

72-
@classmethod
73-
def tearDownClass(cls):
74-
# Destroy a temp directory for temp files.
75-
shutil.rmtree(cls.temp_dir)
76-
7768
###############################################################################
7869
# Round-trip tests
7970

@@ -82,14 +73,15 @@ def test_cube_to_cube(self):
8273
# reference cube.
8374
iris.save(self.cube_ref, self.path_temp_nc)
8475
cube = self._load_sanitised_cube(self.path_temp_nc)
85-
self.assertEqual(cube, self.cube_ref)
76+
assert cube == self.cube_ref
8677

87-
def test_file_to_file(self):
78+
def test_file_to_file(self, request):
8879
# Load cube from reference file, save same cube to file, test against
8980
# reference CDL.
9081
cube = iris.load_cube(self.path_ref_nc)
9182
iris.save(cube, self.path_temp_nc)
92-
self.assertCDL(
83+
_shared_utils.assert_CDL(
84+
request,
9385
self.path_temp_nc,
9486
reference_filename=self.reference_cdl_path,
9587
flags="",
@@ -105,8 +97,4 @@ def test_file_to_file(self):
10597
def test_load_from_file(self):
10698
# Create cube from file, test against reference cube.
10799
cube = self._load_sanitised_cube(self.path_ref_nc)
108-
self.assertEqual(cube, self.cube_ref)
109-
110-
111-
if __name__ == "__main__":
112-
tests.main()
100+
assert cube == self.cube_ref

lib/iris/tests/integration/test_cube.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,24 @@
44
# See LICENSE in the root of the repository for full licensing details.
55
"""Integration tests for :class:`iris.cube.Cube`."""
66

7-
# Import iris.tests first so that some things can be initialised before
8-
# importing anything else.
9-
import iris.tests as tests # isort:skip
10-
11-
from unittest import mock
12-
137
import numpy as np
148

159
import iris
1610
from iris._lazy_data import as_lazy_data, is_lazy_data
1711
from iris.analysis import MEAN
1812
from iris.cube import Cube
13+
from iris.tests import _shared_utils
1914

2015

21-
class Test_aggregated_by(tests.IrisTest):
22-
@tests.skip_data
23-
def test_agg_by_aux_coord(self):
24-
problem_test_file = tests.get_data_path(
16+
class Test_aggregated_by:
17+
@_shared_utils.skip_data
18+
def test_agg_by_aux_coord(self, mocker):
19+
problem_test_file = _shared_utils.get_data_path(
2520
("NetCDF", "testing", "small_theta_colpex.nc")
2621
)
2722
# While loading, "turn off" loading small variables as real data.
28-
with mock.patch("iris.fileformats.netcdf.loader._LAZYVAR_MIN_BYTES", 0):
29-
cube = iris.load_cube(problem_test_file, "air_potential_temperature")
30-
23+
mocker.patch("iris.fileformats.netcdf.loader._LAZYVAR_MIN_BYTES", 0)
24+
cube = iris.load_cube(problem_test_file, "air_potential_temperature")
3125
# Test aggregating by aux coord, notably the `forecast_period` aux
3226
# coord on `cube`, whose `_points` attribute is a lazy array.
3327
# This test then ensures that aggregating using `points` instead is
@@ -38,29 +32,25 @@ def test_agg_by_aux_coord(self):
3832
# triggered the load of the coordinate's data.
3933
forecast_period_coord = cube.coord("forecast_period")
4034

41-
self.assertTrue(is_lazy_data(forecast_period_coord.core_points()))
35+
assert is_lazy_data(forecast_period_coord.core_points())
4236

4337
# Now confirm we can aggregate along this coord.
4438
res_cube = cube.aggregated_by("forecast_period", MEAN)
4539
res_cell_methods = res_cube.cell_methods[0]
46-
self.assertEqual(res_cell_methods.coord_names, ("forecast_period",))
47-
self.assertEqual(res_cell_methods.method, "mean")
40+
assert res_cell_methods.coord_names == ("forecast_period",)
41+
assert res_cell_methods.method == "mean"
4842

4943

50-
class TestDataFillValue(tests.IrisTest):
44+
class TestDataFillValue:
5145
def test_real(self):
5246
data = np.ma.masked_array([1, 2, 3], [0, 1, 0], fill_value=10)
5347
cube = Cube(data)
5448
cube.data.fill_value = 20
55-
self.assertEqual(cube.data.fill_value, 20)
49+
assert cube.data.fill_value == 20
5650

5751
def test_lazy(self):
5852
data = np.ma.masked_array([1, 2, 3], [0, 1, 0], fill_value=10)
5953
data = as_lazy_data(data)
6054
cube = Cube(data)
6155
cube.data.fill_value = 20
62-
self.assertEqual(cube.data.fill_value, 20)
63-
64-
65-
if __name__ == "__main__":
66-
tests.main()
56+
assert cube.data.fill_value == 20

lib/iris/tests/integration/test_ff.py

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,35 @@
44
# See LICENSE in the root of the repository for full licensing details.
55
"""Integration tests for loading LBC fieldsfiles."""
66

7-
# Import iris.tests first so that some things can be initialised before
8-
# importing anything else.
9-
import iris.tests as tests # isort:skip
10-
11-
from unittest import mock
12-
137
import numpy as np
8+
import pytest
149

1510
import iris
11+
from iris.tests import _shared_utils
1612

1713

18-
@tests.skip_data
19-
class TestLBC(tests.IrisTest):
20-
def setUp(self):
14+
@_shared_utils.skip_data
15+
class TestLBC:
16+
@pytest.fixture(autouse=True)
17+
def _setup(self):
2118
# Load multiple cubes from a test file.
22-
file_path = tests.get_data_path(("FF", "lbc", "small_lbc"))
19+
file_path = _shared_utils.get_data_path(("FF", "lbc", "small_lbc"))
2320
self.all_cubes = iris.load(file_path)
2421
# Select the second cube for detailed checks (the first is orography).
2522
self.test_cube = self.all_cubes[1]
2623

2724
def test_various_cubes_shapes(self):
2825
# Check a few aspects of the loaded cubes.
2926
cubes = self.all_cubes
30-
self.assertEqual(len(cubes), 10)
31-
self.assertEqual(cubes[0].shape, (16, 16))
32-
self.assertEqual(cubes[1].shape, (2, 4, 16, 16))
33-
self.assertEqual(cubes[3].shape, (2, 5, 16, 16))
27+
assert len(cubes) == 10
28+
assert cubes[0].shape == (16, 16)
29+
assert cubes[1].shape == (2, 4, 16, 16)
30+
assert cubes[3].shape == (2, 5, 16, 16)
3431

3532
def test_cube_coords(self):
3633
# Check coordinates of one cube.
3734
cube = self.test_cube
38-
self.assertEqual(len(cube.coords()), 8)
35+
assert len(cube.coords()) == 8
3936
for name, shape in [
4037
("forecast_reference_time", (1,)),
4138
("time", (2,)),
@@ -47,24 +44,20 @@ def test_cube_coords(self):
4744
("grid_longitude", (16,)),
4845
]:
4946
coords = cube.coords(name)
50-
self.assertEqual(
51-
len(coords),
52-
1,
53-
"expected one {!r} coord, found {}".format(name, len(coords)),
47+
assert len(coords) == 1, "expected one {!r} coord, found {}".format(
48+
name, len(coords)
5449
)
5550
(coord,) = coords
56-
self.assertEqual(
57-
coord.shape,
58-
shape,
51+
assert coord.shape == shape, (
5952
"coord {!r} shape is {} instead of {!r}.".format(
6053
name, coord.shape, shape
61-
),
54+
)
6255
)
6356

6457
def test_cube_data(self):
6558
# Check just a few points of the data.
6659
cube = self.test_cube
67-
self.assertArrayAllClose(
60+
_shared_utils.assert_array_all_close(
6861
cube.data[:, ::2, 6, 13],
6962
np.array([[4.218922, 10.074577], [4.626897, 6.520156]]),
7063
atol=1.0e-6,
@@ -75,22 +68,17 @@ def test_cube_mask(self):
7568
cube = self.test_cube
7669
mask = np.zeros((2, 4, 16, 16), dtype=bool)
7770
mask[:, :, 7:9, 5:11] = True
78-
self.assertArrayEqual(cube.data.mask, mask)
71+
_shared_utils.assert_array_equal(cube.data.mask, mask)
7972

8073

81-
@tests.skip_data
82-
class TestSkipField(tests.IrisTest):
83-
def test_missing_lbrel(self):
84-
infile = tests.get_data_path(("FF", "lbrel_missing"))
85-
with mock.patch("warnings.warn") as warn_fn:
86-
fields = iris.load(infile)
87-
self.assertIn(
88-
"Input field skipped as PPField creation failed : "
89-
"error = 'Unsupported header release number: -32768'",
90-
warn_fn.call_args[0][0],
74+
@_shared_utils.skip_data
75+
class TestSkipField:
76+
def test_missing_lbrel(self, mocker):
77+
warn_msg = (
78+
"Input field skipped as PPField creation failed : .*"
79+
"error = 'Unsupported header release number: -32768'"
9180
)
92-
self.assertEqual(len(fields), 2)
93-
94-
95-
if __name__ == "__main__":
96-
tests.main()
81+
infile = _shared_utils.get_data_path(("FF", "lbrel_missing"))
82+
with pytest.warns(match=warn_msg):
83+
fields = iris.load(infile)
84+
assert len(fields) == 2

0 commit comments

Comments
 (0)