New Input System doesn't work

I tried to do simple input testing with InputTestFixture like in this doc but it seems like it's not working. Here is my code:

            var keyboard = InputSystem.AddDevice<Keyboard>();

            var shiftAction = new InputAction("apaya", binding: "<Keyboard>/shift", interactions: "Hold");
            shiftAction.Enable();

            _input.Press(keyboard.shiftKey);

            using (var trace = new InputActionTrace())
            {
                trace.SubscribeTo(shiftAction);
                _input.currentTime = 0.1f;

                var actions = trace.ToArray();

                Debug.Log("kon" + actions.Length); // returns 0
            }

            float timeOut = 0f;
            while (!keyboard.shiftKey.isPressed && timeOut < 4f)
            {
                yield return null;
                timeOut += Time.deltaTime;
            }
            Assert.IsTrue(keyboard.shiftKey.isPressed); // this returns false

did I do something wrong?

Seems like not working => means what exactly?

I have no idea what's behind the Press function but I'm expecting the var actions length to be 1 or isPressed to be true

Can you check if your "keyboard" reference is identical to the value of Keyboard.current? I've never had to "add" a keyboard, and I think you're adding a second one which is likely not in use.

1 Like

[quote=“halley1”, post:4, topic: 903864]
Can you check if your “keyboard” reference is identical to the value of Keyboard.current? I’ve never had to “add” a keyboard, and I think you’re adding a second one which is likely not in use.
[/quote]
I did Debug.Log($"compare: {keyboard.deviceId} with: {Keyboard.current.deviceId}"); and it’s just the same.
Anyway what’s the use of currentTime ?

I think I accidentally solved the issue and I have no idea why. This script works.

        var keyboard = InputSystem.AddDevice<Keyboard>();
        var action1 = new InputAction("action1", binding: "<Keyboard>/shift", interactions: "Hold");

        action1.Enable();
        Press(keyboard.shiftKey);

        using (var trace = new InputActionTrace())
        {
            trace.SubscribeTo(action1);
            //currentTime = 0.1f;

            action1.Disable();
            var actions = trace.ToArray();

            Debug.Log("1. " + keyboard.shiftKey.isPressed); // returns true

            Assert.That(actions.Length, Is.EqualTo(1)); // returns 1
        }

Anyone can explain?

So I found that it worked if I did

[TestFixture]
public class DummyTest : InputTestFixture

but not if I instantiate it like

[TestFixture]
class MyTestFixture
{
    private InputTestFixture input = new InputTestFixture();
}

Still don't get it :face_with_spiral_eyes:

Another issue was if it's IEnumerator it doesn't work.

    [UnityTest]
    public IEnumerator Keyboard_ShiftClicked()
    {
        var keyboard = InputSystem.AddDevice<Keyboard>();

        var action1 = new InputAction("action1", binding: "<Keyboard>/shift", interactions: "Hold");

        action1.Enable();
        Press(keyboard.shiftKey);


        using (var trace = new InputActionTrace())
        {
            trace.SubscribeTo(action1);
            //currentTime = 0.1f;

            action1.Disable();
            var actions = trace.ToArray();

            Debug.Log("1. " + keyboard.shiftKey.isPressed); // returns false

            Assert.That(actions.Length, Is.EqualTo(1)); // returns 0
        }
        yield return null;
    }

while this works

    [Test]
    public void Keyboard_ShiftClicked()
    {
        var keyboard = InputSystem.AddDevice<Keyboard>();

        var action1 = new InputAction("action1", binding: "<Keyboard>/shift", interactions: "Hold");

        action1.Enable();
        Press(keyboard.shiftKey);

        using (var trace = new InputActionTrace())
        {
            trace.SubscribeTo(action1);
            //currentTime = 0.1f;

            action1.Disable();
            var actions = trace.ToArray();

            Debug.Log("1. " + keyboard.shiftKey.isPressed); // returns true

            Assert.That(actions.Length, Is.EqualTo(1)); // returns 1
        }
    }

