The Decorator¶
Why a decorator?¶
You might wonder: why not just name functions test_* and let pytest collect them?
The decorator makes inline tests opt-in. Without --inline-tests, the plugin doesn't import your source files at all. It scans for the @test decorator via AST first. No decorator? The file is skipped. No import, no overhead, no accidental test runs.
This matters:
- You control when inline tests run.
pytestruns your regular test suite.itestadds inline tests. Two modes, explicit choice. - No pollution. Your CI can run
pytest tests/without touching source files. - Naming freedom. Write
rejects_empty_input()instead oftest_rejects_empty_input(). - Method-level granularity. Put
@teston methods in regular classes without needing aTestFooclass.
Basic usage¶
The decorator marks the function. Nothing else changes. The function still exists at runtime and can be called normally.
@it alias¶
For BDD-style naming:
from inline_tests import it
@it
def should_return_empty_list_for_no_input():
assert process([]) == []
it is literally test. Same function, different name.
With reason¶
Document why a test exists:
The reason is stored but not currently displayed. Future versions may surface it in reports.
Test classes¶
Group related tests:
class ValidationTests:
@test
def rejects_empty(self):
assert validate("") is False
@test
def accepts_valid(self):
assert validate("hello") is True
Only the methods need @test. The class is just for organization.
Async tests¶
Works with pytest-asyncio:
@test
async def fetches_data():
result = await fetch("https://api.example.com")
assert result.status == 200
Requires inline-tests[async] or pytest-asyncio installed separately.
Production considerations¶
Unlike Rust's #[cfg(test)], Python can't compile out decorated functions. They exist at runtime.
For zero overhead in production:
try:
from inline_tests import test
except ImportError:
test = lambda f=None, **_: f if f else (lambda x: x)
Or simply keep inline-tests as a dev dependency. The decorator itself costs nothing if you don't run itest.