Source code for secml.testing.c_unittest

"""
.. module:: UnitTest
   :synopsis: Class for manage unittests

.. moduleauthor:: Marco Melis <marco.melis@unica.it>
.. moduleauthor:: Ambra Demontis <ambra.demontis@unica.it>

"""
import unittest
import pytest
import numpy as np
import numpy.testing as npt

from secml import global_filterwarnings
from secml.utils import CLog
from secml.settings import SECML_STORE_LOGS


[docs]class CUnitTest(unittest.TestCase): """Superclass for unittests. Provides a wrapper of `unittests.TestCase` in addition to: - integrated logging functionalities (see `CLog`) - integrated timing functionalities (see `CTimer`) - addition assertion methods from `numpy.testing` - `skip`, `skipif`, `importorskip` functions from `pytest` """ @property def logger(self): """Logger for current object.""" return self._logger.get_child(self.__class__.__name__)
[docs] @classmethod def setUpClass(cls): # Unittests logs will be stored in a `unittests.log` file # in the same directory of the calling unittest. # Use `store_logs=True` in configuration file to activate this cls._logger = CLog( logger_id='unittest', add_stream=True, file_handler='unittests.log' if SECML_STORE_LOGS is True else None) cls._logger.set_level('DEBUG') # As per python 3.2 filterwarnings are reset by unittests for each # TestCase. We thus need to restore our filter for every TestCase global_filterwarnings()
[docs] def timer(self): """Returns a CTimer to be used as context manager.""" return self.logger.timer()
# Raises an AssertionError if two array_like objects are not equal
[docs] def assert_array_equal(self, x, y, err_msg='', verbose=True): x = x.tondarray() if hasattr(x, 'tondarray') else x y = y.tondarray() if hasattr(y, 'tondarray') else y return npt.assert_array_equal(x, y, err_msg, verbose)
assert_array_equal.__doc__ = npt.assert_array_equal.__doc__ # AssertionError if two objects are not equal up to desired precision
[docs] def assert_array_almost_equal( self, x, y, decimal=6, err_msg='', verbose=True): x = x.tondarray() if hasattr(x, 'tondarray') else x y = y.tondarray() if hasattr(y, 'tondarray') else y return npt.assert_array_almost_equal(x, y, decimal, err_msg, verbose)
assert_array_almost_equal.__doc__ = npt.assert_array_almost_equal.__doc__ # Compare two arrays relatively to their spacing
[docs] def assert_array_almost_equal_nulp(self, x, y, nulp=1): x = x.tondarray() if hasattr(x, 'tondarray') else x y = y.tondarray() if hasattr(y, 'tondarray') else y return npt.assert_array_almost_equal_nulp(x, y, nulp)
assert_array_almost_equal_nulp.__doc__ = npt.assert_array_almost_equal_nulp.__doc__ # AssertionError if two array_like objects are not ordered by less than
[docs] def assert_array_less(self, x, y, err_msg='', verbose=True): x = x.tondarray() if hasattr(x, 'tondarray') else x y = y.tondarray() if hasattr(y, 'tondarray') else y return npt.assert_array_less(x, y, err_msg, verbose)
assert_array_less.__doc__ = npt.assert_array_less.__doc__ # Check that all elems differ in at most N Units in the last place
[docs] def assert_array_max_ulp(self, a, b, maxulp=1, dtype=None): a = a.tondarray() if hasattr(a, 'tondarray') else a b = b.tondarray() if hasattr(b, 'tondarray') else b return npt.assert_array_max_ulp(a, b, maxulp, dtype)
assert_array_max_ulp.__doc__ = npt.assert_array_max_ulp.__doc__ # AssertionError if two objects are not equal up to desired tolerance
[docs] def assert_allclose(self, actual, desired, rtol=1e-6, atol=0, equal_nan=True, err_msg='', verbose=True): actual = actual.tondarray() if hasattr(actual, 'tondarray') else actual des = desired.tondarray() if hasattr(desired, 'tondarray') else desired return npt.assert_allclose( actual, des, rtol, atol, equal_nan, err_msg, verbose)
assert_allclose.__doc__ = npt.assert_allclose.__doc__ # AssertionError if two items are not equal up to significant digits.
[docs] def assert_approx_equal( self, actual, desired, significant=6, err_msg='', verbose=True,): actual = actual.tondarray() if hasattr(actual, 'tondarray') else actual des = desired.tondarray() if hasattr(desired, 'tondarray') else desired return npt.assert_approx_equal( actual, des, significant, err_msg, verbose)
assert_approx_equal.__doc__ = npt.assert_approx_equal.__doc__
[docs] @staticmethod def assertIsSubDtype(actual, desired): """ Raises an AssertionError if the first dtype is NOT a typecode lower/equal in type hierarchy. Parameters ---------- actual : dtype or str dtype or string representing a typecode. desired : dtype or str dtype or string representing a typecode. """ if desired is float: # To manage the built-in float as either np.float32 or np.float64 desired = np.floating elif desired is int: # To manage the built-in int as either np.int32 or np.int64 desired = np.integer else: # Convert built-in types to numpy dtypes for using issubdtype desired = np.dtype(desired).type if not np.issubdtype(actual, desired): raise AssertionError("{:} is not lower/equal to {:} in the type " "hierarchy.".format(actual, desired))
# Skip something skip = pytest.mark.skip # Skip something conditionally skipif = pytest.mark.skipif # Skipping on a missing import dependency importskip = staticmethod(pytest.importorskip) # Wrapper to use "if __name__ == '__main__': CUnitTest.main()" main = unittest.main