Skip to content

Replace nose with pytest #4734

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

Merged
merged 3 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions lib/iris/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1218,10 +1218,6 @@ class IrisTest(IrisTest_nometa, metaclass=_TestTimingsMetaclass):


class GraphicsTestMixin:

# nose directive: dispatch tests concurrently.
_multiprocess_can_split_ = True

def setUp(self):
# Acquire threading non re-entrant blocking lock to ensure
# thread-safe plotting.
Expand Down
47 changes: 17 additions & 30 deletions lib/iris/tests/runner/_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@

# Because this file is imported by setup.py, there may be additional runtime
# imports later in the file.
import multiprocessing
import os
import sys


# NOTE: Do not inherit from object as distutils does not like it.
class TestRunner:
"""Run the Iris tests under nose and multiprocessor for performance"""
"""Run the Iris tests under pytest and pytest-xdist for performance"""

description = (
"Run tests under nose and multiprocessor for performance. "
"Run tests under pytest and pytest-xdist for performance. "
"Default behaviour is to run all non-gallery tests. "
"Specifying one or more test flags will run *only* those "
"tests."
Expand Down Expand Up @@ -70,8 +69,8 @@ def initialize_options(self):
self.create_missing = False

def finalize_options(self):
# These enviroment variables will be propagated to all the
# processes that nose.run creates.
# These environment variables will be propagated to all the
# processes that pytest-xdist creates.
if self.no_data:
print("Running tests in no-data mode...")
import iris.config
Expand All @@ -95,25 +94,23 @@ def finalize_options(self):
if self.stop:
print("Stopping tests after the first error or failure")
if self.num_processors is None:
# Choose a magic number that works reasonably well for the default
# number of processes.
self.num_processors = (multiprocessing.cpu_count() + 1) // 4 + 1
self.num_processors = "auto"
else:
self.num_processors = int(self.num_processors)

def run(self):
import nose
import pytest

if hasattr(self, "distribution") and self.distribution.tests_require:
self.distribution.fetch_build_eggs(self.distribution.tests_require)

tests = []
if self.system_tests:
tests.append("iris.tests.system_test")
tests.append("lib/iris/tests/system_test.py")
if self.default_tests:
tests.append("iris.tests")
tests.append("lib/iris/tests")
if self.coding_tests:
tests.append("iris.tests.test_coding_standards")
tests.append("lib/iris/tests/test_coding_standards.py")
if self.gallery_tests:
import iris.config

Expand All @@ -129,35 +126,25 @@ def run(self):
"WARNING: Gallery path %s does not exist." % (gallery_path)
)
if not tests:
tests.append("iris.tests")

regexp_pat = r"--match=^([Tt]est(?![Mm]ixin)|[Ss]ystem)"

n_processors = max(self.num_processors, 1)
tests.append("lib/iris/tests")

args = [
"",
None,
"--processes=%s" % n_processors,
"--verbosity=2",
regexp_pat,
"--process-timeout=180",
"-v",
f"-n={self.num_processors}",
]

if self.stop:
args.append("--stop")
args.append("-x")

result = True
for test in tests:
args[1] = test
args[0] = test
print()
print(
"Running test discovery on %s with %s processors."
% (test, n_processors)
f"Running test discovery on {test} with {self.num_processors} processors."
)
# run the tests at module level i.e. my_module.tests
# - test must start with test/Test and must not contain the
# word Mixin.
result &= nose.run(argv=args)
retcode = pytest.main(args=args)
result &= retcode.value == 0
if result is False:
exit(1)
2 changes: 1 addition & 1 deletion lib/iris/tests/system_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import iris


class SystemInitialTest(tests.IrisTest):
class TestSystemInitial(tests.IrisTest):
def test_supported_filetypes(self):
nx, ny = 60, 60
data = np.arange(nx * ny, dtype=">f4").reshape(nx, ny)
Expand Down
18 changes: 9 additions & 9 deletions lib/iris/tests/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_cell_different_bounds(self):
self.assertEqual(len(sub_list), 0)


class TestMixin:
class ConstraintMixin:
"""
Mix-in class for attributes & utilities common to the "normal" and "strict" test cases.

Expand Down Expand Up @@ -134,7 +134,7 @@ def setUp(self):
self.lat_gt_45 = iris.Constraint(latitude=lambda c: c > 45)


class RelaxedConstraintMixin(TestMixin):
class RelaxedConstraintMixin(ConstraintMixin):
@staticmethod
def fixup_sigma_to_be_aux(cubes):
# XXX Fix the cubes such that the sigma coordinate is always an AuxCoord. Pending gh issue #18
Expand Down Expand Up @@ -296,11 +296,11 @@ def load_match(self, files, constraints):


@tests.skip_data
class TestCubeExtract__names(TestMixin, tests.IrisTest):
class TestCubeExtract__names(ConstraintMixin, tests.IrisTest):
def setUp(self):
fname = iris.sample_data_path("atlantic_profiles.nc")
self.cubes = iris.load(fname)
TestMixin.setUp(self)
ConstraintMixin.setUp(self)
cube = iris.load_cube(self.theta_path)
# Expected names...
self.standard_name = "air_potential_temperature"
Expand Down Expand Up @@ -353,11 +353,11 @@ def test_unknown(self):


@tests.skip_data
class TestCubeExtract__name_constraint(TestMixin, tests.IrisTest):
class TestCubeExtract__name_constraint(ConstraintMixin, tests.IrisTest):
def setUp(self):
fname = iris.sample_data_path("atlantic_profiles.nc")
self.cubes = iris.load(fname)
TestMixin.setUp(self)
ConstraintMixin.setUp(self)
cube = iris.load_cube(self.theta_path)
# Expected names...
self.standard_name = "air_potential_temperature"
Expand Down Expand Up @@ -579,9 +579,9 @@ def test_unknown(self):


@tests.skip_data
class TestCubeExtract(TestMixin, tests.IrisTest):
class TestCubeExtract(ConstraintMixin, tests.IrisTest):
def setUp(self):
TestMixin.setUp(self)
ConstraintMixin.setUp(self)
self.cube = iris.load_cube(self.theta_path)

def test_attribute_constraint(self):
Expand Down Expand Up @@ -644,7 +644,7 @@ def test_non_existent_coordinate(self):


@tests.skip_data
class TestConstraints(TestMixin, tests.IrisTest):
class TestConstraints(ConstraintMixin, tests.IrisTest):
def test_constraint_expressions(self):
rt = repr(self.theta)
rl10 = repr(self.level_10)
Expand Down
13 changes: 11 additions & 2 deletions requirements/ci/nox.lock/py38-linux-64.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Generated by conda-lock.
# platform: linux-64
# input_hash: b230293335ef7a307da7d676affe5b26d439c6c026b2db6f0a4331900ea33f02
# input_hash: 41315fe97a24272298c496dfe62676b5ef3ce15bd4750681498f42fd4e9ea036
@EXPLICIT
https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81
https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2021.10.8-ha878542_0.tar.bz2#575611b8a84f45960e87722eeb51fa26
Expand Down Expand Up @@ -112,27 +112,30 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.8.13-h582c2e5_0_cpython
https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h7f98852_1.tar.bz2#536cc5db4d0a3ba0630541aec064b5e4
https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.10-h7f98852_1003.tar.bz2#f59c1242cc1dd93e72c2ee2b360979eb
https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.12-py_0.tar.bz2#2489a97287f90176ecdc3ca982b4b0a0
https://conda.anaconda.org/conda-forge/noarch/attrs-21.4.0-pyhd8ed1ab_0.tar.bz2#f70280205d7044c8b8358c8de3190e5d
https://conda.anaconda.org/conda-forge/noarch/cfgv-3.3.1-pyhd8ed1ab_0.tar.bz2#ebb5f5f7dc4f1a3780ef7ea7738db08c
https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-2.0.12-pyhd8ed1ab_0.tar.bz2#1f5b32dabae0f1893ae3283dac7f799e
https://conda.anaconda.org/conda-forge/noarch/cloudpickle-2.0.0-pyhd8ed1ab_0.tar.bz2#3a8fc8b627d5fb6af827e126a10a86c6
https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.4-pyh9f0ad1d_0.tar.bz2#c08b4c1326b880ed44f3ffb04803332f
https://conda.anaconda.org/conda-forge/linux-64/curl-7.83.0-h7bff187_0.tar.bz2#81e39fb3ae82be7e8d2dd7046f393588
https://conda.anaconda.org/conda-forge/noarch/cycler-0.11.0-pyhd8ed1ab_0.tar.bz2#a50559fad0affdbb33729a68669ca1cb
https://conda.anaconda.org/conda-forge/noarch/distlib-0.3.4-pyhd8ed1ab_0.tar.bz2#7b50d840543d9cdae100e91582c33035
https://conda.anaconda.org/conda-forge/noarch/execnet-1.9.0-pyhd8ed1ab_0.tar.bz2#0e521f7a5e60d508b121d38b04874fb2
https://conda.anaconda.org/conda-forge/noarch/filelock-3.6.0-pyhd8ed1ab_0.tar.bz2#6e03ca6c7b47a4152a2b12c6eee3bd32
https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.0-h8e229c2_0.tar.bz2#f314f79031fec74adc9bff50fbaffd89
https://conda.anaconda.org/conda-forge/noarch/fsspec-2022.3.0-pyhd8ed1ab_0.tar.bz2#960b78685ccbedb992886fc4ce37bf6e
https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.20.2-hcf0ee16_0.tar.bz2#79d7fca692d224dc29a72bda90f78a7b
https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.12.1-mpi_mpich_h08b82f9_4.tar.bz2#975d5635b158c1b3c5c795f9d0a430a1
https://conda.anaconda.org/conda-forge/noarch/idna-3.3-pyhd8ed1ab_0.tar.bz2#40b50b8b030f5f2f22085c062ed013dd
https://conda.anaconda.org/conda-forge/noarch/imagesize-1.3.0-pyhd8ed1ab_0.tar.bz2#be807e7606fff9436e5e700f6bffb7c6
https://conda.anaconda.org/conda-forge/noarch/iniconfig-1.1.1-pyh9f0ad1d_0.tar.bz2#39161f81cc5e5ca45b8226fbb06c6905
https://conda.anaconda.org/conda-forge/noarch/iris-sample-data-2.4.0-pyhd8ed1ab_0.tar.bz2#18ee9c07cf945a33f92caf1ee3d23ad9
https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2#91e27ef3d05cc772ce627e51cff111c4
https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19
https://conda.anaconda.org/conda-forge/noarch/nose-1.3.7-py_1006.tar.bz2#382019d5f8e9362ef6f60a8d4e7bce8f
https://conda.anaconda.org/conda-forge/noarch/olefile-0.46-pyh9f0ad1d_1.tar.bz2#0b2e68acc8c78c8cc392b90983481f58
https://conda.anaconda.org/conda-forge/noarch/platformdirs-2.5.1-pyhd8ed1ab_0.tar.bz2#d5df87964a39f67c46a5448f4e78d9b6
https://conda.anaconda.org/conda-forge/linux-64/proj-9.0.0-h93bde94_1.tar.bz2#cf908994f24ea526afc59f295d5b07c1
https://conda.anaconda.org/conda-forge/noarch/py-1.11.0-pyh6c4a22f_0.tar.bz2#b4613d7e7a493916d867842a6a148054
https://conda.anaconda.org/conda-forge/noarch/pycparser-2.21-pyhd8ed1ab_0.tar.bz2#076becd9e05608f8dc72757d5f3a91ff
https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.0.8-pyhd8ed1ab_0.tar.bz2#7f5738c49fdccd0fc755bfd25a5ea66c
https://conda.anaconda.org/conda-forge/noarch/pyshp-2.3.0-pyhd8ed1ab_0.tar.bz2#0158f62cae46ad1fb77c522c4e7ecc90
Expand All @@ -148,6 +151,7 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-py_0.ta
https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.3-py_0.tar.bz2#d01180388e6d1838c3e1ad029590aa7a
https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.5-pyhd8ed1ab_2.tar.bz2#9ff55a0901cf952f05c654394de76bf7
https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2#f832c45a477c78bebd107098db465095
https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2#5844808ffab9ebdb694585b50ba02a96
https://conda.anaconda.org/conda-forge/noarch/toolz-0.11.2-pyhd8ed1ab_0.tar.bz2#f348d1590550371edfac5ed3c1d44f7e
https://conda.anaconda.org/conda-forge/noarch/wheel-0.37.1-pyhd8ed1ab_0.tar.bz2#1ca02aaf78d9c70d9a81a3bed5752022
https://conda.anaconda.org/conda-forge/noarch/zipp-3.8.0-pyhd8ed1ab_0.tar.bz2#050b94cf4a8c760656e51d2d44e4632c
Expand All @@ -168,7 +172,9 @@ https://conda.anaconda.org/conda-forge/linux-64/numpy-1.22.3-py38h99721a1_2.tar.
https://conda.anaconda.org/conda-forge/noarch/packaging-21.3-pyhd8ed1ab_0.tar.bz2#71f1ab2de48613876becddd496371c85
https://conda.anaconda.org/conda-forge/noarch/partd-1.2.0-pyhd8ed1ab_0.tar.bz2#0c32f563d7f22e3a34c95cad8cc95651
https://conda.anaconda.org/conda-forge/linux-64/pillow-6.2.2-py38h9776b28_0.tar.bz2#bd527d652ba06fb2aae61640bcf7c435
https://conda.anaconda.org/conda-forge/linux-64/pluggy-1.0.0-py38h578d9bd_3.tar.bz2#6ce4ce3d4490a56eb33b52c179609193
https://conda.anaconda.org/conda-forge/noarch/pockets-0.9.1-py_0.tar.bz2#1b52f0c42e8077e5a33e00fe72269364
https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.0-py38h0a891b7_1.tar.bz2#92045570d1da14b3f90621c54f8afb12
https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-4.19.18-py38h709712a_8.tar.bz2#11b72f5b1cc15427c89232321172a0bc
https://conda.anaconda.org/conda-forge/linux-64/pysocks-1.7.1-py38h578d9bd_5.tar.bz2#11113c7e50bb81f30762fe8325f305e1
https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.8.2-pyhd8ed1ab_0.tar.bz2#dd999d1cc9f79e67dbb855c8924c7984
Expand All @@ -194,6 +200,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-22.0.4-pyhd8ed1ab_0.tar.bz2#b1
https://conda.anaconda.org/conda-forge/noarch/pygments-2.12.0-pyhd8ed1ab_0.tar.bz2#cb27e2ded147e5bcc7eafc1c6d343cb3
https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.3.1-py38h5b5ac8f_0.tar.bz2#5d91e0c583547eb69345c3acf4d753ee
https://conda.anaconda.org/conda-forge/linux-64/pyqt-impl-5.12.3-py38h0ffb2e6_8.tar.bz2#acfc7625a212c27f7decdca86fdb2aba
https://conda.anaconda.org/conda-forge/linux-64/pytest-7.1.2-py38h578d9bd_0.tar.bz2#626d2b8f96c8c3d20198e6bd84d1cfb7
https://conda.anaconda.org/conda-forge/linux-64/python-stratify-0.2.post0-py38h71d37f0_2.tar.bz2#cdef2f7b0e263e338016da4b77ae4c0b
https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.3.0-py38h71d37f0_1.tar.bz2#704f1776af689de568514b0ff9dd0fbe
https://conda.anaconda.org/conda-forge/linux-64/scipy-1.8.0-py38h56a6a73_1.tar.bz2#86073932d9e675c5929376f6f8b79b97
Expand All @@ -210,13 +217,15 @@ https://conda.anaconda.org/conda-forge/linux-64/pango-1.50.7-hbd2fdc8_0.tar.bz2#
https://conda.anaconda.org/conda-forge/noarch/pyopenssl-22.0.0-pyhd8ed1ab_0.tar.bz2#1d7e241dfaf5475e893d4b824bb71b44
https://conda.anaconda.org/conda-forge/linux-64/pyqtchart-5.12-py38h7400c14_8.tar.bz2#78a2a6cb4ef31f997c1bee8223a9e579
https://conda.anaconda.org/conda-forge/linux-64/pyqtwebengine-5.12.1-py38h7400c14_8.tar.bz2#857894ea9c5e53c962c3a0932efa71ea
https://conda.anaconda.org/conda-forge/noarch/pytest-forked-1.4.0-pyhd8ed1ab_0.tar.bz2#95286e05a617de9ebfe3246cecbfb72f
https://conda.anaconda.org/conda-forge/linux-64/cartopy-0.20.2-py38h51d8e34_4.tar.bz2#9f23c80d08456c02ab284f974719b013
https://conda.anaconda.org/conda-forge/linux-64/esmpy-8.2.0-mpi_mpich_py38h9147699_101.tar.bz2#5a9de1dec507b6614150a77d1aabf257
https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h90689f9_2.tar.bz2#957a0255ab58aaf394a91725d73ab422
https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.52.5-h0a9e6e8_3.tar.bz2#a08562889b985d021550e22443cf0fce
https://conda.anaconda.org/conda-forge/noarch/nc-time-axis-1.4.1-pyhd8ed1ab_0.tar.bz2#281b58948bf60a2582de9e548bcc5369
https://conda.anaconda.org/conda-forge/linux-64/pre-commit-2.19.0-py38h578d9bd_0.tar.bz2#aa6a241a741c27c9560fd3cebb3f43ce
https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.12.3-py38h578d9bd_8.tar.bz2#88368a5889f31dff922a2d57bbfc3f5b
https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-2.5.0-pyhd8ed1ab_0.tar.bz2#1fdd1f3baccf0deb647385c677a1a48e
https://conda.anaconda.org/conda-forge/noarch/urllib3-1.26.9-pyhd8ed1ab_0.tar.bz2#0ea179ee251aa7100807c35bc0252693
https://conda.anaconda.org/conda-forge/linux-64/graphviz-3.0.0-h5abf519_1.tar.bz2#fcaf13b2713335ff871ba551d5bda679
https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.5.2-py38h578d9bd_0.tar.bz2#b15039e7f67b5f91c35f9b6d27c2775c
Expand Down
4 changes: 3 additions & 1 deletion requirements/ci/py38.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ dependencies:
# Test dependencies.
- filelock
- imagehash >=4.0
- nose
- pillow <7
- pre-commit
- psutil
- pytest
- pytest-xdist
- requests

# Documentation dependencies.
Expand Down
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,11 @@ docs =
test =
filelock
imagehash>=4.0
nose
pillow<7
pre-commit
requests
pytest
pytest-xdist
all =
mo_pack
nc-time-axis>=1.4
Expand Down