Testing
saferaise is designed to be used as a validation tool during development and testing. This guide shows patterns for integrating it into your test suite.
Pytest Fixtures
Create a fixture that enables exception watching for all tests:
# conftest.py
import pytest
import saferaise
saferaise.register("myapp")
@pytest.fixture(autouse=True)
def _enable_saferaise():
with saferaise.enable():
yield
With this fixture, every test automatically validates that @raises-decorated functions have their exceptions properly handled.
Tip
Place saferaise.register("myapp") at the top of conftest.py - it only needs to be called once, before any test imports your package.
Testing That Exceptions Are Raised
Use standard pytest patterns - saferaise doesn't change how exceptions work, it only validates that they're declared and handled:
# myapp/parser.py
from saferaise import raises
@raises(ValueError)
def parse_int(raw: str) -> int:
return int(raw)
# tests/test_parser.py
import pytest
from saferaise import unsafe
from myapp.parser import parse_int
def test_parse_valid():
try:
result = parse_int("42")
except ValueError:
pytest.fail("Should not raise")
assert result == 42
def test_parse_invalid():
with pytest.raises(ValueError):
with unsafe(ValueError): # tell saferaise we're intentionally handling this
parse_int("abc")
Using unsafe in Tests
Note
When testing that a function raises an exception, you need unsafe() to tell saferaise that you're intentionally handling the exception:
def test_connection_error():
with unsafe(ConnectionError):
with pytest.raises(ConnectionError):
fetch_data("https://invalid.example.com")
Using disable in Tests
If you want to temporarily skip all saferaise validation in a specific test:
from saferaise import disable
def test_without_validation():
with disable():
# No @raises validation happens here
result = parse_int("42")
assert result == 42
Async Tests
Works the same way with pytest-asyncio:
# conftest.py
import pytest
import saferaise
saferaise.register("myapp")
@pytest.fixture(autouse=True)
def _enable_saferaise():
with saferaise.enable():
yield
# tests/test_client.py
import pytest
from saferaise import unsafe
from myapp.client import fetch
@pytest.mark.asyncio
async def test_fetch():
try:
data = await fetch("https://example.com")
except (ConnectionError, TimeoutError):
pytest.skip("Network unavailable")
assert len(data) > 0