with async

    [Test]
    public async void Keyboard_ShiftClicked()
    {
        await UniTask.Delay(3000);
        var keyboard = InputSystem.AddDevice<Keyboard>();

        var action1 = new InputAction("action1", binding: "<Keyboard>/shift", interactions: "Hold");

        action1.Enable();
        Press(keyboard.shiftKey);

        using (var trace = new InputActionTrace())
        {
            trace.SubscribeTo(action1);
            //currentTime = 0.1f;

            action1.Disable();
            var actions = trace.ToArray();

            Debug.Log("1. " + keyboard.shiftKey.isPressed); // returns true

            Assert.That(actions.Length, Is.EqualTo(1)); // AssertionException: Expected: 1 But was:  0

        }

    }

why this test has no solid result?

async void is fire-and-forget, so the test runner will think the test is already complete after the first await. You need to use async Task for the test runner to wait for the entire async method to complete. (And you need to use experimental v2 to get that to work.)

I don't know anything about your other questions, sorry.

Hey @Kalita2127 !

Make sure to call InputSystem.Update() after the Press(keyboard.shiftKey); command.

Something like this:

using System.Collections;
using NUnit.Framework;
using UnityEngine.InputSystem;
using UnityEngine.TestTools;

public class NewTestScript : InputTestFixture
{
    Keyboard keyboard;

    [UnityTest]
    public IEnumerator NewTestScriptWithEnumeratorPasses()
    {
        Press(keyboard.shiftKey);
        InputSystem.Update();

        Assert.That(keyboard.shiftKey.isPressed, Is.True);

        yield return null;
    }

    public override void Setup()
    {
        base.Setup();
        keyboard = InputSystem.AddDevice<Keyboard>();
    }

    public override void TearDown()
    {
        base.TearDown();
    }
}

If you would like to test the Hold interaction:

[UnityTest]
    public IEnumerator NewTestScript1WithEnumeratorPasses()
    {
        var action = new InputAction("test", binding: "<Keyboard>/shift", interactions: "Hold");
        action.Enable();

        using (var trace = new InputActionTrace(action))
        {
            Press(keyboard.shiftKey);
            InputSystem.Update();

            Assert.That(trace, Started<HoldInteraction>(action, keyboard.shiftKey));

            trace.Clear();
        }

        yield return null;
    }

[quote=“halley1”, post:4, topic: 903864]
Can you check if your “keyboard” reference is identical to the value of Keyboard.current? I’ve never had to “add” a keyboard, and I think you’re adding a second one which is likely not in use.
[/quote]
[quote=“noeddie”, post:12, topic: 903864]
Hey @Kalita2127 !

Make sure to call InputSystem.Update() after the Press(keyboard.shiftKey); command.

Something like this:

using System.Collections;
using NUnit.Framework;
using UnityEngine.InputSystem;
using UnityEngine.TestTools;

public class NewTestScript : InputTestFixture
{
    Keyboard keyboard;

    [UnityTest]
    public IEnumerator NewTestScriptWithEnumeratorPasses()
    {
        Press(keyboard.shiftKey);
        InputSystem.Update();

        Assert.That(keyboard.shiftKey.isPressed, Is.True);

        yield return null;
    }

    public override void Setup()
    {
        base.Setup();
        keyboard = InputSystem.AddDevice<Keyboard>();
    }

    public override void TearDown()
    {
        base.TearDown();
    }
}

If you would like to test the Hold interaction:

[UnityTest]
    public IEnumerator NewTestScript1WithEnumeratorPasses()
    {
        var action = new InputAction("test", binding: "<Keyboard>/shift", interactions: "Hold");
        action.Enable();

        using (var trace = new InputActionTrace(action))
        {
            Press(keyboard.shiftKey);
            InputSystem.Update();

            Assert.That(trace, Started<HoldInteraction>(action, keyboard.shiftKey));

            trace.Clear();
        }

        yield return null;
    }

[/quote]

Thank you so much guys for your help! I got it working with the (Whatever_device).current combined with InputSystem.Update after each interactions.
Anyway happy new years! :smile: