Python asyncio-centric testing system.

To create a test derive from omni.kit.test.AsyncTestCase and add a method that starts with test_, like in unittest. Method can be either async or regular one. You can also derive from omni.kit.test.AsyncTestCaseFailOnLogError to make test fail automatically when any error is logged (carb.log_error()).

import omni.kit.test

class MyTest(omni.kit.test.AsyncTestCaseFailOnLogError):
    async def setUp(self):

    async def tearDown(self):

    # Actual test, notice it is "async" function, so "await" can be used if needed
    async def test_hello(self):
        self.assertEqual(10, 10)

Test class must be defined on top of your public extension module. Meaning if for instance your extension.toml defines:

name = "" should be a path to your test. That will allow it to be automatically found by test system. Using tests submodule of your extension module is a recommended way to organize tests. That keeps tests together with extension, but not too coupled with the actual module they test, so that they can import module with absolute path (e.g. import and test it the way user will see them.

Refer to omni.example.hello extension as a simplest example of extension with a python test.


For the settings refer to extension.toml file:

title = "Testing System"
category = "Internal"

"omni.kit.async_engine" = {}
"omni.kit.loop" = {}

name = "omni.kit.test"


# Wait few updates (to allow all extensions to load), run tests to completion and exit.
exts."omni.kit.test".runTestsAndQuit = false

# Wait few updates (to allow all extensions to load), and print all tests in stdout
exts."omni.kit.test".printTests = false

# Filter which tests to run: python's fnmatch is used. Use `*`, `?` etc. Test ids look like this [module].[class].[method].
# E.g.: "omni.client.tests.test_client.TestClient.test_list_async"
exts."omni.kit.test".includeTests = ["*"]
exts."omni.kit.test".excludeTests = []

They can be used to filter, automatically run tests and quit.

API Reference

Async version of python unittest module.

AsyncTestCase, AsyncTestSuite and AsyncTextTestRunner classes were copied from python unittest source and async/await keywords were added.

Using “from X import *” on files containing tests in your module will automatically register them. If you do not want to add that line for every X you can just set the global variable “scan_for_test_modules = True” in your file. (Make sure its directory has been added to your extension.toml file under [[python.modules]].)

class omni.kit.test.AsyncTestCase(methodName='runTest')


Base class for all async test cases.

Derive from it to make your tests auto discoverable. Test methods must start with test_ prefix.


If true test will check for Carbonite logging messages and fail if any error level or higher was produced during the test.



Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

fail_on_log_error = False
async run(result=None)
class omni.kit.test.AsyncTestCaseFailOnLogError(methodName='runTest')

Bases: omni.kit.test.AsyncTestCase

Test Case which automatically subscribes to logging events and fails if any error were produced during the test.

This class is for backward compatibility, you can also just change value of fail_on_log_error.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

fail_on_log_error = True
class omni.kit.test.AsyncTestSuite(tests=())

Bases: unittest.suite.TestSuite

A test suite is a composite test consisting of a number of TestCases.

For use, create an instance of TestSuite, then add test case instances. When all tests have been added, the suite can be passed to a test runner, such as TextTestRunner. It will run the individual test cases in the order in which they were added, aggregating the results. When subclassing, do not forget to call the base class constructor.

async run(result, debug=False)
class omni.kit.test.AsyncTextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False)

Bases: unittest.runner.TextTestRunner

A test runner class that displays results in textual form.

It prints out the names of tests as they are run, errors as they occur, and a summary of the results at the end of the test run.

Construct a TextTestRunner.

Subclasses should accept **kwargs to ensure compatibility as the interface changes.

async run(test, on_status_report_fn=None)

Run the given test case or test suite.

class omni.kit.test.LogErrorChecker

Bases: object

Automatically subscribes to logging events and monitors if error were produced during the test.

class omni.kit.test.TeamcityTestResult(stream, descriptions, verbosity)

Bases: unittest.runner.TextTestResult

addError(test, err, *k)

Called when an error has occurred. ‘err’ is a tuple of values as returned by sys.exc_info().

addFailure(test, err, *k)

Called when an error has occurred. ‘err’ is a tuple of values as returned by sys.exc_info().


Called when a test has completed successfully

static get_test_id(test)
report_fail(test, fail_type, err)

Called when the given test is about to be run


Called when the given test has been run

teamcity_message(message_name, **properties)
async omni.kit.test.await_or_call(func)

Awaits on function if it is a coroutine, calls it otherwise.

omni.kit.test.dynamic_test_modules(module_root: str, module_file: str) → List[module]

Import all of the test modules and return a list of the imports so that automatic test recognition works

The normal test recognition mechanism relies on knowing all of the file names at build time. This function is used to support automatic recognition of all test files in a certain directory at run time.

  • module_root – Name of the module for which tests are being imported, usually just __name__ of the caller

  • module_file – File from which the import is happening, usually just __file__ of the caller

In the directory containing your tests add this line to the file (creating the file if necessary):

scan_for_test_modules = True

It will pick up any Python files names or and scan them for tests when the extension is loaded.


The file must be imported with the extension. One way of ensuring this is to add an explicit reference to your test directory/directories in your extension.toml file:

[[python.modules]] name = “”


List of modules that were added, each pointing to a file in which tests are contained


Default function to get all current tests.

It gets tests from all enabled extensions, but also included include and exclude settings to filter them


List of tests.

omni.kit.test.get_tests_from_modules(modules, log=False)
omni.kit.test.run_tests(tests=None, on_finish_fn=None, on_status_report_fn=None)
omni.kit.test.run_tests_in_modules(modules, on_finish_fn=None)