playmode test clean up error, or how to disable real inputs

I’m having this error when performing unity Test TearDown :

MissingReferenceException while executing ‘performed’ callbacks of ‘Cursor/Cursor Position[/Mouse/position]’
UnityEngine.InputSystem.LowLevel.<>c__DisplayClass10_0:<set_onBeforeUpdate>b__0(NativeInputUpdateType)
UnityEngineInternal.Input.NativeInputSystem:NotifyBeforeUpdate(NativeInputUpdateType)

Quite similar, but different usage/context, to : [SOLVED] InvalidOperationException while executing 'performed' callbacks

My guess is the mouse inputs are still listen while everything is shutting down. I only manually created one gamepad. I guess the system adds the rest automatically while in play mode

_gamepadDevice = InputSystem.AddDevice<Gamepad>();

That is removed in the clean up

yield return null;```

Here is the asset corresponding

![5825182--617407--upload_2020-5-9_13-40-35.png|1333x224](upload://7fRmJRz8fmoRFuZ8YdX4mYE1p4T.png)

How can I avoid "real" inputs to be performed from the Input system, so just programmatic ones are taken into account.

Thanks

Hey,
Could you please file a bug report for this? We are currently trying to improve the user test support so it will help us to be aware of these issues.

I can, do you have a quick workaround in mind in the meantime ?
Something like InputSystem.DisableAutoDiscoveryAndClearAllDevicesInputs(); ? :slight_smile:

Tried something like that in the UnityTearDown, but it didn’t do the trick


IconsInputMap.Disable();
InputSystem.RemoveDevice(_gamepadDevice);

yield return null; //allow object call on destroy
IconsInputMap.Dispose();

And I can confirm that if you don’t touch the mouse during the test then the issue does not arrise.

EDIT : I figured which object was causing the issue while being destroyed. So that I had the opportunity to silence the error into a warning.

Though the question is still there. How to avoid my mouse/keyboard to interact with the game view when I want to be in control ?

The question could also arise during game if you want to disable devices.

To isolate the input system and put it in a known state, it’s best to use InputTestFixture. It’ll set up the input system with no devices and disconnected from platform input at the beginning of a test and will automatically clean it up at the end.

1 Like

Thanks for the hint, though I tried using InputTextFixture in playMode tests by creating an instance of it and input discovery is not disabled (mouse&keyaboard still interact)

I’m creating the instance in the [UnitySetUp]

InputTest = new InputTestFixture();
_gamepadDevice = InputSystem.AddDevice<Gamepad>();```

I tried a little check in the tear down as it is shown in the documentation

```csharp
        public IEnumerator TearDownUnity()
        {
            Assert.AreEqual(InputSystem.devices.Single(), _gamepadDevice);
         }

What could I be doing wrong ?

Reading the source code it appeared we have to call the Setup and Teardown manually.

It could be added to the documentation Input testing | Input System | 1.0.2

Alternatively, you can instantiate it in your fixture:

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

[SetUp]
public void SetUp() { input.Setup() }

[TearDown]
public void TearDown() { input.TearDown() }
}

It’s close to a working state now. However on teardown the InputSystem.devices list has discovered other devices, maybe it is expected ?

1 Like

Indeed, the docs are misleading there. Will push a fix. Thanks for the post.

That would be unexpected. And somewhat surprising. If correctly initialized (i.e. after its Setup() method has been called), InputTestFixture completely isolates the system and cuts it off from the native runtime that has the device discovery hooks. The only device “discoveries” that should surface during a test run are those made through the InputSystem API.

I’ll look into it further then. I’m only calling InputSystem.AddDevice once and after setup the device I created is alone as expected.

        private void SetupInputMock()
        {
            InputTest = new InputTestFixture();
            InputTest.Setup();
            _gamepadDevice = InputSystem.AddDevice<Gamepad>();
            Assert.AreEqual(InputSystem.devices.Single(), _gamepadDevice);

In Tear down the following fails

Assert.AreEqual(1, InputSystem.devices.Count, "Devices are "+InputSystem.devices.ToDelimitedString(";"));

            InputSystem.RemoveDevice(_gamepadDevice);
AssertionException: Devices are Gamepad:/Gamepad;Keyboard:/Keyboard;Gamepad:/Gamepad1
Expected: 1
But was: 3

Does this run before or after InputTestFixture.TearDown? The test fixture will nuke the entire input state (including any registered layouts, added devices, etc) and restore the “real” input system state. This also means you usually don’t have to perform any cleanup work. You can even fiddle with InputSettings and such and the fixture will automatically restore the pre-test conditions on completion.

This
Assert.AreEqual(1, InputSystem.devices.Count, "Devices are "+InputSystem.devices.ToDelimitedString(";"));
runs prior to the clean up where I’d expect to have only the test device added.

 public IEnumerator TearDownUnity()
        {
         
            Assert.AreEqual(1, InputSystem.devices.Count, "Devices are "+InputSystem.devices.ToDelimitedString(";"));
            InputSystem.RemoveDevice(_gamepadDevice);

            //Other clean up tasks are performed then finally
            yield return null;
            InputTest.TearDown();

        }

@Rene-Damm
Another related issue with InputTestFixture:

When running a test and it is canceled by user, (may occur on errors as well) the previous state of the Input System isn’t restored. Simple use case is :

  • Cancel a test with InputTestFixture
  • Launch my game in the editor just after, no inputs are generated.

If I close and reopen the editor then it works again.

Having exactly the same issue. Looks like TearDown does not happen.

1 Like

@spajus
semi-unrelated, but I’ve been having trouble with mocking inputs in InputTestFixtures and would be very grateful if you could show how you’ve managed it.

I’ve made a post here .

@Rene-Damm
Did you had the opportunity to look into that issue ?
It’s still reproducing in unity 2019.4.9f1 LTS and Input System 1.1.0-preview 1

Basically Input System mock is still operating and it does discover devices anymore. A simple way to reset it could do the trick. For now the only fix is to relaunch the editor.

For anyone coming here after Googling this issue: I solved this issue by disabling the fast enter play mode settings (Project Settings > Editor > Enter Play Mode Settings). Seems the input is reset on a domain reload. I found editing some code and letting it recompile would also force it to reset.