Skip to content

Commit

Permalink
Remove test timings (#5101)
Browse files Browse the repository at this point in the history
* remove test timings

* whatsnew

* missed a bit

* review action
  • Loading branch information
rcomer authored Dec 14, 2022
1 parent 4a65b9e commit 5555d45
Show file tree
Hide file tree
Showing 12 changed files with 35 additions and 158 deletions.
3 changes: 3 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ This document explains the changes made to Iris for this release
#. `@fnattino`_ changed the order of ``ncgen`` arguments in the command to
create NetCDF files for testing (caused errors on OS X). (:pull:`5105`)

#. `@rcomer`_ removed some old infrastructure that printed test timings.
(:pull:`5101`)


.. comment
Whatsnew author names (@github name) in alphabetical order. Note that,
Expand Down
82 changes: 1 addition & 81 deletions lib/iris/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import collections
from collections.abc import Mapping
import contextlib
import datetime
import difflib
import filecmp
import functools
Expand Down Expand Up @@ -208,7 +207,7 @@ def assert_masked_array_almost_equal(a, b, decimal=6, strict=False):
)


class IrisTest_nometa(unittest.TestCase):
class IrisTest(unittest.TestCase):
"""A subclass of unittest.TestCase which provides Iris specific testing functionality."""

_assertion_counts = collections.defaultdict(int)
Expand Down Expand Up @@ -937,80 +936,6 @@ def assertEqualAndKind(self, value, expected):
)


# An environment variable controls whether test timings are output.
#
# NOTE: to run tests with timing output, nosetests cannot be used.
# At present, that includes not using "python setup.py test"
# The typically best way is like this :
# $ export IRIS_TEST_TIMINGS=1
# $ python -m unittest discover -s iris.tests
# and commonly adding ...
# | grep "TIMING TEST" >iris_test_output.txt
#
_PRINT_TEST_TIMINGS = bool(int(os.environ.get("IRIS_TEST_TIMINGS", 0)))


def _method_path(meth, cls):
return ".".join([cls.__module__, cls.__name__, meth.__name__])


def _testfunction_timing_decorator(fn, cls):
# Function decorator for making a testcase print its execution time.
@functools.wraps(fn)
def inner(*args, **kwargs):
start_time = datetime.datetime.now()
try:
result = fn(*args, **kwargs)
finally:
end_time = datetime.datetime.now()
elapsed_time = (end_time - start_time).total_seconds()
msg = '\n TEST TIMING -- "{}" took : {:12.6f} sec.'
name = _method_path(fn, cls)
print(msg.format(name, elapsed_time))
return result

return inner


def iristest_timing_decorator(cls):
# Class decorator to make all "test_.." functions print execution timings.
if _PRINT_TEST_TIMINGS:
# NOTE: 'dir' scans *all* class properties, including inherited ones.
attr_names = dir(cls)
for attr_name in attr_names:
attr = getattr(cls, attr_name)
if callable(attr) and attr_name.startswith("test"):
attr = _testfunction_timing_decorator(attr, cls)
setattr(cls, attr_name, attr)
return cls


class _TestTimingsMetaclass(type):
# An alternative metaclass for IrisTest subclasses, which makes
# them print execution timings for all the testcases.
# This is equivalent to applying the @iristest_timing_decorator to
# every test class that inherits from IrisTest.
# NOTE: however, it means you *cannot* specify a different metaclass for
# your test class inheriting from IrisTest.
# See below for how to solve that where needed.
def __new__(cls, clsname, base_classes, attrs):
result = type.__new__(cls, clsname, base_classes, attrs)
if _PRINT_TEST_TIMINGS:
result = iristest_timing_decorator(result)
return result


class IrisTest(IrisTest_nometa, metaclass=_TestTimingsMetaclass):
# Derive the 'ordinary' IrisTest from IrisTest_nometa, but add the
# metaclass that enables test timings output.
# This means that all subclasses also get the timing behaviour.
# However, if a different metaclass is *wanted* for an IrisTest subclass,
# this would cause a metaclass conflict.
# Instead, you can inherit from IrisTest_nometa and apply the
# @iristest_timing_decorator explicitly to your new testclass.
pass


get_data_path = IrisTest.get_data_path
get_result_path = IrisTest.get_result_path

Expand All @@ -1019,11 +944,6 @@ class GraphicsTest(graphics.GraphicsTestMixin, IrisTest):
pass


class GraphicsTest_nometa(graphics.GraphicsTestMixin, IrisTest_nometa):
# Graphicstest without the metaclass providing test timings.
pass


