Sessions & Suites
ProTest organizes tests in a hierarchy: Session → Suites → Tests.
ProTestSession
A session is the root of your test hierarchy. You typically have one session per project, or one per major component in a monorepo.
Session Options
Session-Level Tests
You can register tests directly on the session:
These tests don't belong to any suite.
Session Fixtures
Bind fixtures to the session with bind():
from protest import fixture
@fixture()
def database():
db = connect()
yield db
db.close()
session.bind(database) # → SESSION scope
ProTestSuite
Suites group related tests together. They also define a scope boundary for fixtures.
from protest import ProTestSuite
api_suite = ProTestSuite("API")
session.add_suite(api_suite)
@api_suite.test()
async def test_endpoint():
assert True
Suite Options
api_suite = ProTestSuite(
"API",
description="Integration tests for REST API", # Optional documentation
max_concurrency=2, # Cap parallelism for this suite
tags=["integration"], # Tags inherited by all tests in suite
)
Suite Fixtures
Bind fixtures to a suite with bind():
Nested Suites
Suites can contain other suites, creating a hierarchy:
api_suite = ProTestSuite("API")
users_suite = ProTestSuite("Users")
orders_suite = ProTestSuite("Orders")
api_suite.add_suite(users_suite)
api_suite.add_suite(orders_suite)
session.add_suite(api_suite)
This creates the structure:
Full Path
Each suite has a full_path property showing its position in the hierarchy:
Fixture Inheritance
Child suites can access fixtures from parent suites:
@fixture()
def api_client():
return Client()
api_suite.bind(api_client) # → SUITE scope
@users_suite.test()
async def test_get_user(client: Annotated[Client, Use(api_client)]):
# api_client is available here because Users is inside API
pass
Execution Order
- Session fixtures are resolved once at start
- Suites run in registration order
- Within each suite:
- Suite fixtures are resolved once
- Tests run (potentially in parallel)
- Suite fixtures are torn down
- Session fixtures are torn down at end
Teardown follows LIFO order: children before parents.