UnitTest support

Tortoise ORM includes its own helper utilities to assist in unit tests.


from tortoise.contrib import test

class TestSomething(test.TestCase):
    def test_something(self):

    async def test_something_async(self):

    @test.skip('Skip this')
    def test_skip(self):

    def test_something(self):

To get test.TestCase to work as expected, you need to configure your test environment setup and teardown to call the following:

from tortoise.contrib.test import initializer, finalizer

# In setup
initializer(['module.a', 'module.b.c'])
# With optional db_url, app_label and loop parameters
initializer(['module.a', 'module.b.c'], db_url='...', app_label="someapp", loop=loop)
# Or env-var driven → See Green test runner section below.

# In teardown

On the DB_URL it should follow the following standard:

TORTOISE_TEST_DB=sqlite:///tmp/test-{}.sqlite TORTOISE_TEST_DB=postgres://postgres:@{}

The {} is a string-replacement parameter, that will create a randomized database name. This is currently required for test.IsolatedTestCase to function. If you don’t use test.IsolatedTestCase then you can give an absolute address. The SQLite in-memory :memory: database will always work, and is the default.

Test Runners


In your .green file:

initializer = tortoise.contrib.test.env_initializer
finalizer = tortoise.contrib.test.finalizer

And then define the TORTOISE_TEST_MODULES environment variable with a comma separated list of module paths.

Furthermore, you may set the database configuration parameter as an environment variable (defaults to sqlite://:memory:):

TORTOISE_TEST_DB=sqlite:///tmp/test-{}.sqlite TORTOISE_TEST_DB=postgres://postgres:@{}



pytest 5.4.0 & 5.4.1 has a bug that stops it from working with async test cases. You may have to install pytest>=5.4.2 to get it to work.

Run the initializer and finalizer in your conftest.py file:

import os
import pytest
from tortoise.contrib.test import finalizer, initializer

@pytest.fixture(scope="session", autouse=True)
def initialize_tests(request):
    db_url = os.environ.get("TORTOISE_TEST_DB", "sqlite://:memory:")
    initializer(["tests.testmodels"], db_url=db_url, app_label="models")


Load the plugin tortoise.contrib.test.nose2 either via command line:

nose2 --plugin tortoise.contrib.test.nose2 --db-module tortoise.tests.testmodels

Or via the config file:

plugins = tortoise.contrib.test.nose2

# Must specify at least one module path
db-module =
# You can optionally override the db_url here
db-url = sqlite://testdb-{}.sqlite


class tortoise.contrib.test.IsolatedTestCase(methodName='runTest')[source]

Bases: SimpleTestCase

An asyncio capable test class that will ensure that an isolated test db is available for each test.

Use this if your test needs perfect isolation.

Note to use {} as a string-replacement parameter, for your DB_URL. That will create a randomised database name.

It will create and destroy a new DB instance for every test. This is obviously slow, but guarantees a fresh DB.

If you define a tortoise_test_modules list, it overrides the DB setup module for the tests.

tortoise_test_modules : Iterable[str | module] = []
class tortoise.contrib.test.SimpleTestCase(methodName='runTest')[source]

Bases: IsolatedAsyncioTestCase

The Tortoise base test class.

This will ensure that your DB environment has a test double set up for use.

An asyncio capable test class that provides some helper functions.

Will run any test_*() function either as sync or async, depending on the signature of the function. If you specify async test_*() then it will run it in an event loop.

Based on asynctest

assertListSortEqual(list1, list2, msg=Ellipsis, sorted_key=None)[source]
Return type:


async asyncSetUp()[source]
Return type:


async asyncTearDown()[source]
Return type:


exception tortoise.contrib.test.SkipTest[source]

Bases: Exception

Raise this exception in a test to skip it.

Usually you can use TestCase.skipTest() or one of the skipping decorators instead of raising this directly.

class tortoise.contrib.test.TestCase(methodName='runTest')[source]

Bases: TruncationTestCase

An asyncio capable test class that will ensure that each test will be run at separate transaction that will rollback on finish.

This is a fast test runner. Don’t use it if your test uses transactions.

async asyncSetUp()[source]
Return type:


async asyncTearDown()[source]
Return type:


class tortoise.contrib.test.TruncationTestCase(methodName='runTest')[source]

Bases: SimpleTestCase

An asyncio capable test class that will truncate the tables after a test.

Use this when your tests contain transactions.

This is slower than TestCase but faster than IsolatedTestCase. Note that usage of this does not guarantee that auto-number-pks will be reset to 1.


Calls initializer() with parameters mapped from environment variables.


A comma-separated list of modules to include (required)


The name of the APP to initialise the modules in (optional)

If not provided, it will default to “models”.


The db_url of the test db. (optional)

If not provided, it will default to an in-memory SQLite DB.

Return type:



Mark test as expecting failure.

On success it will be marked as unexpected success.


Cleans up the DB after testing. Must be called as part of the test environment teardown.

Return type:


tortoise.contrib.test.getDBConfig(app_label, modules)[source]

DB Config factory, for use in testing.


Label of the app (must be distinct for multiple apps).


List of modules to look for models in.

Return type:


tortoise.contrib.test.initializer(modules, db_url=None, app_label='models', loop=None)[source]

Sets up the DB for testing. Must be called as part of test environment setup.


List of modules to look for models in.


The db_url, defaults to sqlite://:memory.


The name of the APP to initialise the modules in, defaults to “models”


Optional event loop.

Return type:


tortoise.contrib.test.requireCapability(connection_name='models', **conditions)[source]

Skip a test if the required capabilities are not matched.


The database must be initialized before the decorated test runs.


async def test_run_sqlite_only(self):

Or to conditionally skip a class:

class TestSqlite(test.TestCase):

name of the connection to retrieve capabilities from.


capability tests which must all pass for the test to run.


Unconditionally skip a test.

tortoise.contrib.test.skipIf(condition, reason)[source]

Skip a test if the condition is true.

tortoise.contrib.test.skipUnless(condition, reason)[source]

Skip a test unless the condition is true.