Skip to main content
`Ctrl`+`K`

# `testutils`

Utilities for writing tests.

- `ParametricTestCase` provides a `TestCase.subTest()` replacement for Python < 3.4

- `LoggingValidator` with context or the `validate_logging()` decorator enables testing the number of logging messages of different levels.

class ParametricTestCase(methodName='runTest')

parameterize(test_case_class, *args, **kwargs)

  Create a suite containing all tests taken from the given subclass, passing them the parameters.

      class TestParameterizedCase(unittest.TestCase):
          def __init__(self, methodName='runTest', foo=None):
              unittest.TestCase.__init__(self, methodName)
              self.foo = foo

      def suite():
          testSuite = unittest.TestSuite()
          testSuite.addTest(parameterize(TestParameterizedCase, foo=10))
          testSuite.addTest(parameterize(TestParameterizedCase, foo=50))
          return testSuite

exception LoggingRuntimeError(msg, records)

  Raised when the LoggingValidator fails

class LoggingValidator(logger=None, critical=None, error=None, warning=None, info=None, debug=None, notset=None)

  Context checking the number of logging messages from a specified Logger.

  It disables propagation of logging message while running.

  This is meant to be used as a with statement, for example:

      >>> with LoggingValidator(logger, error=2, warning=0):
      >>>     pass  # Run tests here expecting 2 ERROR and no WARNING from logger
      ...

  Parameters:

    - logger (str or `logging.Logger`) – Name or instance of the logger to test. (Default: root logger)

    - critical (int) – Expected number of CRITICAL messages. Default: Do not check.

    - error (int) – Expected number of ERROR messages. Default: Do not check.

    - warning (int) – Expected number of WARNING messages. Default: Do not check.

    - info (int) – Expected number of INFO messages. Default: Do not check.

    - debug (int) – Expected number of DEBUG messages. Default: Do not check.

    - notset (int) – Expected number of NOTSET messages. Default: Do not check.

  Raises:

    RuntimeError – If the message counts are the expected ones.

  can_be_checked()

    Returns True if this listener have received enough messages to be valid, and then checked.

    This can be useful for asynchronous wait of messages. It allows process an early break, instead of waiting much time in an active loop.

  get_count_by_level()

    Returns the current message count by level.

  emit(record)

    Override `logging.Handler.emit()`

validate_logging(logger=None, critical=None, error=None, warning=None, info=None, debug=None, notset=None)

  Decorator checking number of logging messages.

  Propagation of logging messages is disabled by this decorator.

  In case the expected number of logging messages is not found, it raises a RuntimeError.

      >>> class Test(unittest.TestCase):
      ...     @validate_logging('module_logger_name', error=2, warning=0)
      ...     def test(self):
      ...         pass  # Test expecting 2 ERROR and 0 WARNING messages

  Parameters:

    - logger (str or `logging.Logger`) – Name or instance of the logger to test. (Default: root logger)

    - critical (int) – Expected number of CRITICAL messages. Default: Do not check.

    - error (int) – Expected number of ERROR messages. Default: Do not check.

    - warning (int) – Expected number of WARNING messages. Default: Do not check.

    - info (int) – Expected number of INFO messages. Default: Do not check.

    - debug (int) – Expected number of DEBUG messages. Default: Do not check.

    - notset (int) – Expected number of NOTSET messages. Default: Do not check.

class TestLogging(*args, **kwargs)

class EnsureImportError(name)

  This context manager allows to simulate the unavailability of a library, even if it is actually available. It ensures that an ImportError is raised if the code inside the context tries to import the module.

  It can be used to test that a correct fallback library is used, or that the expected error code is returned.

  Trivial example:

      from silx.utils.testutils import EnsureImportError

      with EnsureImportError("h5py"):
          try:
              import h5py
          except ImportError:
              print("Good")

  Note

  This context manager does not remove the library from the namespace, if it is already imported. It only ensures that any attempt to import it again will cause an ImportError to be raised.