Usage Examples#

Creating Test Cases with omni.kit.test#

import omni.kit.test
import unittest
import asyncio
import omni.kit.app
import omni.kit.async_engine
import time
import random
from omni.kit.test.async_unittest import AsyncTextTestRunner

# Regular async test case
class BasicAsyncTest(omni.kit.test.AsyncTestCase):
    async def setUp(self):
        print("Setting up test")
        
    async def test_simple_async(self):
        # Wait for 3 UI frame updates
        await self.wait_n_updates(3)
        self.assertEqual(1 + 1, 2)
    
    async def test_with_retry(self):
        counter = [0]
        
        def operation():
            counter[0] += 1
            return counter[0] >= 3  # Return True after 3 attempts
        
        # Retry until operation returns True
        result = await self.retry_until_success(operation, wait_frames=1, max_retries=5)
        self.assertTrue(result)
        
        # Reset counter
        counter[0] = 0
        
        # Using assertion helper with retry
        await self.assertTrueWithRetry(
            lambda: (counter[0] + 1) and counter.__setitem__(0, counter[0] + 1) >= 3,
            wait_frames=1,
            max_retries=5
        )
    
    async def tearDown(self):
        print("Cleaning up test")

# Test case that fails on log errors
class ErrorLoggingTest(omni.kit.test.AsyncTestCaseFailOnLogError):
    async def test_operations_without_errors(self):
        # This test will pass if no error logs are generated
        self.assertEqual(2 + 2, 4)
        await self.wait_n_updates(3)

# Benchmark test for performance testing
class PerformanceBenchmark(omni.kit.test.BenchmarkTestCase):
    async def test_operation_performance(self):
        # Record a single performance metric
        start_time = time.perf_counter()
        await self._simulate_complex_operation(iterations=50)
        execution_time = time.perf_counter() - start_time
        
        self.set_metric_sample(
            name="operation_execution_time",
            value=execution_time,
            unit="seconds"
        )
        
        # Record an array of metrics
        frame_times = [0.01, 0.02, 0.015, 0.018, 0.022]  # Example values
        self.set_metric_sample_array(
            name="frame_execution_times",
            values=frame_times,
            unit="seconds"
        )
    
    async def _simulate_complex_operation(self, iterations):
        for _ in range(iterations):
            await asyncio.sleep(0.001)  # Small sleep to simulate work

# Create a test suite with tests from different classes
test_suite = omni.kit.test.AsyncTestSuite()
test_suite.addTest(BasicAsyncTest('test_simple_async'))
test_suite.addTest(ErrorLoggingTest('test_operations_without_errors'))
test_suite.addTest(PerformanceBenchmark('test_operation_performance'))

# Create the test runner from the correct submodule
runner = AsyncTextTestRunner(verbosity=2)

# Run the tests
async def run_tests():
    await runner.run(test_suite)

# Use the async engine to run our test coroutine
omni.kit.async_engine.run_coroutine(run_tests())

Managing Tests with Callbacks and Run Functions#

import omni.kit.test
from omni.kit.test import TestRunStatus, TestReturnCode
import sys

# Define a callback function to handle test status updates
def test_status_callback(test_id, status, **kwargs):
    """
    This callback will be called whenever a test's status changes.
    """
    if status == TestRunStatus.RUNNING:
        print(f"[RUNNING] Test started: {test_id}")
    elif status == TestRunStatus.PASSED:
        print(f"[PASSED] Test completed successfully: {test_id}")
    elif status == TestRunStatus.FAILED:
        fail_message = kwargs.get('fail_message', 'No details provided')
        print(f"[FAILED] Test failed: {test_id}")
        print(f"Failure details: {fail_message}")

# Register the callback to receive test status updates
omni.kit.test.add_test_status_report_cb(test_status_callback)

# Create a simple test class
class SimpleTest(omni.kit.test.AsyncTestCase):
    async def test_success(self):
        print("Running successful test")
        self.assertTrue(True)
    
    async def test_failure(self):
        print("Running failing test")
        self.assertTrue(False, "This test is deliberately failing")

# Define a function to be called when all tests are finished
def on_tests_finished(result):
    print("\nTest Run Summary:")
    print(f"Tests run: {result.testsRun}")
    print(f"Failures: {len(result.failures)}")
    print(f"Errors: {len(result.errors)}")
    print(f"Overall success: {result.wasSuccessful()}")
    print(f"Return code: {0 if result.wasSuccessful() else TestReturnCode.UNIT_TESTS_FAILED}")

# Create test instances (run_tests expects a list, not a suite)
test_success = SimpleTest('test_success')

# Pass a list of tests instead of a suite
tests = [test_success]

# Run tests with our finish callback
omni.kit.test.run_tests(tests, on_finish_fn=on_tests_finished)

# Pass the class itself, not an instance for add_test_case_to_tested_extension
omni.kit.test.add_test_case_to_tested_extension(SimpleTest, "my_submodule")