Source code for helpers.testing

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Feb  9 14:41:43 2024

Helpers module for testing utilities
"""
import os
import json
import warnings
import numpy as np


[docs] class DataChecker: """ Object allowing to quickly generate and check generated data from scripts. Here is an example of use for one given script: >>> from pySDC.helpers.testing import DataChecker >>> >>> data = DataChecker(__file__) >>> # ... some computations ... >>> data.storeAndCheck('solution', solution) >>> # ... some other computations ... >>> data.storeAndCheck('errors', errors) >>> # ... ploting some figures >>> data.writeToJSON() # end of script The `storeAndCheck` method use a unique key as first argument, and the data as second argument, into list format. Calling this method will store the data into a cache variable, and compare with reference data stored in `_dataRef.json` (if it exists, see below ...). Finally, the `writeToJSON` method saves the cache variable into a json file `_data.json`. When there is no `_dataRef.json` in the script directory, executing the script output some warning telling that there is no reference data to compare with. To remove those warnings (and properly test data), just rename the `_data.json` into `_dataRef.json`. Then re-running the script will then compare the newly generated data with the reference data stored into `_dataRef.json`, and raise an error if there is some differences. Important --------- - using the `__file__` built-in variable is necessary to save data in the script directory, independently of the working directory. - several script in the same directory can use the DataChecker, which implies that the key provided to `storeAndCheck` must be unique across all directory scripts. If not, the same key from previous directory will simply be overwritten in the cached variable and the `_data.ref` file. """ def __init__(self, filePath): path = '/' + os.path.join(*filePath.split('/')[:-1]) self._data = {} # cache for data self._dataRef = None # cache for reference data self._dataFile = os.path.join(path, '_data.json') self._dataRefFile = os.path.join(path, '_dataRef.json')
[docs] def storeAndCheck(self, key, data, rtol=1e-5, atol=1e-8): """ Store data into cache, and check with eventual reference data Parameters ---------- key : str Unique key (project wide) for the data. data : list or array-like The data that has to be stored. rtol : float Relative tolerance atol : float Absolute tolerance """ self._data[key] = list(data) if self._dataRef is None: try: with open(self._dataRefFile, "r") as f: self._dataRef = json.load(f) except FileNotFoundError: warnings.warn(f"no reference data to check key:{key}") return # pragma: no cover assert key in self._dataRef, f"key:{key} not in reference data" data = self._data[key] ref = self._dataRef[key] assert len(data) == len(ref), f"data with len:{len(data)}) cannot be compared to ref with len:{len(ref)})" assert np.allclose( data, ref, atol=atol, rtol=rtol, equal_nan=True ), f"{key}, difference between data:{data} and ref:{ref}"
[docs] def writeToJSON(self): """Write cached data into a json file""" if os.path.isfile(self._dataFile): with open(self._dataFile, "r") as f: self._data.update(json.load(f)) with open(self._dataFile, "w") as f: json.dump(self._data, f)