Skip to content

Commit 6b4623b

Browse files
Merge pull request #944 from sadielbartholomew/test-skipping-post3.20
Test skipping based on module (esp. `healpix`) availability
2 parents 9c4a504 + 9c28b79 commit 6b4623b

9 files changed

Lines changed: 116 additions & 65 deletions

.flake8

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ per-file-ignores =
3030
# https://stackoverflow.com/questions/59167405/)
3131
__init__.py: F401
3232
*/__init__.py: F401
33+
# Whole-module test skips (via setUp method) for these cases means exit
34+
# before reach undefined vars where need given module for defining those.
35+
# This is the cleanest way but sets off F821 code en-masse so ignore that.
36+
cf/test/test_HEALPix_utils.py: F821

cf/test/test_Domain.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22
import re
33
import unittest
4+
from importlib.util import find_spec
45

56
import numpy as np
67

@@ -494,6 +495,9 @@ def test_Domain_cyclic_iscyclic(self):
494495
d2.cyclic("X", iscyclic=False)
495496
self.assertTrue(d2.iscyclic("X"))
496497

498+
# Note: here only need healpix for cf under-the-hood code, not in test
499+
# directly, so no need to actually import healpix, just test it is there.
500+
@unittest.skipUnless(find_spec("healpix"), "Requires 'healpix' package.")
497501
def test_Domain_create_healpix(self):
498502
"""Test Domain.create_healpix."""
499503
d = cf.Domain.create_healpix(0)

cf/test/test_Field.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616

1717
import cf
1818

19+
healpix_available = False
20+
# Note: here only need healpix for cf under-the-hood code, not in test
21+
# directly, so no need to actually import healpix, just test it is there.
22+
if find_spec("healpix"):
23+
healpix_available = True
24+
1925
n_tmpfiles = 1
2026
tmpfiles = [
2127
tempfile.mkstemp("_test_Field.nc", dir=os.getcwd())[1]
@@ -3137,6 +3143,7 @@ def test_Field_to_units(self):
31373143
with self.assertRaises(ValueError):
31383144
g.to_units("degC")
31393145

3146+
@unittest.skipUnless(healpix_available, "Requires 'healpix' package.")
31403147
def test_Field_healpix_change_indexing_scheme(self):
31413148
"""Test Field.healpix_change_indexing_scheme."""
31423149
# HEALPix field
@@ -3236,6 +3243,7 @@ def test_Field_healpix_change_indexing_scheme(self):
32363243
with self.assertRaises(ValueError):
32373244
self.f0.healpix_change_indexing_scheme("ring")
32383245

3246+
@unittest.skipUnless(healpix_available, "Requires 'healpix' package.")
32393247
def test_Field_healpix_to_ugrid(self):
32403248
"""Test Field.healpix_to_ugrid."""
32413249
# HEALPix field
@@ -3276,6 +3284,7 @@ def test_Field_healpix_to_ugrid(self):
32763284
with self.assertRaises(ValueError):
32773285
self.f0.healpix_to_ugrid()
32783286

3287+
@unittest.skipUnless(healpix_available, "Requires 'healpix' package.")
32793288
def test_Field_create_latlon_coordinates(self):
32803289
"""Test Field.create_latlon_coordinates."""
32813290
# ------------------------------------------------------------
@@ -3334,6 +3343,7 @@ def test_Field_create_latlon_coordinates(self):
33343343
self.assertTrue(mc[:16].equals(l2.auxiliary_coordinate(c)[:16]))
33353344
self.assertTrue(mc[16:].equals(l1.auxiliary_coordinate(c)[4:]))
33363345

3346+
@unittest.skipUnless(healpix_available, "Requires 'healpix' package.")
33373347
def test_Field_healpix_subspace(self):
33383348
"""Test Field.subspace for HEALPix grids"""
33393349
f = self.f12
@@ -3369,6 +3379,7 @@ def test_Field_healpix_subspace(self):
33693379
np.array_equal(g.coordinate("healpix_index"), [13, 12])
33703380
)
33713381

