docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Create reusable test components

    To create reusable test components with custom behavior for different phases of the test lifecycle, derive your class from UITestComponent. Override its lifecycle methods to implement your logic at the appropriate stages.

    Lifecycle methods

    UITestComponent provides four lifecycle methods you can override:

    Method When it's called Intended purpose
    Initialize(AbstractUITestFixture) When the component is added to the test fixture Set up the component and initialize references
    BeforeTest() Before each test runs Prepare test-specific state
    AfterTest() After each test completes Clean up test-specific state
    Shutdown() When removing the component or tearing down the fixture Release resources and perform final cleanup

    Example: Custom logging component

    The following example creates a custom test component that logs messages during different stages of the test or test fixture:

    public class TestLoggerComponent : UITestComponent
    {
        string testLoggerTag = "|| TestLoggerComponent || ";
        string currentTest;
    
        // Invoked when the test component is added to the test fixture.
        protected override void Initialize(AbstractUITestFixture testFixture)
        {
            // Required: call the base Initialize.
            base.Initialize(testFixture);
    
            Debug.Log($"{testLoggerTag} Component Initialized");
        }
    
        // Invoked before each test.
        protected override void BeforeTest()
        {
            currentTest = TestContext.CurrentContext.Test.Name;
            Debug.Log($"{testLoggerTag} Beginning test: {currentTest}");
        }
    
        // Invoked after each test.
        protected override void AfterTest()
        {
            Debug.Log($"{testLoggerTag} Ending test: {currentTest}");
        }
    
        // Invoked at the end of the test fixture.
        protected override void Shutdown()
        {
            currentTest = null;
            Debug.Log($"{testLoggerTag} Test Fixture Shutdown");
        }
    
        public void LogMessage(string message)
        {
            Debug.Log($"{currentTest}: {message}");
        }
    }
    

    Add your custom test component to a test fixture using the AddTestComponent<T>() method:

    public class TestLoggerComponentExample : UITestFixture
    {
        TestLoggerComponent testLoggerComponent;
    
        [OneTimeSetUp]
        public void OneTimeSetUp()
        {
            testLoggerComponent = AddTestComponent<TestLoggerComponent>();
        }
    
        [Test]
        public void MyTestWithLoggingComponent()
        {
            // Test steps.
            // ...
        }
    
        [Test]
        public void MyOtherTestWithLoggingComponent()
        {
            testLoggerComponent.LogMessage("Adding more logs here");
    
            // Test steps.
            // ...
        }
    }
    

    Example: UI setup component

    The following example creates a custom test component that sets up the test fixture UI:

    public class UISetupComponent : UITestComponent
    {
        public Button testButton { get; private set; }
    
        protected override void Initialize(AbstractUITestFixture testFixture)
        {
            // Required: call the base Initialize.
            base.Initialize(testFixture);
    
            // Force fixtures that use this test component to clear
            // the content of the rootVisualElement at the end of each test.
            fixture.clearContentAfterTest = true;
        }
    
        protected override void BeforeTest()
        {
            // Instantiate your elements.
            testButton = new Button() { name = "UISetupComponentButton" };
    
            // Add them to the rootVisualElement.
            fixture.rootVisualElement.Add(testButton);
        }
    
        protected override void AfterTest()
        {
            // Clean up of the rootVisualElement is automatic
            // when clearContentAfterTest is true.
            // You can add custom cleanup here if needed.
            testButton = null;
        }
    }
    

    To use it in your tests:

    public class TestUISetupComponentExample : UITestFixture
    {
        UISetupComponent uiSetupComponent;
    
        [OneTimeSetUp]
        public void OneTimeSetUp()
        {
            uiSetupComponent = AddTestComponent<UISetupComponent>();
        }
    
        [Test]
        public void MyTestWithUISetupComponent()
        {
            Button button = rootVisualElement.Q<Button>("UISetupComponentButton");
            Assume.That(button, Is.Not.Null);
    
            // Test steps.
            // ...
        }
    
        [Test]
        public void MyOtherTestWithUISetupComponent()
        {
            Button button = rootVisualElement.Q<Button>("UISetupComponentButton");
            Assume.That(button, Is.Not.Null);
    
            // Test steps.
            // ...
        }
    }
    

    Best practices

    When creating custom UITestComponent classes:

    • Keep components focused: Design each component to have a single, clear responsibility.
    • Use appropriate lifecycle methods: Initialize resources in Initialize() or BeforeTest(), clean up the state in AfterTest() or Shutdown(). Don't forget to call the base function when overriding the Initialize() method.
    • Manage and check references: Be mindful of checking for null references and cleaning up the state properly between tests.

    Additional resources

    • UITestComponent
    • AddTestComponent<T>
    In This Article
    Back to top
    Copyright © 2026 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)