In this article, we’ll cover Unity’s built-in Test Framework package for unit testing.
This package allows developers to either do Test-Driven development or Unit Testing in general.
I’ll be doing the latter for this article in order to showcase the functionality Unity has put at our fingertips.
As always, the definitive information on this subject is Unity’s own documentation, which can be accessed here:
About Unity Test Framework
The Unity Test Framework (UTF) enables Unity users to test their code in both Edit Mode and Play Mode, and also on…
Per Unity’s documentation:
“UTF uses a Unity integration of NUnit library, which is an open-source unit testing library for .Net languages.
UTF currently uses NUnit version 3.5.
For more information about NUnit, see the official NUnit website and the NUnit documentation.”
The Test Framework Package
The Unity Test Framework package is most likely installed by default.
You can check by opening Package Manager > Packages: Unity Registry and scrolling down to “Test Framework”.
If it’s not installed, you can do so here.
Keeping Our Project in Order
In our project, we’ll want to keep our unit testing files separate from our game files.
Start by creating a new folder in the Project window called “Game” where all of our gameplay related (not UTF related) files will be stored.
NOTE: Disregard creating the “UnitTesting” folder that was shown above.
Test folders are created automatically using the TestRunner window in Unity.
Next, open and place the Test Runner window by going to Window > General > Test Runner.
Workflow: How to create a new test assembly
Unity Test Framework looks for a test inside any assembly that references NUnit. We refer to such assemblies as…
Per Unity’s documentation:
“Unity Test Framework looks for a test inside any assembly that references NUnit.
We refer to such assemblies as TestAssemblies.
The Test Runner UI can help you set up TestAssemblies.
Play Mode and Edit Mode tests need to be in separate assemblies.
In the Test Runner window, you will see an EditMode tab enabled by default, as well as a Create EditMode Test Assembly Folder button.
Click the button to create a Tests folder with a respective .asmdef file by default.”
Just like the documentation says, we’ll click the “Create EditMode Test Assembly Folder” button and then rename it to suit our taste.
I’ve called mine “UTF-EditorTests” for clarity.
If we navigate within this newly created folder, we can see the asmdef file that was created.
Under “Assembly Definition References” we can see references to “UnityEngine.TestRunner” and “UnityEditor.TestRunner”.
Note: The UnityEditor.TestRunner reference is only available for Edit Mode tests.
Below those is a reference to the nunit.framework.dll.
Creating an Assembly Definition (asmdef) File for the Game Folder
Because the UTF framework makes use of assembly definition (asmdef) files, we’ll need to create some ourself that it will reference for testing gameplay functionality.
In this small prototype example project, we’ll create a simple “Game” asmdef file in our Game folder.
In a more complex project, you will likely have many more asmdef files which you will need to reference when testing the functionality of a Unity project.
Referencing Game Assembly (asmdef) Files from Test Assembly Files
For the UTF assembly to “see” gameplay related classes and test their functionality, it will need a reference to the “Game” asmdef file.
As shown above, simply display the UTF asmdef file in the Inspector and lock the view for ease of use.
Then, navigate to the Game asmdef file and drag it into the UTF asmdef file under “Assembly Definition References”.
To save this reference, we need to click the “Apply” button at the bottom of the Inspector window for the UTF-EditorTests asmdef file (or whatever you named it).
Creating a Test Class/Script
To create our first test class, selected the UTF-EditorTests asmdef file and click the “Create Test Script in current folder” button.
Name it something useful if possible.
For demonstration purposes, I’ve named it something generic.
Open the newly created class in your IDE.
I’m using JetBrains Rider IDE, so it will look a bit different from Microsoft Visual Studio.
JetBrains Rider AI Assistant
As of the writing of this article (August 2023), AI implemented based on Large Language Models (LLMs) has become popular and, finally, useful!
So much so, that JetBrains and others are integrating AI LLMs into their IDEs.
While this can be a two-edged sword, for simple straight-forward questions it can be incredibly useful.
I simply highlighted the “[Test]” bit of code, right clicked and asked the AI assistant to “Explain” what I’ve highlighted.
The response is shown above and gives us a handy demonstration of using the “Assert” class as part of the Test Framework.
The provided example is a simple method that adds two numbers together that are “asserted” to always equal 15.
This is hard coded, but a similar test method in real-world usage would take in two values as parameters before performing this assertion.
We’d also want to avoid naming it something vague, as was done in this example.
If the answer is always expected to be 15, name it accordingly.
“public void SumOfNumbersIsFifteen(int num1, int num2)” for example.
We can see that AI in its current stage is great for giving us a direction for something basic, but we must refine the approach it provides.
Never let the AI do ALL of the thinking for you!
Just to let you see it in action, I’ve asked Rider’s AI Assistant to explain the “[UnitTest]” bit of code.
This time, no example was given but we still got some useful information out of it.
We’ll use the AI example code to demonstrate running a Unit Test in the Unity Editor.
Above I’ve copied it over into the default test method with the existing values which should return as valid.
Run the Test(s)
In the Test Runner window, select the test(s) you wish to run and click “Run Selected”.
We can see our “UTFEditorTest01” class which contains the AI generated test code returning with a valid result.
Back in ourUTFEditorTest01 class, let’s change the “y” value to 3.
5 + 3 = 8, not the asserted value of 15, so this test should fail.
And indeed, we can see that the test method now fails.
Edit Mode vs. Play Mode tests
Let's clarify a bit what Play Mode and Edit Mode test means from the Unity Test Framework perspective: Edit Mode tests…
Edit Mode VS Play Mode
Per Unity’s documentation:
“Edit Mode tests (also known as Editor tests) are only run in the Unity Editor and have access to the Editor code in addition to the game code.
With Edit Mode tests it is possible to test any of your Editor extensions using the UnityTest attribute.
For Edit Mode tests, your test code runs in the EditorApplication.update callback loop.
Note: You can also control entering and exiting Play Mode from your Edit Mode test.
This allows your test to make changes before entering Play Mode.”
The Edit Mode asmdef file should only target the Editor as a platform.
“You can run Play Mode tests as a standalone in a Player or inside the Editor.
Play Mode tests allow you to exercise your game code, as the tests run as coroutines if marked with the UnityTest attribute.”
In the next article, we’ll cover running unit tests in Play Mode.