Guide¶
An ordered walkthrough of voci, one concept per page. Start here and read forward; each page assumes the ones before it.
Install¶
voci needs Python 3.13 or newer. The core package has no dependencies.
Your first test¶
A test is an async def (or plain def) function whose name starts with test_, in a file named
test_*.py or *_test.py:
Run the suite from the project root:
config: none
PASS tests/test_math.py 1 test Σ 0.00s
1 test · 1 passed · 0.02s wall (0.0x concurrency)
The first line names the [tool.voci] table the run picked up, or none. The Σ column is the
sum of every test's own duration in that file; the last line's wall time is how long the run
actually took, and the multiplier is the ratio between the two. One instant test has nothing to
overlap, so the multiplier only becomes interesting once the suite has tests that wait on
something.
The shape of a suite¶
A voci suite is ordinary Python modules. There is no conftest.py and no name-based lookup —
anything shared is a function you import.
tests/
fixtures.py shared fixtures, imported by the test files that want them
test_users.py
test_orders.py
A fixture is a function decorated with @voci.fixture(). A test — or another fixture — asks for
one by naming Depends(that_function) in a parameter's Annotated[...] metadata:
# tests/fixtures.py
import voci
@voci.fixture()
def settings() -> Settings:
return Settings(endpoint="https://hooks.test/v1", retries=3)
# tests/test_delivery.py
from typing import Annotated
from voci import Depends
from tests.fixtures import settings
async def test_endpoint_is_versioned(config: Annotated[Settings, Depends(settings)]) -> None:
assert config.endpoint.endswith("/v1")
Because the fixture arrives as an imported name rather than a string, "go to definition" lands on
it, renames are safe, and a misspelling is an ImportError at collection time.
Depends(that_function) also works in a parameter's default — config: Settings =
Depends(settings) — which is shorter to write. Fixtures
covers what that form costs you, and why Annotated is the one this guide teaches.