From 9ab7463216114027e53e42ee477e28659317d802 Mon Sep 17 00:00:00 2001 From: Patrick Peglar Date: Tue, 14 Feb 2017 13:10:33 +0000 Subject: [PATCH 1/3] Add test execution timings. --- lib/iris/tests/__init__.py | 80 ++++++++++++++++++- lib/iris/tests/test_plot.py | 9 ++- .../tests/unit/analysis/maths/test_add.py | 9 ++- .../tests/unit/analysis/maths/test_divide.py | 9 ++- .../unit/analysis/maths/test_multiply.py | 9 ++- .../unit/analysis/maths/test_subtract.py | 9 ++- .../grib/message/test_GribMessage.py | 30 ++++--- lib/iris/tests/unit/merge/test_ProtoCube.py | 44 ++++++---- lib/iris/tests/unit/tests/test_IrisTest.py | 8 +- 9 files changed, 165 insertions(+), 42 deletions(-) diff --git a/lib/iris/tests/__init__.py b/lib/iris/tests/__init__.py index f8cfa8c3a0..0d53b0e508 100644 --- a/lib/iris/tests/__init__.py +++ b/lib/iris/tests/__init__.py @@ -37,6 +37,7 @@ import codecs import collections import contextlib +import datetime import difflib import filecmp import functools @@ -219,7 +220,7 @@ def get_data_path(relative_path): return data_path -class IrisTest(unittest.TestCase): +class _IrisTest_nometa(unittest.TestCase): """A subclass of unittest.TestCase which provides Iris specific testing functionality.""" _assertion_counts = collections.defaultdict(int) @@ -853,10 +854,76 @@ def assertArrayShapeStats(self, result, shape, mean, std_dev, rtol=1e-6): self.assertArrayAllClose(result.data.std(), std_dev, rtol=rtol) +# An environment variable controls whether test timings are output. +_PRINT_TEST_TIMINGS = bool(int(os.environ.get('IRIS_TEST_TIMINGS', 0))) + + +def _method_path(meth): + cls = meth.im_class + return '.'.join([cls.__module__, cls.__name__, meth.__name__]) + + +def _test_timings_function_decorator(fn): + # 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) + print(msg.format(name, elapsed_time)) + return result + return inner + + +def _test_timings_class_decorator(cls): + # Class decorator to make all "test_.." functions print execution timings. + if _PRINT_TEST_TIMINGS: + # NOTE: 'dir' hits *all* function 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 = _test_timings_function_decorator(attr) + 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 @_test_timings_class_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 = _test_timings_class_decorator(result) + return result + + +class IrisTest(_IrisTest_nometa): + # 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 + # @_test_timings_class_decorator explicitly to your new testclass. + if _PRINT_TEST_TIMINGS: + __metaclass__ = TestTimingsMetaclass + + get_result_path = IrisTest.get_result_path -class GraphicsTest(IrisTest): +class GraphicsTestMixin(object): # nose directive: dispatch tests concurrently. _multiprocess_can_split_ = True @@ -879,6 +946,15 @@ def tearDown(self): _lock.release() +class GraphicsTest(GraphicsTestMixin, IrisTest): + pass + + +class GraphicsTest_nometa(GraphicsTestMixin, _IrisTest_nometa): + # Graphicstest without the metaclass providing test timings. + pass + + class TestGribMessage(IrisTest): def assertGribMessageContents(self, filename, contents): """ diff --git a/lib/iris/tests/test_plot.py b/lib/iris/tests/test_plot.py index 2b9f38688f..79fc8f570b 100644 --- a/lib/iris/tests/test_plot.py +++ b/lib/iris/tests/test_plot.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2016, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -581,8 +581,10 @@ def override_with_decorated_methods(attr_dict, target_dict, @tests.skip_data +@tests._test_timings_class_decorator class TestPcolorNoBounds(six.with_metaclass(CheckForWarningsMetaclass, - tests.GraphicsTest, SliceMixin)): + tests.GraphicsTest_nometa, + SliceMixin)): """ Test the iris.plot.pcolor routine on a cube with coordinates that have no bounds. @@ -595,8 +597,9 @@ def setUp(self): @tests.skip_data +@tests._test_timings_class_decorator class TestPcolormeshNoBounds(six.with_metaclass(CheckForWarningsMetaclass, - tests.GraphicsTest, + tests.GraphicsTest_nometa, SliceMixin)): """ Test the iris.plot.pcolormesh routine on a cube with coordinates diff --git a/lib/iris/tests/unit/analysis/maths/test_add.py b/lib/iris/tests/unit/analysis/maths/test_add.py index 24569c2bfd..59ee32139c 100644 --- a/lib/iris/tests/unit/analysis/maths/test_add.py +++ b/lib/iris/tests/unit/analysis/maths/test_add.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2016, Met Office +# (C) British Crown Copyright 2014 - 2017, Met Office # # This file is part of Iris. # @@ -31,7 +31,9 @@ @tests.skip_data -class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin): +@tests._test_timings_class_decorator +class TestBroadcasting(tests._IrisTest_nometa, + CubeArithmeticBroadcastingTestMixin): @property def data_op(self): return operator.add @@ -41,7 +43,8 @@ def cube_func(self): return add -class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin): +@tests._test_timings_class_decorator +class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): return operator.add diff --git a/lib/iris/tests/unit/analysis/maths/test_divide.py b/lib/iris/tests/unit/analysis/maths/test_divide.py index d577133af3..4b58ad931c 100644 --- a/lib/iris/tests/unit/analysis/maths/test_divide.py +++ b/lib/iris/tests/unit/analysis/maths/test_divide.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2016, Met Office +# (C) British Crown Copyright 2014 - 2017, Met Office # # This file is part of Iris. # @@ -33,7 +33,9 @@ @tests.skip_data -class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin): +@tests._test_timings_class_decorator +class TestBroadcasting(tests._IrisTest_nometa, + CubeArithmeticBroadcastingTestMixin): @property def data_op(self): try: @@ -46,7 +48,8 @@ def cube_func(self): return divide -class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin): +@tests._test_timings_class_decorator +class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): try: diff --git a/lib/iris/tests/unit/analysis/maths/test_multiply.py b/lib/iris/tests/unit/analysis/maths/test_multiply.py index 8056796d72..ff3fd1cea7 100644 --- a/lib/iris/tests/unit/analysis/maths/test_multiply.py +++ b/lib/iris/tests/unit/analysis/maths/test_multiply.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2016, Met Office +# (C) British Crown Copyright 2014 - 2017, Met Office # # This file is part of Iris. # @@ -31,7 +31,9 @@ @tests.skip_data -class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin): +@tests._test_timings_class_decorator +class TestBroadcasting(tests._IrisTest_nometa, + CubeArithmeticBroadcastingTestMixin): @property def data_op(self): return operator.mul @@ -41,7 +43,8 @@ def cube_func(self): return multiply -class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin): +@tests._test_timings_class_decorator +class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): return operator.mul diff --git a/lib/iris/tests/unit/analysis/maths/test_subtract.py b/lib/iris/tests/unit/analysis/maths/test_subtract.py index 95464c9af2..3c5328cf5e 100644 --- a/lib/iris/tests/unit/analysis/maths/test_subtract.py +++ b/lib/iris/tests/unit/analysis/maths/test_subtract.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2016, Met Office +# (C) British Crown Copyright 2014 - 2017, Met Office # # This file is part of Iris. # @@ -31,7 +31,9 @@ @tests.skip_data -class TestBroadcasting(tests.IrisTest, CubeArithmeticBroadcastingTestMixin): +@tests._test_timings_class_decorator +class TestBroadcasting(tests._IrisTest_nometa, + CubeArithmeticBroadcastingTestMixin): @property def data_op(self): return operator.sub @@ -41,7 +43,8 @@ def cube_func(self): return subtract -class TestMasking(tests.IrisTest, CubeArithmeticMaskingTestMixin): +@tests._test_timings_class_decorator +class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): return operator.sub diff --git a/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py b/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py index 75860c15df..b286fed5ae 100644 --- a/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py +++ b/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2016, Met Office +# (C) British Crown Copyright 2014 - 2017, Met Office # # This file is part of Iris. # @@ -210,28 +210,37 @@ def _example_section_3(grib_definition_template_number, scanning_mode): 'Nj': 3, 'Ni': 4} - -class Test_data__grid_template_0(tests.IrisTest, Mixin_data__grid_template): +@tests._test_timings_class_decorator +class Test_data__grid_template_0(tests._IrisTest_nometa, + Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(0, scanning_mode) -class Test_data__grid_template_1(tests.IrisTest, Mixin_data__grid_template): +@tests._test_timings_class_decorator +class Test_data__grid_template_1(tests._IrisTest_nometa, + Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(1, scanning_mode) -class Test_data__grid_template_5(tests.IrisTest, Mixin_data__grid_template): +@tests._test_timings_class_decorator +class Test_data__grid_template_5(tests._IrisTest_nometa, + Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(5, scanning_mode) -class Test_data__grid_template_12(tests.IrisTest, Mixin_data__grid_template): +@tests._test_timings_class_decorator +class Test_data__grid_template_12(tests._IrisTest_nometa, + Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(12, scanning_mode) -class Test_data__grid_template_30(tests.IrisTest, Mixin_data__grid_template): +@tests._test_timings_class_decorator +class Test_data__grid_template_30(tests._IrisTest_nometa, + Mixin_data__grid_template): def section_3(self, scanning_mode): section_3 = _example_section_3(30, scanning_mode) # Dimensions are 'Nx' + 'Ny' instead of 'Ni' + 'Nj'. @@ -242,13 +251,16 @@ def section_3(self, scanning_mode): return section_3 -class Test_data__grid_template_40_regular(tests.IrisTest, +@tests._test_timings_class_decorator +class Test_data__grid_template_40_regular(tests._IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(40, scanning_mode) -class Test_data__grid_template_90(tests.IrisTest, Mixin_data__grid_template): +@tests._test_timings_class_decorator +class Test_data__grid_template_90(tests._IrisTest_nometa, + Mixin_data__grid_template): def section_3(self, scanning_mode): section_3 = _example_section_3(90, scanning_mode) # Exceptionally, dimensions are 'Nx' + 'Ny' instead of 'Ni' + 'Nj'. diff --git a/lib/iris/tests/unit/merge/test_ProtoCube.py b/lib/iris/tests/unit/merge/test_ProtoCube.py index 79bbbb7b68..19ebac23f5 100644 --- a/lib/iris/tests/unit/merge/test_ProtoCube.py +++ b/lib/iris/tests/unit/merge/test_ProtoCube.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2016, Met Office +# (C) British Crown Copyright 2014 - 2017, Met Office # # This file is part of Iris. # @@ -50,7 +50,7 @@ def cube1(self): return example_cube() @abc.abstractproperty - def cube2(): + def cube2(self): pass @abc.abstractproperty @@ -86,7 +86,8 @@ def test_error(self): self.assertTrue(result) -class Test_register__match(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__match(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return [] @@ -96,7 +97,8 @@ def cube2(self): return example_cube() -class Test_register__standard_name(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__standard_name(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube.standard_name', 'air_temperature', 'air_density'] @@ -108,7 +110,8 @@ def cube2(self): return cube -class Test_register__long_name(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__long_name(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube.long_name', 'screen_air_temp', 'Belling'] @@ -120,7 +123,8 @@ def cube2(self): return cube -class Test_register__var_name(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__var_name(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube.var_name', "'airtemp'", "'airtemp2'"] @@ -132,7 +136,8 @@ def cube2(self): return cube -class Test_register__units(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__units(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube.units', "'K'", "'C'"] @@ -144,7 +149,9 @@ def cube2(self): return cube -class Test_register__attributes_unequal(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__attributes_unequal(Mixin_register, + tests._IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'mint'"] @@ -156,7 +163,9 @@ def cube2(self): return cube -class Test_register__attributes_unequal_array(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__attributes_unequal_array(Mixin_register, + tests._IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'mint'"] @@ -174,7 +183,9 @@ def cube2(self): return cube -class Test_register__attributes_superset(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__attributes_superset(Mixin_register, + tests._IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'stuffed'"] @@ -186,7 +197,9 @@ def cube2(self): return cube -class Test_register__attributes_multi_diff(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__attributes_multi_diff(Mixin_register, + tests._IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'sam'", "'mint'"] @@ -209,7 +222,8 @@ def cube2(self): return cube -class Test_register__cell_method(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__cell_method(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube.cell_methods'] @@ -221,7 +235,8 @@ def cube2(self): return cube -class Test_register__data_shape(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__data_shape(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube.shape', '(2,)', '(3,)'] @@ -233,7 +248,8 @@ def cube2(self): return cube -class Test_register__data_dtype(Mixin_register, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_register__data_dtype(Mixin_register, tests._IrisTest_nometa): @property def fragments(self): return ['cube data dtype', 'int32', 'int8'] diff --git a/lib/iris/tests/unit/tests/test_IrisTest.py b/lib/iris/tests/unit/tests/test_IrisTest.py index 13096f14c2..e315c52670 100644 --- a/lib/iris/tests/unit/tests/test_IrisTest.py +++ b/lib/iris/tests/unit/tests/test_IrisTest.py @@ -80,7 +80,9 @@ def test_different_mask_nonstrict(self): self._func(self.arr1, arr2, strict=False) -class Test_assertMaskedArrayEqual(_MaskedArrayEquality, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_assertMaskedArrayEqual(_MaskedArrayEquality, + tests._IrisTest_nometa): @property def _func(self): return self.assertMaskedArrayEqual @@ -127,7 +129,9 @@ def test_masked_nonmasked_same_emptymask(self): self.assertMaskedArrayEqual(arr1, arr2) -class Test_assertMaskedArrayAlmostEqual(_MaskedArrayEquality, tests.IrisTest): +@tests._test_timings_class_decorator +class Test_assertMaskedArrayAlmostEqual(_MaskedArrayEquality, + tests._IrisTest_nometa): @property def _func(self): return self.assertMaskedArrayAlmostEqual From 90d44653f8954375e667840e18db8a40f3be0c35 Mon Sep 17 00:00:00 2001 From: Patrick Peglar Date: Tue, 14 Feb 2017 15:06:06 +0000 Subject: [PATCH 2/3] Use IrisTest in place of unittest.TestCase everywhere. --- lib/iris/tests/test_cell.py | 6 ++---- lib/iris/tests/test_cf.py | 6 ++---- lib/iris/tests/test_coding_standards.py | 15 +++++++++------ lib/iris/tests/test_coord_api.py | 11 +++++------ lib/iris/tests/test_io_init.py | 5 ++--- lib/iris/tests/test_pp_module.py | 14 +++++++------- lib/iris/tests/test_std_names.py | 9 +++++---- lib/iris/tests/test_util.py | 11 +++++------ .../fileformats/grib/message/test_GribMessage.py | 1 + 9 files changed, 38 insertions(+), 40 deletions(-) diff --git a/lib/iris/tests/test_cell.py b/lib/iris/tests/test_cell.py index 17823cd6b8..8a1a0fbe46 100644 --- a/lib/iris/tests/test_cell.py +++ b/lib/iris/tests/test_cell.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2015, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -22,15 +22,13 @@ # import iris tests first so that some things can be initialised before importing anything else import iris.tests as tests -import unittest - import numpy as np import iris.coords from iris.coords import Cell -class TestCells(unittest.TestCase): +class TestCells(tests.IrisTest): def setUp(self): self.cell1 = iris.coords.Cell(3, [2, 4]) self.cell2 = iris.coords.Cell(360., [350., 370.]) diff --git a/lib/iris/tests/test_cf.py b/lib/iris/tests/test_cf.py index 09fea3cc32..3623367c42 100644 --- a/lib/iris/tests/test_cf.py +++ b/lib/iris/tests/test_cf.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2016, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -25,14 +25,12 @@ # import iris tests first so that some things can be initialised before importing anything else import iris.tests as tests -import unittest - import iris import iris.fileformats.cf as cf from iris.tests import mock -class TestCaching(unittest.TestCase): +class TestCaching(tests.IrisTest): def test_cached(self): # Make sure attribute access to the underlying netCDF4.Variable # is cached. diff --git a/lib/iris/tests/test_coding_standards.py b/lib/iris/tests/test_coding_standards.py index ca2c0b75b4..1985d88206 100644 --- a/lib/iris/tests/test_coding_standards.py +++ b/lib/iris/tests/test_coding_standards.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2013 - 2016, Met Office +# (C) British Crown Copyright 2013 - 2017, Met Office # # This file is part of Iris. # @@ -18,6 +18,10 @@ from __future__ import (absolute_import, division, print_function) from six.moves import (filter, input, map, range, zip) # noqa +# import iris tests first so that some things can be initialised before +# importing anything else +import iris.tests as tests + from datetime import datetime from fnmatch import fnmatch from glob import glob @@ -25,7 +29,6 @@ import os import re import subprocess -import unittest import pep8 @@ -170,7 +173,7 @@ def get_file_results(self): self).get_file_results() -class TestCodeFormat(unittest.TestCase): +class TestCodeFormat(tests.IrisTest): def test_pep8_conformance(self): # # Tests the iris codebase against the "pep8" tool. @@ -218,7 +221,7 @@ def test_pep8_conformance(self): '{}'.format('\n '.join(unexpectedly_good))) -class TestLicenseHeaders(unittest.TestCase): +class TestLicenseHeaders(tests.IrisTest): @staticmethod def years_of_license_in_file(fh): """ @@ -345,7 +348,7 @@ def test_license_headers(self): raise ValueError('There were license header failures. See stdout.') -class TestFutureImports(unittest.TestCase): +class TestFutureImports(tests.IrisTest): excluded = ( '*/iris/fileformats/_old_pp_packing.py', '*/iris/fileformats/_pyke_rules/__init__.py', @@ -406,4 +409,4 @@ def test_future_imports(self): if __name__ == '__main__': - unittest.main() + tests.main() diff --git a/lib/iris/tests/test_coord_api.py b/lib/iris/tests/test_coord_api.py index 5e2811d6ad..cff8c5664f 100644 --- a/lib/iris/tests/test_coord_api.py +++ b/lib/iris/tests/test_coord_api.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2016, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -22,7 +22,6 @@ # import iris tests first so that some things can be initialised before importing anything else import iris.tests as tests -import unittest from xml.dom.minidom import Document import logging @@ -40,7 +39,7 @@ logger = logging.getLogger('tests') -class TestLazy(unittest.TestCase): +class TestLazy(tests.IrisTest): def setUp(self): # Start with a coord with LazyArray points. shape = (3, 4) @@ -107,7 +106,7 @@ def test_lazy_shared_data(self): @tests.skip_data -class TestCoordSlicing(unittest.TestCase): +class TestCoordSlicing(tests.IrisTest): def setUp(self): cube = iris.tests.stock.realistic_4d() self.lat = cube.coord('grid_latitude') @@ -278,7 +277,7 @@ def test_AuxCoord_str(self): ('coord_api', 'str_repr', 'aux_time_str.txt')) -class TestAuxCoordCreation(unittest.TestCase): +class TestAuxCoordCreation(tests.IrisTest): def test_basic(self): a = iris.coords.AuxCoord(np.arange(10), 'air_temperature', units='kelvin') @@ -336,7 +335,7 @@ def test_AuxCoord_fromcoord(self): self.assertIsNot(a.coord_system, b.coord_system) -class TestDimCoordCreation(unittest.TestCase): +class TestDimCoordCreation(tests.IrisTest): def test_basic(self): a = iris.coords.DimCoord(np.arange(10), 'air_temperature', units='kelvin') diff --git a/lib/iris/tests/test_io_init.py b/lib/iris/tests/test_io_init.py index 827ba406b5..e516e1c52e 100644 --- a/lib/iris/tests/test_io_init.py +++ b/lib/iris/tests/test_io_init.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2016, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -25,14 +25,13 @@ # import iris tests first so that some things can be initialised before importing anything else import iris.tests as tests -import unittest from io import BytesIO import iris.fileformats as iff import iris.io -class TestDecodeUri(unittest.TestCase): +class TestDecodeUri(tests.IrisTest): def test_decode_uri(self): tests = { '/data/local/someDir/PP/COLPEX/COLPEX_16a_pj001.pp': ( diff --git a/lib/iris/tests/test_pp_module.py b/lib/iris/tests/test_pp_module.py index 22713c0029..d1b9ea64c0 100644 --- a/lib/iris/tests/test_pp_module.py +++ b/lib/iris/tests/test_pp_module.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2013 - 2015, Met Office +# (C) British Crown Copyright 2013 - 2017, Met Office # # This file is part of Iris. # @@ -98,7 +98,7 @@ def check_pp(self, pp_fields, reference_filename): reference_fh.writelines(test_string) -class TestPPHeaderDerived(unittest.TestCase): +class TestPPHeaderDerived(tests.IrisTest): def setUp(self): self.pp = pp.PPField2() @@ -338,7 +338,7 @@ def test_save_single(self): os.remove(temp_filename) -class TestBitwiseInt(unittest.TestCase): +class TestBitwiseInt(tests.IrisTest): def test_3(self): with mock.patch('warnings.warn') as warn: @@ -447,7 +447,7 @@ def test_128(self): self.assertEqual(t.flag128, 1) -class TestSplittableInt(unittest.TestCase): +class TestSplittableInt(tests.IrisTest): def test_3(self): t = pp.SplittableInt(3) @@ -546,7 +546,7 @@ def test_negative_number(self): self.assertEqual(str(err), 'Negative numbers not supported with splittable integers object') -class TestSplittableIntEquality(unittest.TestCase): +class TestSplittableIntEquality(tests.IrisTest): def test_not_implemented(self): class Terry(object): pass sin = pp.SplittableInt(0) @@ -554,7 +554,7 @@ class Terry(object): pass self.assertIs(sin.__ne__(Terry()), NotImplemented) -class TestPPDataProxyEquality(unittest.TestCase): +class TestPPDataProxyEquality(tests.IrisTest): def test_not_implemented(self): class Terry(object): pass pox = pp.PPDataProxy("john", "michael", "eric", "graham", "brian", @@ -563,7 +563,7 @@ class Terry(object): pass self.assertIs(pox.__ne__(Terry()), NotImplemented) -class TestPPFieldEquality(unittest.TestCase): +class TestPPFieldEquality(tests.IrisTest): def test_not_implemented(self): class Terry(object): pass pox = pp.PPField3() diff --git a/lib/iris/tests/test_std_names.py b/lib/iris/tests/test_std_names.py index e5e203b24e..3fd1d07614 100644 --- a/lib/iris/tests/test_std_names.py +++ b/lib/iris/tests/test_std_names.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2015, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -18,12 +18,13 @@ from __future__ import (absolute_import, division, print_function) from six.moves import (filter, input, map, range, zip) # noqa -import unittest +# import iris tests first so that some things can be initialised before importing anything else +import iris.tests as tests from iris.std_names import STD_NAMES -class TestStandardNames(unittest.TestCase): +class TestStandardNames(tests.IrisTest): """ standard_names.py is a machine generated file which contains a single dictionary called STD_NAMES @@ -50,4 +51,4 @@ def test_standard_names(self): if __name__ == "__main__": - unittest.main() + tests.main() diff --git a/lib/iris/tests/test_util.py b/lib/iris/tests/test_util.py index 5ffa33d30b..97bb4d627d 100644 --- a/lib/iris/tests/test_util.py +++ b/lib/iris/tests/test_util.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2016, Met Office +# (C) British Crown Copyright 2010 - 2017, Met Office # # This file is part of Iris. # @@ -28,7 +28,6 @@ import iris.tests as tests import inspect -import unittest import cf_units import numpy as np @@ -39,7 +38,7 @@ import iris.util -class TestMonotonic(unittest.TestCase): +class TestMonotonic(tests.IrisTest): def assertMonotonic(self, array, direction=None, **kwargs): if direction is not None: mono, dir = iris.util.monotonic(array, return_direction=True, **kwargs) @@ -94,7 +93,7 @@ def test_monotonic_strict(self): self.assertMonotonic(b) -class TestReverse(unittest.TestCase): +class TestReverse(tests.IrisTest): def test_simple(self): a = np.arange(12).reshape(3, 4) np.testing.assert_array_equal(a[::-1], iris.util.reverse(a, 0)) @@ -119,7 +118,7 @@ def test_single(self): self.assertRaises(ValueError, iris.util.reverse, a, [0, -1]) -class TestClipString(unittest.TestCase): +class TestClipString(tests.IrisTest): def setUp(self): self.test_string = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." self.rider = "**^^**$$..--__" # A good chance at being unique and not in the string to be tested! @@ -357,4 +356,4 @@ def test_2d_auxcoord_transpose(self): if __name__ == '__main__': - unittest.main() + tests.main() diff --git a/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py b/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py index b286fed5ae..8f0043cb61 100644 --- a/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py +++ b/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py @@ -210,6 +210,7 @@ def _example_section_3(grib_definition_template_number, scanning_mode): 'Nj': 3, 'Ni': 4} + @tests._test_timings_class_decorator class Test_data__grid_template_0(tests._IrisTest_nometa, Mixin_data__grid_template): From e520f142343b119ed13ac4d2364dfd2f65477ab3 Mon Sep 17 00:00:00 2001 From: Patrick Peglar Date: Tue, 14 Feb 2017 16:36:11 +0000 Subject: [PATCH 3/3] Revise naming + add a usage description. --- lib/iris/tests/__init__.py | 38 +++++++++------ lib/iris/tests/test_plot.py | 4 +- .../tests/unit/analysis/maths/test_add.py | 8 ++-- .../tests/unit/analysis/maths/test_divide.py | 8 ++-- .../unit/analysis/maths/test_multiply.py | 8 ++-- .../unit/analysis/maths/test_subtract.py | 8 ++-- .../grib/message/test_GribMessage.py | 28 +++++------ lib/iris/tests/unit/merge/test_ProtoCube.py | 48 +++++++++---------- lib/iris/tests/unit/tests/test_IrisTest.py | 8 ++-- 9 files changed, 83 insertions(+), 75 deletions(-) diff --git a/lib/iris/tests/__init__.py b/lib/iris/tests/__init__.py index 0d53b0e508..24daca0095 100644 --- a/lib/iris/tests/__init__.py +++ b/lib/iris/tests/__init__.py @@ -220,7 +220,7 @@ def get_data_path(relative_path): return data_path -class _IrisTest_nometa(unittest.TestCase): +class IrisTest_nometa(unittest.TestCase): """A subclass of unittest.TestCase which provides Iris specific testing functionality.""" _assertion_counts = collections.defaultdict(int) @@ -855,6 +855,15 @@ def assertArrayShapeStats(self, result, shape, mean, std_dev, rtol=1e-6): # 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))) @@ -863,7 +872,7 @@ def _method_path(meth): return '.'.join([cls.__module__, cls.__name__, meth.__name__]) -def _test_timings_function_decorator(fn): +def _testfunction_timing_decorator(fn): # Function decorator for making a testcase print its execution time. @functools.wraps(fn) def inner(*args, **kwargs): @@ -880,23 +889,23 @@ def inner(*args, **kwargs): return inner -def _test_timings_class_decorator(cls): +def iristest_timing_decorator(cls): # Class decorator to make all "test_.." functions print execution timings. if _PRINT_TEST_TIMINGS: - # NOTE: 'dir' hits *all* function properties, including inherited ones. + # 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 = _test_timings_function_decorator(attr) + attr = _testfunction_timing_decorator(attr) setattr(cls, attr_name, attr) return cls -class TestTimingsMetaclass(type): +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 @_test_timings_class_decorator to + # 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. @@ -904,20 +913,19 @@ class TestTimingsMetaclass(type): def __new__(cls, clsname, base_classes, attrs): result = type.__new__(cls, clsname, base_classes, attrs) if _PRINT_TEST_TIMINGS: - result = _test_timings_class_decorator(result) + result = iristest_timing_decorator(result) return result -class IrisTest(_IrisTest_nometa): - # Derive the 'ordinary' IrisTest from _IrisTest_nometa, but add the +class IrisTest(six.with_metaclass(_TestTimingsMetaclass, IrisTest_nometa)): + # 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 - # @_test_timings_class_decorator explicitly to your new testclass. - if _PRINT_TEST_TIMINGS: - __metaclass__ = TestTimingsMetaclass + # Instead, you can inherit from IrisTest_nometa and apply the + # @iristest_timing_decorator explicitly to your new testclass. + pass get_result_path = IrisTest.get_result_path @@ -950,7 +958,7 @@ class GraphicsTest(GraphicsTestMixin, IrisTest): pass -class GraphicsTest_nometa(GraphicsTestMixin, _IrisTest_nometa): +class GraphicsTest_nometa(GraphicsTestMixin, IrisTest_nometa): # Graphicstest without the metaclass providing test timings. pass diff --git a/lib/iris/tests/test_plot.py b/lib/iris/tests/test_plot.py index 79fc8f570b..961d5a520e 100644 --- a/lib/iris/tests/test_plot.py +++ b/lib/iris/tests/test_plot.py @@ -581,7 +581,7 @@ def override_with_decorated_methods(attr_dict, target_dict, @tests.skip_data -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class TestPcolorNoBounds(six.with_metaclass(CheckForWarningsMetaclass, tests.GraphicsTest_nometa, SliceMixin)): @@ -597,7 +597,7 @@ def setUp(self): @tests.skip_data -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class TestPcolormeshNoBounds(six.with_metaclass(CheckForWarningsMetaclass, tests.GraphicsTest_nometa, SliceMixin)): diff --git a/lib/iris/tests/unit/analysis/maths/test_add.py b/lib/iris/tests/unit/analysis/maths/test_add.py index 59ee32139c..1e24c3cf18 100644 --- a/lib/iris/tests/unit/analysis/maths/test_add.py +++ b/lib/iris/tests/unit/analysis/maths/test_add.py @@ -31,8 +31,8 @@ @tests.skip_data -@tests._test_timings_class_decorator -class TestBroadcasting(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class TestBroadcasting(tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin): @property def data_op(self): @@ -43,8 +43,8 @@ def cube_func(self): return add -@tests._test_timings_class_decorator -class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): +@tests.iristest_timing_decorator +class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): return operator.add diff --git a/lib/iris/tests/unit/analysis/maths/test_divide.py b/lib/iris/tests/unit/analysis/maths/test_divide.py index 4b58ad931c..9b166787d8 100644 --- a/lib/iris/tests/unit/analysis/maths/test_divide.py +++ b/lib/iris/tests/unit/analysis/maths/test_divide.py @@ -33,8 +33,8 @@ @tests.skip_data -@tests._test_timings_class_decorator -class TestBroadcasting(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class TestBroadcasting(tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin): @property def data_op(self): @@ -48,8 +48,8 @@ def cube_func(self): return divide -@tests._test_timings_class_decorator -class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): +@tests.iristest_timing_decorator +class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): try: diff --git a/lib/iris/tests/unit/analysis/maths/test_multiply.py b/lib/iris/tests/unit/analysis/maths/test_multiply.py index ff3fd1cea7..3bcc401ad1 100644 --- a/lib/iris/tests/unit/analysis/maths/test_multiply.py +++ b/lib/iris/tests/unit/analysis/maths/test_multiply.py @@ -31,8 +31,8 @@ @tests.skip_data -@tests._test_timings_class_decorator -class TestBroadcasting(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class TestBroadcasting(tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin): @property def data_op(self): @@ -43,8 +43,8 @@ def cube_func(self): return multiply -@tests._test_timings_class_decorator -class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): +@tests.iristest_timing_decorator +class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): return operator.mul diff --git a/lib/iris/tests/unit/analysis/maths/test_subtract.py b/lib/iris/tests/unit/analysis/maths/test_subtract.py index 3c5328cf5e..68e5f4de60 100644 --- a/lib/iris/tests/unit/analysis/maths/test_subtract.py +++ b/lib/iris/tests/unit/analysis/maths/test_subtract.py @@ -31,8 +31,8 @@ @tests.skip_data -@tests._test_timings_class_decorator -class TestBroadcasting(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class TestBroadcasting(tests.IrisTest_nometa, CubeArithmeticBroadcastingTestMixin): @property def data_op(self): @@ -43,8 +43,8 @@ def cube_func(self): return subtract -@tests._test_timings_class_decorator -class TestMasking(tests._IrisTest_nometa, CubeArithmeticMaskingTestMixin): +@tests.iristest_timing_decorator +class TestMasking(tests.IrisTest_nometa, CubeArithmeticMaskingTestMixin): @property def data_op(self): return operator.sub diff --git a/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py b/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py index 8f0043cb61..d0dd419ff6 100644 --- a/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py +++ b/lib/iris/tests/unit/fileformats/grib/message/test_GribMessage.py @@ -211,36 +211,36 @@ def _example_section_3(grib_definition_template_number, scanning_mode): 'Ni': 4} -@tests._test_timings_class_decorator -class Test_data__grid_template_0(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_0(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(0, scanning_mode) -@tests._test_timings_class_decorator -class Test_data__grid_template_1(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_1(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(1, scanning_mode) -@tests._test_timings_class_decorator -class Test_data__grid_template_5(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_5(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(5, scanning_mode) -@tests._test_timings_class_decorator -class Test_data__grid_template_12(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_12(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(12, scanning_mode) -@tests._test_timings_class_decorator -class Test_data__grid_template_30(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_30(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): section_3 = _example_section_3(30, scanning_mode) @@ -252,15 +252,15 @@ def section_3(self, scanning_mode): return section_3 -@tests._test_timings_class_decorator -class Test_data__grid_template_40_regular(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_40_regular(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): return _example_section_3(40, scanning_mode) -@tests._test_timings_class_decorator -class Test_data__grid_template_90(tests._IrisTest_nometa, +@tests.iristest_timing_decorator +class Test_data__grid_template_90(tests.IrisTest_nometa, Mixin_data__grid_template): def section_3(self, scanning_mode): section_3 = _example_section_3(90, scanning_mode) diff --git a/lib/iris/tests/unit/merge/test_ProtoCube.py b/lib/iris/tests/unit/merge/test_ProtoCube.py index 19ebac23f5..ac94c3bede 100644 --- a/lib/iris/tests/unit/merge/test_ProtoCube.py +++ b/lib/iris/tests/unit/merge/test_ProtoCube.py @@ -86,8 +86,8 @@ def test_error(self): self.assertTrue(result) -@tests._test_timings_class_decorator -class Test_register__match(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__match(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return [] @@ -97,8 +97,8 @@ def cube2(self): return example_cube() -@tests._test_timings_class_decorator -class Test_register__standard_name(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__standard_name(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube.standard_name', 'air_temperature', 'air_density'] @@ -110,8 +110,8 @@ def cube2(self): return cube -@tests._test_timings_class_decorator -class Test_register__long_name(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__long_name(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube.long_name', 'screen_air_temp', 'Belling'] @@ -123,8 +123,8 @@ def cube2(self): return cube -@tests._test_timings_class_decorator -class Test_register__var_name(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__var_name(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube.var_name', "'airtemp'", "'airtemp2'"] @@ -136,8 +136,8 @@ def cube2(self): return cube -@tests._test_timings_class_decorator -class Test_register__units(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__units(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube.units', "'K'", "'C'"] @@ -149,9 +149,9 @@ def cube2(self): return cube -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class Test_register__attributes_unequal(Mixin_register, - tests._IrisTest_nometa): + tests.IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'mint'"] @@ -163,9 +163,9 @@ def cube2(self): return cube -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class Test_register__attributes_unequal_array(Mixin_register, - tests._IrisTest_nometa): + tests.IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'mint'"] @@ -183,9 +183,9 @@ def cube2(self): return cube -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class Test_register__attributes_superset(Mixin_register, - tests._IrisTest_nometa): + tests.IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'stuffed'"] @@ -197,9 +197,9 @@ def cube2(self): return cube -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class Test_register__attributes_multi_diff(Mixin_register, - tests._IrisTest_nometa): + tests.IrisTest_nometa): @property def fragments(self): return ['cube.attributes', "'sam'", "'mint'"] @@ -222,8 +222,8 @@ def cube2(self): return cube -@tests._test_timings_class_decorator -class Test_register__cell_method(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__cell_method(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube.cell_methods'] @@ -235,8 +235,8 @@ def cube2(self): return cube -@tests._test_timings_class_decorator -class Test_register__data_shape(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__data_shape(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube.shape', '(2,)', '(3,)'] @@ -248,8 +248,8 @@ def cube2(self): return cube -@tests._test_timings_class_decorator -class Test_register__data_dtype(Mixin_register, tests._IrisTest_nometa): +@tests.iristest_timing_decorator +class Test_register__data_dtype(Mixin_register, tests.IrisTest_nometa): @property def fragments(self): return ['cube data dtype', 'int32', 'int8'] diff --git a/lib/iris/tests/unit/tests/test_IrisTest.py b/lib/iris/tests/unit/tests/test_IrisTest.py index e315c52670..9b4436eb74 100644 --- a/lib/iris/tests/unit/tests/test_IrisTest.py +++ b/lib/iris/tests/unit/tests/test_IrisTest.py @@ -80,9 +80,9 @@ def test_different_mask_nonstrict(self): self._func(self.arr1, arr2, strict=False) -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class Test_assertMaskedArrayEqual(_MaskedArrayEquality, - tests._IrisTest_nometa): + tests.IrisTest_nometa): @property def _func(self): return self.assertMaskedArrayEqual @@ -129,9 +129,9 @@ def test_masked_nonmasked_same_emptymask(self): self.assertMaskedArrayEqual(arr1, arr2) -@tests._test_timings_class_decorator +@tests.iristest_timing_decorator class Test_assertMaskedArrayAlmostEqual(_MaskedArrayEquality, - tests._IrisTest_nometa): + tests.IrisTest_nometa): @property def _func(self): return self.assertMaskedArrayAlmostEqual