3382+
@unittest.skipUnless(healpix_available, "Requires 'healpix' package.")
33723383
def test_Field_healpix_decrease_refinement_level(self):
33733384
"""Test Field.healpix_decrease_refinement_level."""
33743385
f = self.f12
@@ -3469,6 +3480,7 @@ def my_mean(a, axis=None):
34693480
with self.assertRaises(ValueError):
34703481
self.f0.healpix_decrease_refinement_level(0, "mean")
34713482

3483+
@unittest.skipUnless(healpix_available, "Requires 'healpix' package.")
34723484
def test_Field_healpix_increase_refinement_level(self):
34733485
"""Test Field.healpix_increase_refinement_level."""
34743486
f = self.f12

cf/test/test_HEALPix_utils.py

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,78 @@
11
import datetime
22
import unittest
33

4-
import healpix
54
import numpy as np
65

76
import cf
87

9-
# Create matching lists of selected nested, ring, nuniq and zuniq
10-
# indices for every refinement level.
11-
indices = [
12-
(r, i, healpix.nest2ring(healpix.order2nside(r), i))
13-
for r in range(30)
14-
for i in (0, 7, (12 * 4**r) - 1)
15-
]
16-
refinement_levels, nested_indices, ring_indices = map(list, zip(*indices))
17-
18-
nuniq_indices = [
19-
i + 4 ** (1 + r) for r, i in zip(refinement_levels, nested_indices)
20-
]
21-
22-
zuniq_indices = [
23-
(2 * i + 1) * 4 ** (29 - r)
24-
for r, i in zip(refinement_levels, nested_indices)
25-
]
8+
healpix_imported = True
9+
try:
10+
import healpix # noqa: F401
11+
except ImportError:
12+
healpix_imported = False
2613

2714

2815
class DataTest(unittest.TestCase):
2916
"""Unit tests for HEALPix utilities."""
3017

18+
def setUp(self):
19+
"""Preparations called immediately before each test method."""
20+
# Skip all if healpix module not available!
21+
if not healpix_imported:
22+
self.skipTest(
23+
"Test module requires 'healpix' package. Install it to run all."
24+
)
25+
26+
# Create matching lists of selected nested, ring, nuniq and zuniq
27+
# indices for every refinement level.
28+
indices = [
29+
(r, i, healpix.nest2ring(healpix.order2nside(r), i))
30+
for r in range(30)
31+
for i in (0, 7, (12 * 4**r) - 1)
32+
]
33+
self.refinement_levels, self.nested_indices, self.ring_indices = map(
34+
list, zip(*indices)
35+
)
36+
37+
self.nuniq_indices = [ # noqa: F841
38+
i + 4 ** (1 + r)
39+
for r, i in zip(self.refinement_levels, self.nested_indices)
40+
]
41+
42+
self.zuniq_indices = [ # noqa: F841
43+
(2 * i + 1) * 4 ** (29 - r)
44+
for r, i in zip(self.refinement_levels, self.nested_indices)
45+
]
46+
3147
def test_HEALPix_uniq2zuniq(self):
3248
"""Test _uniq2zuniq"""
3349
from cf.data.dask_utils_healpix import _uniq2zuniq
3450

3551
self.assertTrue(
36-
np.array_equal(_uniq2zuniq(nuniq_indices), zuniq_indices)
52+
np.array_equal(_uniq2zuniq(self.nuniq_indices), self.zuniq_indices)
3753
)
3854

3955
def test_HEALPix_zuniq2uniq(self):
4056
"""Test _zuniq2uniq"""
4157
from cf.data.dask_utils_healpix import _zuniq2uniq
4258

4359
self.assertTrue(
44-
np.array_equal(_zuniq2uniq(zuniq_indices), nuniq_indices)
60+
np.array_equal(_zuniq2uniq(self.zuniq_indices), self.nuniq_indices)
4561
)
4662

4763
def test_HEALPix_zuniq2pix(self):
4864
"""Test _zuniq2pix"""
4965
from cf.data.dask_utils_healpix import _zuniq2pix
5066

5167
# nested
52-
order, i = _zuniq2pix(zuniq_indices, nest=True)
68+
order, i = _zuniq2pix(self.zuniq_indices, nest=True)
5369

