From 292ae0ff7640461dd1b311814d794cae00ef4bfd Mon Sep 17 00:00:00 2001 From: Applin Date: Sun, 7 Apr 2024 16:55:19 +0100 Subject: [PATCH] Simplify unit tests to make it easier to read --- quasielasticbayes/test/qldata_test.py | 17 +++++------- quasielasticbayes/test/qlres_test.py | 9 +++---- quasielasticbayes/test/qlse_test.py | 14 +++++----- quasielasticbayes/test/testing.py | 37 +++++++++++++++++++++++++++ quasielasticbayes/testing.py | 10 +++----- 5 files changed, 57 insertions(+), 30 deletions(-) create mode 100644 quasielasticbayes/test/testing.py diff --git a/quasielasticbayes/test/qldata_test.py b/quasielasticbayes/test/qldata_test.py index 58ccbe9..b28691e 100644 --- a/quasielasticbayes/test/qldata_test.py +++ b/quasielasticbayes/test/qldata_test.py @@ -4,10 +4,9 @@ import numpy as np import tempfile -from quasielasticbayes.testing import load_json, add_path +from quasielasticbayes.testing import add_path, load_json, RELATIVE_TOLERANCE_FIT, RELATIVE_TOLERANCE_PROB from quasielasticbayes.QLdata import qldata - DATA_DIR = os.path.join(os.path.dirname(__file__), 'data') @@ -19,13 +18,12 @@ class QLdataTest(unittest.TestCase): """ def test_qlres_minimal_input(self): - # reference inputs - fin = 'qldata_input.json' - with open(os.path.join(DATA_DIR, 'qldata', fin), 'r') as fh: + with open(os.path.join(DATA_DIR, 'qldata', 'qldata_input.json'), 'r') as fh: inputs = load_json(fh) - with tempfile.TemporaryDirectory() as tmp_dir: + with tempfile.TemporaryDirectory() as tmp_dir: inputs['wrks'] = add_path(tmp_dir, inputs['wrks']) + nd, xout, yout, eout, yfit, yprob = qldata(inputs['numb'], inputs['Xv'], inputs['Yv'], @@ -42,16 +40,15 @@ def test_qlres_minimal_input(self): inputs['wrkr'], inputs['lwrk']) # verify - cf = 'qldata_output.json' - with open(os.path.join(DATA_DIR, 'qldata', cf), 'r') as fh: + with open(os.path.join(DATA_DIR, 'qldata', 'qldata_output.json'), 'r') as fh: reference = load_json(fh) self.assertEqual(reference['nd'], nd) np.testing.assert_allclose(reference['xout'], xout) np.testing.assert_allclose(reference['yout'], yout) np.testing.assert_allclose(reference['eout'], eout) - np.testing.assert_allclose(reference['yfit'], yfit, rtol=1e-3) - np.testing.assert_allclose(reference['yprob'], yprob, rtol=1e-3) + np.testing.assert_allclose(reference['yfit'], yfit, rtol=RELATIVE_TOLERANCE_FIT) + np.testing.assert_allclose(reference['yprob'], yprob, rtol=RELATIVE_TOLERANCE_PROB) if __name__ == '__main__': diff --git a/quasielasticbayes/test/qlres_test.py b/quasielasticbayes/test/qlres_test.py index 092e832..ca7a4b6 100644 --- a/quasielasticbayes/test/qlres_test.py +++ b/quasielasticbayes/test/qlres_test.py @@ -5,7 +5,7 @@ import numpy as np import sys -from quasielasticbayes.testing import add_path, load_json +from quasielasticbayes.testing import add_path, load_json, RELATIVE_TOLERANCE_FIT, RELATIVE_TOLERANCE_PROB from quasielasticbayes.QLres import qlres DATA_DIR = os.path.join(os.path.dirname(__file__), 'data') @@ -20,8 +20,7 @@ class QLresTest(unittest.TestCase): @unittest.skipIf(sys.platform == "darwin", "Reading the json reference file causes an unexplained crash.") def test_qlres_minimal_input(self): - # reference inputs - with open(os.path.join(DATA_DIR, 'qlres', 'qlres-input-spec-0.json'), 'r') as fh: + with open(os.path.join(DATA_DIR, 'qldata', 'qlres-input-spec-0.json'), 'r') as fh: inputs = load_json(fh) with tempfile.TemporaryDirectory() as tmp_dir: @@ -41,8 +40,8 @@ def test_qlres_minimal_input(self): np.testing.assert_allclose(reference['xout'], xout) np.testing.assert_allclose(reference['yout'], yout) np.testing.assert_allclose(reference['eout'], eout) - np.testing.assert_allclose(reference['yfit'], yfit, rtol=1e-3) - np.testing.assert_allclose(reference['yprob'], yprob, rtol=1e-2) + np.testing.assert_allclose(reference['yfit'], yfit, rtol=RELATIVE_TOLERANCE_FIT) + np.testing.assert_allclose(reference['yprob'], yprob, rtol=RELATIVE_TOLERANCE_PROB) if __name__ == '__main__': unittest.main() diff --git a/quasielasticbayes/test/qlse_test.py b/quasielasticbayes/test/qlse_test.py index c4eb3f0..2be6306 100644 --- a/quasielasticbayes/test/qlse_test.py +++ b/quasielasticbayes/test/qlse_test.py @@ -4,10 +4,9 @@ import numpy as np import tempfile -from quasielasticbayes.testing import load_json, add_path +from quasielasticbayes.testing import add_path, load_json, RELATIVE_TOLERANCE_FIT, RELATIVE_TOLERANCE_PROB from quasielasticbayes.QLres import qlres - DATA_DIR = os.path.join(os.path.dirname(__file__), 'data') @@ -19,13 +18,12 @@ class QLresTest(unittest.TestCase): """ def test_qlres_minimal_input(self): - # reference inputs - fin = 'qlse_input.json' - with open(os.path.join(DATA_DIR, 'qlse', fin), 'r') as fh: + with open(os.path.join(DATA_DIR, 'qldata', 'qlse_input.json'), 'r') as fh: inputs = load_json(fh) - with tempfile.TemporaryDirectory() as tmp_dir: + with tempfile.TemporaryDirectory() as tmp_dir: inputs['wrks'] = add_path(tmp_dir, inputs['wrks']) + nd, xout, yout, eout, yfit, yprob = qlres(inputs['numb'], inputs['Xv'], inputs['Yv'], @@ -51,8 +49,8 @@ def test_qlres_minimal_input(self): np.testing.assert_allclose(reference['xout'], xout) np.testing.assert_allclose(reference['yout'], yout) np.testing.assert_allclose(reference['eout'], eout) - np.testing.assert_allclose(reference['yfit'], yfit, rtol=1e-3) - np.testing.assert_allclose(reference['yprob'], yprob, rtol=1e-2) + np.testing.assert_allclose(reference['yfit'], yfit, rtol=RELATIVE_TOLERANCE_FIT) + np.testing.assert_allclose(reference['yprob'], yprob, rtol=RELATIVE_TOLERANCE_PROB) if __name__ == '__main__': diff --git a/quasielasticbayes/test/testing.py b/quasielasticbayes/test/testing.py new file mode 100644 index 0000000..5dda1ca --- /dev/null +++ b/quasielasticbayes/test/testing.py @@ -0,0 +1,37 @@ +"""Utility code to help with testing +""" +import base64 +import json +import numpy as np +import os + +RELATIVE_TOLERANCE_FIT=1e-3 +RELATIVE_TOLERANCE_PROB=1e-2 + + +def _json_numpy_obj_hook(dct): + """ + Decodes a previously encoded numpy ndarray + with proper shape and dtype + :param dct: (dict) json encoded ndarray + :return: (ndarray) if input was an encoded ndarray + """ + if isinstance(dct, dict) and '__ndarray__' in dct: + data = base64.b64decode(dct['__ndarray__']) + return np.frombuffer(data, dct['dtype']).reshape(dct['shape']) + return dct + + +def load_json(*args, **kwargs): + """Loads a json-encoded file-like object to a dictionary. + Adds supports for decoding numpy arrays + See json.load. + """ + kwargs.setdefault('object_hook', _json_numpy_obj_hook) + return json.load(*args, **kwargs) + + +def add_path(file_path, file_name): + """Sets the path for a file + """ + return os.path.join(file_path, file_name) diff --git a/quasielasticbayes/testing.py b/quasielasticbayes/testing.py index 2a289cd..5dda1ca 100644 --- a/quasielasticbayes/testing.py +++ b/quasielasticbayes/testing.py @@ -5,6 +5,9 @@ import numpy as np import os +RELATIVE_TOLERANCE_FIT=1e-3 +RELATIVE_TOLERANCE_PROB=1e-2 + def _json_numpy_obj_hook(dct): """ @@ -32,10 +35,3 @@ def add_path(file_path, file_name): """Sets the path for a file """ return os.path.join(file_path, file_name) - - -# def get_qlse_prob(ref): -# if sys.platform == 'win32': -# return ref -# else: -# return [-2.7656994e+04, -1.8887866e+2, 0.0, -5.8251953e-1]