InputTestFixture issues - NullReferenceException in InputStateBuffers

Does anyone have experience using InputTestFixture to test input? I am trying to test how my player controller responds to gamepad input. The code below seems to work or fail inconsistently. Sometimes the test will run perfectly, and then the next time I run the same test (without any changes) I get a NullReferenceException in line 19 when I try to set the gamepad (full stack trace at the bottom). Is there some configuration I am doing incorrectly?

For reference I am using Input System 1.10.0 and Test Framework 1.4.5 in Unity 2022.3.36f1 on Mac OS.

    [UnityTest]
    public IEnumerator TestMove0()
    {
        Vector3 pos = new Vector3(-5,-4,0);
        GameObject player = GameObject.Instantiate(playerPrefab, pos, Quaternion.identity);
        rigidbody = player.GetComponent<Rigidbody2D>();

        Gamepad gamepad = InputSystem.AddDevice<Gamepad>();

        Assert.That(rigidbody.position.x, Is.EqualTo(pos.x).Within(0.01));
        Assert.That(rigidbody.position.y, Is.EqualTo(pos.y).Within(0.01));

        yield return new WaitForFixedUpdate();

        Assert.That(rigidbody.position.x, Is.EqualTo(pos.x).Within(0.01));
        Assert.That(rigidbody.position.y, Is.EqualTo(pos.y).Within(0.01));
        
        // move to the right for 1s
        Set(gamepad.leftStick, new Vector2(1,0));
        InputSystem.Update();

        yield return new WaitForSeconds(1);

        Assert.That(rigidbody.position.x, Is.EqualTo(pos.x + 5).Within(0.01));
        Assert.That(rigidbody.position.y, Is.EqualTo(pos.y).Within(0.01));
    }

The full stack trace shows that a low-level buffer doesn’t appear to have been allocated.

---
System.NullReferenceException : Object reference not set to an instance of an object
---
  at UnityEngine.InputSystem.LowLevel.InputStateBuffers+DoubleBuffers.GetFrontBuffer (System.Int32 deviceIndex) [0x00000] in Library/PackageCache/com.unity.inputsystem@1.10.0/InputSystem/State/InputStateBuffers.cs:78 
  at UnityEngine.InputSystem.LowLevel.InputStateBuffers.GetFrontBufferForDevice (System.Int32 deviceIndex) [0x00000] in Library/PackageCache/com.unity.inputsystem@1.10.0/InputSystem/State/InputStateBuffers.cs:132 
  at UnityEngine.InputSystem.InputControl.get_currentStatePtr () [0x00000] in Library/PackageCache/com.unity.inputsystem@1.10.0/InputSystem/Controls/InputControl.cs:801 
  at UnityEngine.InputSystem.LowLevel.DeltaStateEvent.From (UnityEngine.InputSystem.InputControl control, UnityEngine.InputSystem.LowLevel.InputEventPtr& eventPtr, Unity.Collections.Allocator allocator) [0x00078] in Library/PackageCache/com.unity.inputsystem@1.10.0/InputSystem/Events/DeltaStateEvent.cs:90 
  at UnityEngine.InputSystem.InputTestFixture.Set[TValue] (UnityEngine.InputSystem.InputControl`1[TValue] control, TValue state, System.Double time, System.Double timeOffset, System.Boolean queueEventOnly) [0x000a5] in Library/PackageCache/com.unity.inputsystem@1.10.0/Tests/TestFixture/InputTestFixture.cs:577 
  at TestMove+<TestMove0>d__5.MoveNext () [0x001c3] in Assets/Tests/PlayMode/TestMove.cs:56 
  at UnityEngine.TestTools.TestEnumerator+<Execute>d__7.MoveNext () [0x0003a] in Library/PackageCache/com.unity.test-framework@1.4.5/UnityEngine.TestRunner/NUnitExtensions/Attributes/TestEnumerator.cs:44 

I can’t help with the issue. Still I want to provide thought for input (no pun): what do you gain from testing input?

To me it sounds like one of the very last things I would consider putting under a test regime. Because you will notice it if something is off. And you do test your game regularly with all supported input devices anyway. Right? :wink:

Here your test assumes that 1s to the right equals 5 units along x in movement. Instead, you could supply your input controller with a move action event for 1s (or 5 units) and confirm that the position changed 5 units to the right.

This bypasses the input system entirely because the real worthwhile thing to test here is what your input controller does with the input, not that the input is correctly generated - you can trust that Input System is well tested to begin with.

Moreover, although I assume this is test code, you will certainly want to grab that “5 units” value from your player controller because during testing you will likely tweak such settings.

1 Like

I’ve just had the same exception stack in some of our InputTestFixture based tests. This happened after we updated a project from 2021.3.1 to 2021.3.45.

We were using an older version on the InputSystem (1.7.0). Updating to 1.12.0 resolved the issue for us.

1 Like