1

Problem: I made a simple menu system with UItoolkit in unity. Essentially just a start button that when pressed navigates to a new scene. When I the test scene, everything works fine, but when I tried to implement a corresponding play mode unit test the test doesn't register my Uitoolkit button as being clicked.

Test Case Code

[UnityTest]
public IEnumerator TestButtonClick()
{
    bool clicked = false;
    startButton.clicked += () =>
    {
        clicked = true;
        Debug.Log("Button clicked!"); // Debug to check if the click event fires
    };


    startButton.SetEnabled(true);
    startButton.style.display = DisplayStyle.Flex;

    var pickingMode = startButton.pickingMode;
    Debug.Log($"Button picking mode: {pickingMode}");


    var displayStyle = startButton.resolvedStyle.display;
    Debug.Log($"Button display style: {displayStyle}");


    yield return null;

    var root = startButton.hierarchy.parent;
    if (root != null)
    {
        Debug.Log($"Button's parent is: {root}");
    }
    else
    {
        Debug.LogError("The button has no parent in the hierarchy.");
    }

    Debug.Log($"Button is interactable: {startButton.enabledSelf}");

    // Simulate PointerDownEvent
    using (var pointerDownEvent = new PointerDownEvent())
    {
        pointerDownEvent.target = startButton;  // Ensure the event is targeted to the correct button
        startButton.SendEvent(pointerDownEvent);

        // Log to check if the event was received
        Debug.Log($"PointerDownEvent target: {pointerDownEvent.target}");

        Assert.IsFalse(pointerDownEvent.isPropagationStopped, "PointerDownEvent propagation was stopped unexpectedly.");
    }
    yield return new WaitForSeconds(0.1f); // Small delay between down and up event

    // Simulate PointerUpEvent
    using (var pointerUpEvent = new PointerUpEvent())
    {
        pointerUpEvent.target = startButton;  // Ensure the event is targeted to the correct button
        startButton.SendEvent(pointerUpEvent);

        // Log to check if the event was received
        Debug.Log($"PointerUpEvent target: {pointerUpEvent.target}");

        Assert.IsFalse(pointerUpEvent.isPropagationStopped, "PointerUpEvent propagation was stopped unexpectedly.");
    }



    yield return null;
    // Assert that the button click event was triggered
    if (!clicked)
    {
        Debug.LogError("The button click event was not triggered.");
    }

    // Assert that the button click event was triggered


    Assert.IsTrue(clicked, "The button click event was not triggered.");
}

LOGS

TestButtonClick (0.201s)
---
Unhandled log message: '[Error] The button click event was not triggered.'. Use UnityEngine.TestTools.LogAssert.Expect
---
UI_tests/<TestButtonClick>d__6:MoveNext () (at Assets/Tests/UI_tests.cs:121)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)


---
Button picking mode: Position
Button display style: Flex
Button's parent is: VisualElement Buttons (x:0.00, y:0.00, width:NaN, height:NaN) world rect: (x:0.00, y:0.00, width:NaN, height:NaN)
Button is interactable: True
PointerDownEvent target: Button Play (x:0.00, y:0.00, width:NaN, height:NaN) world rect: (x:0.00, y:0.00, width:NaN, height:NaN)
PointerUpEvent target: Button Play (x:0.00, y:0.00, width:NaN, height:NaN) world rect: (x:0.00, y:0.00, width:NaN, height:NaN)
The button click event was not triggered.

.UXML

<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/UI/MenuStyles.uss?fileID=7433441132597879392&amp;guid=446f70e76c5306241815d1b7f67264e1&amp;type=3#MenuStyles" />
<engine:VisualElement name="LeftSection" style="flex-grow: 1; background-color: rgb(0, 0, 0); width: 45%; height: 100%; margin-left: 50px;">
    <engine:VisualElement name="Buttons" style="flex-grow: 1; justify-content: center; padding-left: 20%; padding-right: 20%; padding-top: 20%; padding-bottom: 20%;">
        <engine:Button text="Play" name="Play" class="menu-button" />
        <engine:Button text="Settings" name="Settings" class="menu-button" />
        <engine:Button text="Rotate" name="Rotate" class="menu-button" />
        <engine:Button text="Exit" name="Exit" class="menu-button" />
    </engine:VisualElement>
</engine:VisualElement>
</engine:UXML>

UPDATE

When I create a UIdocument in the code along with a button I can check that it's clicked however when I tried to load my visualtree element it appears as my UI is unable to load.

Below is the code I tried TestClick2() creates a UIdoc in code and TestClick3 is using my visualTree and custom Menu.UXML. I don't understand why my TestClick2() functions fine, but my TestClick3() fails playmode testing.

    [UnityTest]
public IEnumerator TestClick2()
{

    bool wasClicked = false;
    Button btn = new Button { name = "foobar" };
    btn.RegisterCallback<ClickEvent>(_ => wasClicked = true);
    GameObject hostGameObject = new GameObject();
    UIDocument uiDoc = hostGameObject.AddComponent<UIDocument>();
    uiDoc.panelSettings = ScriptableObject.CreateInstance<PanelSettings>();
    uiDoc.rootVisualElement.Add(btn);
    yield return null;

    using (ClickEvent clkEvt = ClickEvent.GetPooled())
    {
        clkEvt.target = btn;
        btn.SendEvent(clkEvt);
    }

    Assert.IsTrue(wasClicked);

}
[UnityTest]
public IEnumerator TestClick3()
{
    var uiDocument = new GameObject().AddComponent<UIDocument>();
    // Load your specific UXML file
    var visualTree = Resources.Load<VisualTreeAsset>("Menu");
    if (visualTree != null)
    {
        uiDocument.
            visualTreeAsset = visualTree;
    }
    if (visualTree == null)
    {
        Debug.LogError("Visual Tree is null. Could nor load from resources");
    }

    yield return null;

    root = uiDocument.rootVisualElement;



    yield return null;

    startButton = root.Q<Button>("Play");
    if (startButton == null)
    {
        Debug.LogError("Play button was not found.");
    }
    Debug.Log("startButton is: " + startButton);
    Assert.NotNull(startButton, "start button null");

    bool wasClicked = false;

    startButton.SetEnabled(true);
    startButton.style.display = DisplayStyle.Flex;
    

    startButton.RegisterCallback<ClickEvent>(_ => wasClicked = true);
    yield return null;

    using (ClickEvent clkEvt = ClickEvent.GetPooled())
    {
        clkEvt.target = startButton;
        startButton.SendEvent(clkEvt);
    }

    Assert.IsTrue(wasClicked);

}
2
  • 1
    Why are there NaN values for the with/height of the button and parent? In general though: The button onclick is part of the UIToolkit itself and not a functionality you should be writing Unit tests for ... It is tested already in the Unit tests of UIToolkit .. you should focus your own tests rather on the things you implement Commented Feb 28 at 20:26
  • Problem is I wanted to make sure my new scene loads after clicking the start button, but I found out my button is never clicked when I run my playmode test so I changed my unit test just to focus on the clicking. Additionally, when I included a check for the active scene my next scene didn't load. Also I'm not sure why height and width of the button and parent are appearing as NaN values. I tried specifying the size of the buttons size to be 100%, in the UI builder, but still get the same result. Commented Feb 28 at 21:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.