run_test¶

plasmapy.utils.pytest_helpers.pytest_helpers.run_test(func, args: Any = (), kwargs: Dict[KT, VT] = {}, expected_outcome: Any = None, rtol: float = 0.0, atol: float = 0.0)

Test that a function or class returns the expected result, raises the expected exception, or issues an expected warning for the supplied positional and keyword arguments.

Parameters: func (callable, list, or tuple) – The callable to be tested. The first (and sole) argument to run_test may alternatively be a list or tuple containing these arguments (optionally omitting kwargs if the len returns 3). args (tuple or object) – The positional arguments to func. kwargs (dict) – The keyword arguments to func. expected_outcome (object) – The expected result, exception, or warning from func(*args, **kwargs). This may also be a tuple of length two that contains the expected result as the first item and the expected warning as the second item. rtol (float) – The relative tolerance to be used by allclose in an element-wise comparison, defaulting to 0. atol (float) – The absolute tolerance to be used by allclose in an element-wise comparison, defaulting to 0. None UnexpectedResultFail – If the test returns a result that is different from the expected result. TypeMismatchFail – If the actual result is of a different type than the expected result. UnexpectedExceptionFail – If an exception occurs when no exception or a different exception is expected. MissingExceptionFail – If no exception is raised when an exception is expected. MissingWarningFail – An expected warning is not issued. UnitsError – If the result has different units than expected. TypeError – If the equality of the actual result and expected result cannot be determined (e.g., for a class lacking an __eq__ method.

Examples

The simplest way to use run_test is with inputs for the function to be tests, the positional arguments in a tuple or list, the keyword arguments in a dict, and then finally the expected result or outcome.

>>> args = tuple()
>>> kwargs = dict()
>>> run_test(lambda: 0, args, kwargs, 0)


If expected is a an exception or warning, then run_test will raise an exception if the expected exception is not raised or the expected warning is not issued.

>>> from warnings import warn

>>> issue_warning = lambda: warn("Electrons are weird!", UserWarning)
>>> run_test(issue_warning, args, kwargs, UserWarning)

>>> def raise_exception(): raise RuntimeError
>>> run_test(raise_exception, args, kwargs, RuntimeError)


For warnings, run_test can accept a tuple of two items where the first item is the expected result and the second item is the expected warning.

def return_arg_and_warn(x):
warn("", UserWarning)
return x

run_test(return_arg_and_warn, 1, {}, (1, UserWarning))


This function is also flexible enough that it can accept a tuple or list as its sole argument, with the arguments in the same order as in the function signature.

>>> return_arg = lambda x: x
>>> inputs = (return_arg, 42, {}, 42)
>>> run_test(inputs)


If the tuple or list has a length of 3, then run_test assumes that kwargs is missing.

>>> inputs_without_kwargs = [return_arg, 42, 42]
>>> run_test(inputs_without_kwargs)

import pytest

def func(x, raise_exception=False, issue_warning=False):
if raise_exception:
raise ValueError("I'm sorry, Dave. I'm afraid I can't do that.")
elif issue_warning:
warn("Open the pod bay doors, HAL.", UserWarning)
return x

inputs_table = [
(func, 1, 1),
(func, (2,), {}, 2),
(func, 3, {'raise_exception': True}, ValueError),
(func, 4, {'issue_warning': True}, UserWarning),
(func, 5, {'issue_warning': True}, (5, UserWarning)),
]

@pytest.mark.parametrize('inputs', inputs_table)
def test_func(inputs):
run_test(inputs)