def skip_data(fn):
"""
Decorator to choose whether to run tests, based on the availability of
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/tests/graphics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ perceived as it may be a simple pixel shift.

## Testing Strategy

The `iris.tests.IrisTest_nometa.check_graphic` test routine calls out to
The `iris.tests.IrisTest.check_graphic` test routine calls out to
`iris.tests.graphics.check_graphic` which tests against the **acceptable**
result. It does this using an image **hash** comparison technique which allows
us to be robust against minor variations based on underlying library updates.
Expand Down
6 changes: 2 additions & 4 deletions lib/iris/tests/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,8 @@ def override_with_decorated_methods(attr_dict, target_dict, decorator):


@tests.skip_data
@tests.iristest_timing_decorator
class TestPcolorNoBounds(
tests.GraphicsTest_nometa, SliceMixin, metaclass=CheckForWarningsMetaclass
tests.GraphicsTest, SliceMixin, metaclass=CheckForWarningsMetaclass
):
"""
Test the iris.plot.pcolor routine on a cube with coordinates
Expand All @@ -729,9 +728,8 @@ def setUp(self):


@tests.skip_data
@tests.iristest_timing_decorator
class TestPcolormeshNoBounds(
tests.GraphicsTest_nometa, SliceMixin, metaclass=CheckForWarningsMetaclass
tests.GraphicsTest, SliceMixin, metaclass=CheckForWarningsMetaclass
):
"""
Test the iris.plot.pcolormesh routine on a cube with coordinates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcastingDerived(
tests.IrisTest_nometa,
tests.IrisTest,
MathsAddOperationMixin,
CubeArithmeticBroadcastingTestMixin,
):
Expand Down
6 changes: 2 additions & 4 deletions lib/iris/tests/unit/analysis/maths/test__arith__meshcoords.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ def _base_testcube(self):


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcastingWithMesh(
tests.IrisTest_nometa,
tests.IrisTest,
MeshLocationsMixin,
MathsAddOperationMixin,
CubeArithmeticBroadcastingTestMixin,
Expand All @@ -71,9 +70,8 @@ class TestBroadcastingWithMesh(


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcastingWithMeshAndDerived(
tests.IrisTest_nometa,
tests.IrisTest,
MeshLocationsMixin,
MathsAddOperationMixin,
CubeArithmeticBroadcastingTestMixin,
Expand Down
11 changes: 3 additions & 8 deletions lib/iris/tests/unit/analysis/maths/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcasting(
tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin
):
class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin):
@property
def data_op(self):
return operator.add
Expand All @@ -34,8 +31,7 @@ def cube_func(self):
return add


@tests.iristest_timing_decorator
class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin):
class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin):
@property
def data_op(self):
return operator.add
Expand All @@ -57,9 +53,8 @@ def test_reversed_points(self):
add(cube1, cube2)


@tests.iristest_timing_decorator
class TestMaskedConstant(
tests.IrisTest_nometa, CubeArithmeticMaskedConstantTestMixin
tests.IrisTest, CubeArithmeticMaskedConstantTestMixin
):
@property
def data_op(self):
Expand Down
8 changes: 2 additions & 6 deletions lib/iris/tests/unit/analysis/maths/test_divide.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcasting(
tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin
):
class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin):
@property
def data_op(self):
return operator.truediv
Expand All @@ -36,8 +33,7 @@ def cube_func(self):
return divide


@tests.iristest_timing_decorator
class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin):
class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin):
@property
def data_op(self):
return operator.truediv
Expand Down
11 changes: 3 additions & 8 deletions lib/iris/tests/unit/analysis/maths/test_multiply.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcasting(
tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin
):
class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin):
@property
def data_op(self):
return operator.mul
Expand All @@ -34,8 +31,7 @@ def cube_func(self):
return multiply


@tests.iristest_timing_decorator
class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin):
class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin):
@property
def data_op(self):
return operator.mul
Expand All @@ -57,9 +53,8 @@ def test_reversed_points(self):
multiply(cube1, cube2)


@tests.iristest_timing_decorator
class TestMaskedConstant(
tests.IrisTest_nometa, CubeArithmeticMaskedConstantTestMixin
tests.IrisTest, CubeArithmeticMaskedConstantTestMixin
):
@property
def data_op(self):
Expand Down
11 changes: 3 additions & 8 deletions lib/iris/tests/unit/analysis/maths/test_subtract.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@


@tests.skip_data
@tests.iristest_timing_decorator
class TestBroadcasting(
tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin
):
class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin):
@property
def data_op(self):
return operator.sub
Expand All @@ -34,8 +31,7 @@ def cube_func(self):
return subtract


@tests.iristest_timing_decorator
class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin):
class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin):
@property
def data_op(self):
return operator.sub
Expand All @@ -57,9 +53,8 @@ def test_reversed_points(self):
subtract(cube1, cube2)


@tests.iristest_timing_decorator
class TestMaskedConstant(
tests.IrisTest_nometa, CubeArithmeticMaskedConstantTestMixin
tests.IrisTest, CubeArithmeticMaskedConstantTestMixin
):
@property
def data_op(self):
Expand Down
Loading

0 comments on commit 5555d45

Please sign in to comment.