From ab1416927d0f8309c0bb1645c31a63f1cf1e6847 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Mon, 11 Mar 2024 18:03:03 +0000 Subject: [PATCH 1/2] Rewrite result_path. --- lib/iris/tests/_shared_utils.py | 61 ++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/lib/iris/tests/_shared_utils.py b/lib/iris/tests/_shared_utils.py index af2a1b03ab..6a4f15c9b1 100644 --- a/lib/iris/tests/_shared_utils.py +++ b/lib/iris/tests/_shared_utils.py @@ -11,8 +11,7 @@ import filecmp import functools import gzip - -# import inspect +import inspect import json import math import os @@ -208,9 +207,8 @@ def get_result_path(relative_path): return os.path.abspath(os.path.join(_RESULT_PATH, relative_path)) -def result_path(self, basename=None, ext=""): - """Return the full path to a test result, generated from the \ - calling file, class and, optionally, method. +def result_path(basename=None, ext=""): + """Generate the path to a test result; from the calling file, class, method. Parameters ---------- @@ -220,8 +218,41 @@ def result_path(self, basename=None, ext=""): Appended file extension. """ - return None - # todo: complete this! + if __package__ != "iris.tests": + # Would normally use assert, but this means something to PyTest. + message = "result_path() must be in the iris.tests root to function." + raise RuntimeError(message) + tests_root = Path(__file__).parent + + if ext and not ext.startswith("."): + ext = f".{ext}" + + frame = inspect.currentframe() + caller_frame = inspect.getouterframes(frame)[1] + caller_path = Path(caller_frame.filename) + caller_instance = caller_frame.frame.f_locals.get("self") + caller_func = caller_frame.function + + # Generate the directory name from the calling file name. + output_path = get_result_path("") / caller_path.relative_to(tests_root) + output_path = output_path.with_suffix("") + output_path = output_path.with_name(output_path.name.replace("test_", "")) + + # Add a class subdirectory if called from a class. + if caller_instance is not None: + output_class = caller_instance.__class__.__name__.replace("Test", "") + output_path = output_path / output_class + + # Generate the file name from the calling function name. + if basename is not None: + output_func = basename + else: + output_func = caller_func.replace("test_", "") + output_path = output_path / output_func + + output_path = output_path.with_suffix(ext) + + return str(output_path) def assert_CML_approx_data(cubes, reference_filename=None, **kwargs): @@ -818,7 +849,9 @@ class MyDataTests(tests.IrisTest): or os.environ.get("IRIS_TEST_NO_DATA") ) - skip = pytest.skipIf(condition=no_data, reason="Test(s) require external data.") + skip = pytest.mark.skipif( + condition=no_data, reason="Test(s) require external data." + ) return skip(fn) @@ -833,31 +866,33 @@ class MyGeoTiffTests(test.IrisTest): ... """ - skip = pytest.skipIf(condition=not GDAL_AVAILABLE, reason="Test requires 'gdal'.") + skip = pytest.mark.skipif( + condition=not GDAL_AVAILABLE, reason="Test requires 'gdal'." + ) return skip(fn) skip_plot = graphics.skip_plot -skip_sample_data = pytest.skipIf( +skip_sample_data = pytest.mark.skipif( not SAMPLE_DATA_AVAILABLE, ('Test(s) require "iris-sample-data", ' "which is not available."), ) -skip_nc_time_axis = pytest.skipIf( +skip_nc_time_axis = pytest.mark.skipif( not NC_TIME_AXIS_AVAILABLE, 'Test(s) require "nc_time_axis", which is not available.', ) -skip_inet = pytest.skipIf( +skip_inet = pytest.mark.skipif( not INET_AVAILABLE, ('Test(s) require an "internet connection", ' "which is not available."), ) -skip_stratify = pytest.skipIf( +skip_stratify = pytest.mark.skipif( not STRATIFY_AVAILABLE, 'Test(s) require "python-stratify", which is not available.', ) From e999c78c3d14f2e138c4f62969721c79def0415a Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Tue, 12 Mar 2024 09:38:58 +0000 Subject: [PATCH 2/2] Review comments. --- lib/iris/tests/_shared_utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/iris/tests/_shared_utils.py b/lib/iris/tests/_shared_utils.py index 6a4f15c9b1..cf03a77495 100644 --- a/lib/iris/tests/_shared_utils.py +++ b/lib/iris/tests/_shared_utils.py @@ -219,6 +219,8 @@ def result_path(basename=None, ext=""): """ if __package__ != "iris.tests": + # Relying on this being the location so that we can derive the full + # path of the tests root. # Would normally use assert, but this means something to PyTest. message = "result_path() must be in the iris.tests root to function." raise RuntimeError(message) @@ -246,6 +248,8 @@ def result_path(basename=None, ext=""): # Generate the file name from the calling function name. if basename is not None: output_func = basename + elif caller_func == "": + output_func = "" else: output_func = caller_func.replace("test_", "") output_path = output_path / output_func