An open API service indexing awesome lists of open source software.

https://github.com/jonking93/pytest-error

Decorator to validate pytest tests that should raise expected exceptions
https://github.com/jonking93/pytest-error

exceptions pytest testing

Last synced: 4 months ago
JSON representation

Decorator to validate pytest tests that should raise expected exceptions

Awesome Lists containing this project

README

          

# pytest-error

A decorator for testing exceptions with [pytest](https://docs.pytest.org/en/stable/index.html).

## About

The `pytest-error` package provides an `@error` decorator to validate pytest tests that should raise an exception. The decorator is built on the [pytest.raises][pytest.raises] context manager, and further extends its functionality to allow validation of error messages using strings. ([pytest.raises][pytest.raises] requires regular expressions to validate error messages).

Some motivations for using the decorator include:

1. Testing error messages without needing regular expressions
2. Adding a marker to quickly identify tests that examine error states
3. Keeping the [action code][test anatomy] for exception tests at the same indent level as other tests

[pytest.raises]: https://docs.pytest.org/en/stable/how-to/assert.html#assertions-about-expected-exceptions
[test anatomy]: https://docs.pytest.org/en/stable/explanation/anatomy.html

## Examples

Require a test to raise an expected exception:

```python
from pytest_error import error

@error(ValueError, "some message A", "another message B", "final message C")
def test():
raise ValueError(
"This test must raise an ValueError whose error message "
"must include some message A, another message B, and a final message C."
)

@error((TypeError, ValueError), 'some message')
def test_multiple_types():
raise TypeError(
"This test must raise either a TypeError or ValueError, "
"and the error must include some message".
)
```

Auto-fail and display the raised message in the pytest results (useful for examining error messages when writing tests):
```python
@error(RuntimeError)
def test():
raise RuntimeError(
"Because @error does not include any error message strings, "
"this test will fail and will display the raised error message "
"in the pytest output. Refer to the documentation for ways to "
"disable auto-failing."
)
```

Plays well with the pytest ecosystem:
```python
@error(TypeError, 'some error message')
@pytest.mark.parametrize('parameter', (1,2,3))
def test_with_parameters(parameter):
raise TypeError(
'This test uses parameters, and should raise a TypeError with some error message'
)

@error(ValueError, 'some error message')
def test_with_fixtures(fixtureA, fixtureB):
raise ValueError(
'This test uses fixtures, and should raise a ValueError with some error message'
)

class TestClass:
@error(RuntimeError, 'some error message')
def test_that_is_a_method(cls):
raise RuntimeError(
'This test is a class method, and should raise a RuntimeError with some error message'
)

@error((ValueError, TypeError), 'some message', check=some_callable, match=some_regex)
def test_raises_api():
raise ValueError(
"This exception raised by this test must satisfy the `check` and `match` args "
"from the pytest.raises API, and must raise a ValueError with some message."
)
```

Inject parameters and fixtures into expected error messages:
```python
@error(ValueError, 'message including {param1} and {fixture2}')
@pytest.mark.parametrize(
'param1', ('some message A', 'some message B')
)
def test(param1, fixture1, fixture2):
raise ValueError(
f'This test should raise an exception that has a message '
f'including {param1} and {fixture2}'
)
```

## Installation

**Requires**: Python 3.10+, pytest 8.4+

```
pip install pytest-error
```

## Documentation

You can find more detailed examples, a user guide, and a comprehensive API at the [project documentation](https://jonking93.github.io/pytest-error).