54-
self.assertTrue(np.array_equal(order, refinement_levels))
55-
self.assertTrue(np.array_equal(i, nested_indices))
70+
self.assertTrue(np.array_equal(order, self.refinement_levels))
71+
self.assertTrue(np.array_equal(i, self.nested_indices))
5672

5773
# ring
5874
with self.assertRaises(NotImplementedError):
59-
_zuniq2pix(zuniq_indices, nest=False)
75+
_zuniq2pix(self.zuniq_indices, nest=False)
6076

6177
def test_HEALPix_pix2zuniq(self):
6278
"""Test _pix2zuniq"""
@@ -65,18 +81,18 @@ def test_HEALPix_pix2zuniq(self):
6581
# nested
6682
z = [
6783
_pix2zuniq(r, i, nest=True)
68-
for r, i in zip(refinement_levels, nested_indices)
84+
for r, i in zip(self.refinement_levels, self.nested_indices)
6985
]
7086

71-
self.assertTrue(np.array_equal(z, zuniq_indices))
87+
self.assertTrue(np.array_equal(z, self.zuniq_indices))
7288

7389
# ring
7490
z = [
7591
_pix2zuniq(r, i, nest=False)
76-
for r, i in zip(refinement_levels, ring_indices)
92+
for r, i in zip(self.refinement_levels, self.ring_indices)
7793
]
7894

79-
self.assertTrue(np.array_equal(z, zuniq_indices))
95+
self.assertTrue(np.array_equal(z, self.zuniq_indices))
8096

8197

8298
if __name__ == "__main__":

cf/test/test_RegridOperator.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
class RegridOperatorTest(unittest.TestCase):
2020

2121
def setUp(self):
22-
src = cf.example_field(0)
23-
dst = cf.example_field(1)
24-
self.r = src.regrids(dst, "linear", return_operator=True)
22+
# Skip all if espmy module not available!
23+
if not esmpy_imported:
24+
self.skipTest(
25+
"Test module requires 'esmpy' package. Install it to run all."
26+
)
27+
else:
28+
src = cf.example_field(0)
29+
dst = cf.example_field(1)
30+
self.r = src.regrids(dst, "linear", return_operator=True)
2531

26-
@unittest.skipUnless(esmpy_imported, "Requires esmpy/ESMF package.")
2732
def test_RegridOperator_attributes(self):
2833
self.assertEqual(self.r.coord_sys, "spherical")
2934
self.assertEqual(self.r.method, "linear")
@@ -51,7 +56,6 @@ def test_RegridOperator_attributes(self):
5156
self.assertIsNone(self.r.dst_z)
5257
self.assertFalse(self.r.ln_z)
5358

54-
@unittest.skipUnless(esmpy_imported, "Requires esmpy/ESMF package.")
5559
def test_RegridOperator_copy(self):
5660
self.assertIsInstance(self.r.copy(), self.r.__class__)
5761

cf/test/test_collapse.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import tempfile
66
import unittest
7+
from importlib.util import find_spec
78

89
import numpy as np
910

@@ -825,6 +826,9 @@ def test_Field_collapse_ugrid(self):
825826
# Check the collpsed fields writes
826827
cf.write(f, tmpfile)
827828

829+
# Note: here only need healpix for cf under-the-hood code, not in test
830+
# directly, so no need to actually import healpix, just test it is there.
831+
@unittest.skipUnless(find_spec("healpix"), "Requires 'healpix' package.")
828832
def test_Field_collapse_HEALPix(self):
829833
"""Test HEALPix collapses."""
830834
f0 = cf.example_field(12)

cf/test/test_functions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import platform
55
import sys
66
import unittest
7+
from importlib.util import find_spec
78

89
import dask.array as da
910
import numpy as np
@@ -487,6 +488,9 @@ def test_normalize_slice(self):
487488
with self.assertRaises(IndexError):
488489
cf.normalize_slice(index, 8, cyclic=True)
489490

491+
# Note: here only need healpix for cf under-the-hood code, not in test
492+
# directly, so no need to actually import healpix, just test it is there.
493+
@unittest.skipUnless(find_spec("healpix"), "Requires 'healpix' package.")
490494
def test_locate(self):
491495
"""Test cf.locate"""
492496
# HEALPix

0 commit comments

Comments
 (0)