testutils#

Utilities for writing tests.

class ParametricTestCase(methodName='runTest')[source]#
parameterize(test_case_class, *args, **kwargs)[source]#

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)[source]#

Raised when the LoggingValidator fails

class LoggingValidator(logger=None, critical=None, error=None, warning=None, info=None, debug=None, notset=None)[source]#

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()[source]#

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()[source]#

Returns the current message count by level.

emit(record)[source]#

Override logging.Handler.emit()

validate_logging(logger=None, critical=None, error=None, warning=None, info=None, debug=None, notset=None)[source]#

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)[source]#
class EnsureImportError(name)[source]#

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.