Automate Player Input with Unity Test Runner and NSubstitute

The player paddle on the left moves vertically with 🔼/🔽 keyboard input from a human. Can this be automated? 🤖
My TDD “Pong Clone” utilizes NSubstitute for automated player input testing.

It’s a Pong clone, but made with TDD 💻

This winter, I wanted to make a simple game in Unity using TDD (Test-driven Development) methodologies. Since my professional background is in test automation, I thought it would be fun to “virtually collaborate” with a YouTuber by letting them handle the gameplay code in the form of tutorial videos. With software development, the collaboration possibilities are vast and abundant. So why not try something new? By following Zigurous’s “How to make Pong in Unity” series, I could direct my efforts into writing and automating test cases instead of coding gameplay logic from the ground up.

Setting up NSubstitute for Unity ✅

Before we dive into the code, I should note that I used a Unity-specific version of NSubstitute, which is fully up-to-date with the mainline version, and also compatible with recent versions of the Unity editor. If you’re using this article as a technical reference, be sure to read the library’s setup instructions. New references need to be added to your assembly definition before running tests inside the Unity editor.

NSubstitute requires additional assembly definition references inside Unity, so be sure to add them!

Refactoring the PlayerInput script ♻️

Now that we’ve taken care of the setup specifics, let’s dive into the player input code. The developer’s original MonoBehavior combines player input with paddle movement inside PlayerPaddle.cs (GitHub). This works fine when we expect a human to move the player paddle up and down with a keyboard. However, if we want to automate player input for Unity test cases, we need to refactor by separating the input code from the paddle movement code. When we do this, both real and simulated input can interface with the code that moves the player paddle up and down.

Refactoring the PlayerPaddle script ♻️

We’ll make another small modification in the interest of testing, this time to the PlayerPaddle script. But first, let’s better understand the relationship it has with our new, refactored PlayerInput script.

Mocking PlayerPaddle’s input with substitution 🥸

With NSubstitute, we can “mock” the IPlayerInput interface containing the VerticalDirection() method. Let’s take a look at PlayerPaddleTests, and the UnitySetUp method SetupPlayerPaddle().

Running all tests inside the Unity editor with Test Runner.

Simulating PlayerInput with Unity Test Runner 🕹️

Pong paddles have three states: moving down, moving up, and not moving at all. Each of these can be tested using Nsubstitute’s Returns() method by passing in the desired paddle direction. Let’s take a look at the code that checks if the player paddle moves upwards when our test instructs it to do so.

Game over, the automation robots win? 🤖

In this article, we looked at simulating player input with Unity Test Runner. Since it’s not always desirable to have a human perform testing manually, using NSubstitute to mock player input inside a Unity test case is a relatively straightforward approach to automating player input. By separating player input from paddle movement, we were able to use common C# features including interfaces and property setters to our testing advantage.

Is your team hiring?

I’m Jordan, a Game Test Automation & Unity Tools Developer based in The Bay Area, California. 🌉 I can help your team achieve their test automation goals, improve code quality and increase developer satisfaction. Contact me directly! 📧

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store