Async context manager for isolated test database setup. This is the recommended way to set up Tortoise ORM for testing with pytest. Each call creates a completely isolated context with its own: - ConnectionHandler (no global state pollution) - Apps registry - Database (crea
(
modules: list[str],
db_url: str = "sqlite://:memory:",
app_label: str = "models",
*,
connection_label: str | None = None,
use_tz: bool = True,
timezone: str = "UTC",
routers: list[str | type] | None = None,
)
| 524 | |
| 525 | @asynccontextmanager |
| 526 | async def tortoise_test_context( |
| 527 | modules: list[str], |
| 528 | db_url: str = "sqlite://:memory:", |
| 529 | app_label: str = "models", |
| 530 | *, |
| 531 | connection_label: str | None = None, |
| 532 | use_tz: bool = True, |
| 533 | timezone: str = "UTC", |
| 534 | routers: list[str | type] | None = None, |
| 535 | ) -> AsyncIterator[TortoiseContext]: |
| 536 | """ |
| 537 | Async context manager for isolated test database setup. |
| 538 | |
| 539 | This is the recommended way to set up Tortoise ORM for testing with pytest. |
| 540 | Each call creates a completely isolated context with its own: |
| 541 | - ConnectionHandler (no global state pollution) |
| 542 | - Apps registry |
| 543 | - Database (created fresh, cleaned up on exit) |
| 544 | - Timezone and router configuration |
| 545 | |
| 546 | Example with pytest-asyncio: |
| 547 | @pytest_asyncio.fixture |
| 548 | async def db(): |
| 549 | async with tortoise_test_context(["myapp.models"]) as ctx: |
| 550 | yield ctx |
| 551 | |
| 552 | @pytest.mark.asyncio |
| 553 | async def test_create_user(db): |
| 554 | user = await User.create(name="Alice") |
| 555 | assert user.id is not None |
| 556 | |
| 557 | Features: |
| 558 | - Creates isolated TortoiseContext (no global state pollution) |
| 559 | - Creates fresh database and generates schemas |
| 560 | - Cleans up connections on exit |
| 561 | - xdist-safe (each worker gets own context) |
| 562 | |
| 563 | Args: |
| 564 | modules: List of module paths to discover models from. |
| 565 | db_url: Database URL, defaults to in-memory SQLite. |
| 566 | app_label: The app label for the models, defaults to "models". |
| 567 | connection_label: The connection alias name. If None, defaults to "default". |
| 568 | use_tz: If True, datetime fields will be timezone-aware. |
| 569 | timezone: Timezone to use, defaults to "UTC". |
| 570 | routers: List of database router paths or classes. |
| 571 | |
| 572 | Yields: |
| 573 | An initialized TortoiseContext ready for use. |
| 574 | """ |
| 575 | import warnings |
| 576 | |
| 577 | from tortoise.warnings import TortoiseLoopSwitchWarning |
| 578 | |
| 579 | with warnings.catch_warnings(): |
| 580 | warnings.filterwarnings("ignore", category=TortoiseLoopSwitchWarning) |
| 581 | ctx = TortoiseContext() |
| 582 | async with ctx: |
| 583 | config = generate_config( |
searching dependent graphs…