
When developing with Unity, as with any other application development, writing unit tests is a good idea. The following are some of the benefits of writing unit tests.
I'm sure there are many other benefits, but these are the ones I feel are worth mentioning.
As a testing framework usually used in Unity, UTF (Unity Testing Framework) is available.
UTF is based on NUnit, which is a testing framework for.
In Unity 2019.2 and later versions, UTF must be installed in your project as a separate package in order to use it. However, in Unity 2020.3 LTS, it was already installed in the template that I selected when creating the project from the Unity HUB. (Maybe some templates do not include it?).
Let's see if UTF is available in your environment. In the Unity menu, select
-> and click
In the Package Manager window menu, select Unity Registry
from
Select Unity Registry
from the in the Package Manager window menu, and enter Test Framework
in the search bar at the top right of the window.
The test frameworks will appear in the list.
If it already has a green check mark, it is already installed. If not, you can install it with the
button.By installing UTF and writing the test code, you can run unit tests using Unity functions. You don't need to include the test validation code in the production program every time. You can verify the module functions and check the results without having to include the test validation code in the production program.
UTF has two execution modes. There are two execution modes in UTF: Edit Mode and Play Mode.
You can run the test in Edit Mode, which is the mode in which you are editing the Unity Editor. This is useful because you don't have to run the game every time you want to run a test.
This mode allows you to run tests based on the state of the game when the project is played (run).
If you add the [UnityTest]
attribute, the test code will be executed as a coroutine.
First, let's display the window to run the tests and view the list.
Select
-> -> from the Unity Editor menu to open a window called Test Runner.
Pressing the
button will create a folder for creating test code in the location currently open in the project.
In this "Tests" folder, a file with the extension asmdef
is created by default, Tests.asmdef
. This is called the assembly definition file and describes the configuration of a feature called Assembly Definition (or adf for short) in Unity, where you can define the dependencies of your tests on assemblies to make the minimum necessary DLL calls.
In the assembly definition file (asmdef file), you need to add references to the assemblies that are required to run the tests. Also, if the test mode is Edit Mode, the test script under this folder should be set to run in Edit Mode.
When you select the asmdef file in the Unity Editor, the inspector will display You can set the assembly and execution platform to be referenced by the test code.
Check the Editor checkbox. (I think it's on by default)
Next, let's create the test code.
From the Test Runner window Press the
button.
A new file NewTestScript.cs
will be generated. Rename it appropriately.
The content of the code is as follows by default.
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
public class NewTestScript
{
// A Test behaves as an ordinary method
[Test]
public void NewTestScriptSimplePasses()
{
// Use the Assert class to test conditions
}
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
// `yield return null;` to skip a frame.
[UnityTest]
public IEnumerator NewTestScriptWithEnumeratorPasses()
{
// Use the Assert class to test conditions.
// Use yield to skip a frame.
yield return null;
}
}
There are two methods with Attributes: [Test]
and [UnityTest]
.
These two methods are the test code.
These two methods are the test code, and you can check and run them from the list in the
These two methods are the test codes, and you can check and run them from the list on the Test Runner window.
Right-click on the test you want to run in the window ->
You can run the test by selecting .As a result, a green check will appear, indicating that the test was successful.
You can also run all the test code by clicking
at the top of the window.Let's try to write a normal NUnit code that can be used for C# development regardless of Unity.
For reference, we will create two tests with the [Test]
Attribute.
You can run them in both Edit Mode and Play Mode.
Create a test case as follows (rewrite the previous test code)
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
public class NewTestScript
{
[Test]
public void Test1_Equal() {
Debug.Log("Here is my first Test!");
Assert.That( 5*20, Is.EqualTo(100));
}
[Test]
public void Test2_Equal() {
Debug.Log("Here is my second Test!");
Assert.That(3, Is.InRange(5,10));
}
}
When you run it, you will see that the test case for Test2_Equal
has failed.
You can use the following NUnit 3.0 Assert for your test code.
Here is an example.
Assert.That(100, Is.EqualTo(5 * 20));
If the number 100
is the same as 5 * 20
, then the verification is OK.
Assert Function of NUnit 2 (Classic Model)
You can still use the validation code for tests using the Assert feature (Classic Model) of NUnit 2, but the new NUnit feature is simpler to write tests with, and the new features are not (for backward compatibility?) applicable in the future. However, since the new NUnit features are simple to write tests with and the new features (due to backward compatibility?) will not be applied in the future when writing with the Classic Model, the official recommendation seems to be to write NUnit 3~.
For a list of the features of NUnit's Classic Model Assertions, click here (nunit.org official)](https://docs.nunit.org/articles/nunit/writing-tests/assertions/assertion-models/classic.html).
You can check the status and debug log output of a successful or failed test from the Unity Test Runner window. and debug log output.
Let's try to select a failed case in Test Runner.
If we click on the Test2_Equals test case to check it, we see That` outputs the contents of the comparison that failed.
You can also see the contents of Debug.Log
written in the test case here.
NUnit3 essentially uses Assert.That
to write test code.
Assert.That( Result , Expected Constraint );
This section describes how to write constraints (Constraint) that are often used.
Examples | Meaning of the Examples |
---|---|
Assert.That( a, Is.EqualTo( 2 )); | a is equals to 2 |
Assert.That( b, Is.InRange( 5,10)); | 5 <= b <= 10 |
Assert.That( new List |
List(1,2,3) has an element 2 |
Assert.That( c, Is.Not.EqualTo(3) ); | c is not equals to 3 |
Assert.That( d, Is.EqualTo(1).Or.EqualTo(2)); | d is 1 OR 2 |
Assert.That( e, Is.GreaterThan(3).And.LessThan(5) | 3 <= e AND e <= 5 |
For example, when checking functionality in another script from Edit Mode, you may not be able to reference (or resolve) the class properly. (The same applies to Play Mode tests)
Assets\NodachiFramework\common\unity_util\Tests\OperateHierarchyTest.cs(6,7): error CS0246: The type or namespace name 'NodachiFramework' could not be found (are you missing a using directive or an assembly reference?)
Create an assembly definition file (asmdef file) for the project and set up a reference from the assembly definition file for testing.
For example, your game's Asset folder has the following folder structure and you want to test "CommonUtil.cs".
Script
+- CommonUtil.cs
Tests
+- EditTest
| +- MyEditTestAssembly.asmdef
| +- SampleEditTest.cs
|
+- PlayTest
+- PlayTestAssembly.asmdef
+- SamplePlayTest.cs
Assume that Script dir contains the various scripts used in the game project. We will create a new assembly definition file directly under Script.
From within Unity's Project,
the Script folder -> -> to create a new assembly definition file.From the inspector of the PlayTestAssembly.asmdef
you created for testing, click
From the button in Assembly Definition References.
Add the Assembly Definition that you just created under Script.
Now you can refer to the classes under the Script folder of your project from your test code.
We will check the flow of testing for the state of the game when it is run.
Suppose you have the following project structure.
Resources
+- Prehabs
+- Bomb
Script
+- BombBehavior.cs
The Bomb prefab has the script "BombBehavior.cs" attached to it, and It will explode after some time! It is assumed to be a simple one. This time, we will test the behavior of BombBehavior.cs.
Create a Tests folder directly under the project for confirmation. (You can put it anywhere you like.)
Resources
+- Prehabs
+- Bomb
Script
+- BombBehavior.cs
Tests
Open a window called Test Runner by selecting
-> -> from the Unity Editor menu.Once the Test Runner window is open, select
and click Select , with the "Tests" folder selected from the project.
A new folder "Tests/Tests" will be created, and we renamed it to "Tests/PlayTests".
Resources
+- Prehabs
+- Bomb
Script
+- BombBehavior.cs
Tests
+- PlayTests
+- PlayTests.asmdef
We want to test the contents of the "BombBehavior.cs" script under the Script folder. Create an assembly definition under Script folder so that we can refer to it in our test code.
Reference to other modules from test code in Edit Mode and Play Mode" in this article.)
the Script folder -> -> to create a new assembly definition file. (See the section "Resources
+- Prehabs
+- Bomb
Script
+- BombBehavior.cs
+- MyGameAssembly.asmdef
Tests
+- PlayTests
+- PlayTests.asmdef
Open the inspector of "PlayTests.asmdef" and add "MyGameAssembly.asmdef" directly under Script to "Assembly Definitiono Reference".
Then, in the PlayTests folder, create "SamplePlayTest.cs" to write the test code.
Resources
+- Prehabs
+- Bomb
Script
+- BombBehavior.cs
Tests
+- PlayTests
+- PlayTests.asmdef
+- SamplePlayTest.cs
I wrote the following code.
public class UnityPlayModeTest
{
[UnityTest]
public IEnumerator BombTimer_Success()
{
GameObject bombPrehab = MonoBehaviour.Instantiate (
Resources.Load<GameObject>("Prehabs/Bomb"),
new Vector3( 0.0f, 0.0f, 1.0f),
Quaternion.identity);
BombBehavior bombBehavior = bombPrehab.GetComponent<BombBehavior>();
// (A) The bomb hasn't exploded yet.
Assert.That( bombBehavior.isExploded(), Is.EqualTo(false) );
yield return new WaitForSeconds(5.0f);
// (B) It was 5 seconds, so the bomb is exploding.
Assert.That( bombBehavior.isExploded(), Is.EqualTo(true) );
GameObject.Destroy(bombBehavior.gameObject);
yield return null;
}
}
The method BombTimer_Success
in this test code creates a prefab of Prehabs/Bomb
in the test scene and checks its behavior.
The Bomb prefab will explode in 3 seconds, and you can check if it is exploding or not with the isExploded()
method, True/False.
In the test case, we check that it is not exploding in line 11 (A), and check that it is exploding in line 15 (B).
Now you can test from TestRunner, just like in Edit Mode.
When you run it, the test scene will start up and you will see the results after a while.
The test code is called as a coroutine, and the behavior is checked before and after 5 seconds have passed.
date | modification |
---|---|
none |
Thank you for your message.
Sorry. The Error has occurred.We apologize for the inconvenience.Please try again in a few minutes or contact us via DM below.
Twitter:@NodachiSoft_engName:Send the following information to us. If you are happy with your submission, please click "Send". If you want to modify it, please click "Back".
Name: