Nodachisoft Nodachisoft logo, Katana Sword Icon
  
@Amaji✎ Update December-27-2021

How to write and run Edit Mode test and Play Mode test code using Unity Testing Framework (UTF) in Unity

How to write and run Edit Mode test and Play Mode test code using Unity Testing Framework (UTF) in Unity

Abstract

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.

  1. Improve the quality of modules
  2. Clarification of module specification and behavior
  3. Easier refactoring of module implementation (in the future)
  4. Faster module development
  5. Check the behavior of Unity when it is upgraded

I'm sure there are many other benefits, but these are the ones I feel are worth mentioning.

Unity Testing Framework

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 Window -> Package Manager and click

Package Manager

In the Package Manager window menu, select Unity Registry from Packages: Select Unity Registry from the Packages: 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.

Search in Package Manager

If it already has a green check mark, it is already installed. If not, you can install it with the Install button.

Features

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.

Edit 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.

Play Mode

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.

How to run a test in Edit Mode

First, let's display the window to run the tests and view the list.

Select Window -> General -> Test Runner from the Unity Editor menu to open a window called Test Runner.

Test Runner

Pressing the Create EditMode Test Assembly Folder button will create a folder for creating test code in the location currently open in the project.

new Tests folder

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.

asmdef configuration

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.

EditrModeInspector

Check the Editor checkbox. (I think it's on by default)

Create new test code in Edit Mode

Next, let's create the test code.

From the Test Runner window Press the Create Test Script in current folder button.

Create NewTestScript

A new file NewTestScript.cs will be generated. Rename it appropriately.

The content of the code is as follows by default.

 
NewTestScript.cs
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.

Test Runner Test List

Right-click on the test you want to run in the window -> RUN You can run the test by selecting RUN.

As a result, a green check will appear, indicating that the test was successful.

Test Result

You can also run all the test code by clicking Run All at the top of the window.

Try to write normal NUnit test code

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)

 
NewTestScript.cs
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.

Test Error

You can use the following NUnit 3.0 Assert for your test code.

Here is an example.

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).

Checking test execution results and outputting debug logs

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.

Testcase Result

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.

How to write Nunit3

NUnit3 essentially uses Assert.That to write test code.

assert.that
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(){1,2,3}, Has.Member(2) ); 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

Reference to other modules from test code in Edit Mode and Play Mode.

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)

ErrorExample
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, right-click the Script folder -> Create -> Assembly Definition 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.

PlayTestAssembly

Now you can refer to the classes under the Script folder of your project from your test code.

Flow of running tests in Play Mode

We will check the flow of testing for the state of the game when it is run.

Sample project structure

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 Window -> General -> Test Runner from the Unity Editor menu.

Once the Test Runner window is open, select PlayMode and click Select Create PlayMode Test Assembly Folder, with the "Tests" folder selected from the project.

Create PlayMode Test Assembly Folder

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.

Right-click the Script folder -> Create -> Assembly Definition to create a new assembly definition file. (See the section "Reference to other modules from test code in Edit Mode and Play Mode" in this article.)

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.

 
SamplePlayTest.cs
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.

Websites and references that were very helpful.

Page History

date modification
none
 
 
Message sent

Thank you for your message.

Something error has occured!

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_eng
Name:
 
Replay To:
 
Message:
 
Back
Check the content!

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:
 
Reply To:
 
Message:
 
Enter a confirmation key to make sure that you are not operating from a Robot.
Confirmation Key is 95
Back
 / 
Go to Confirmation
Entry fields
Go to Confirmation

There are 5 articles that may be relevant!

System.Type.GetType returns null in Unity C# code

System.Type.GetType returns null in Unity C# code

#Unity#.net✎ 2022-1-11
System.Type.GetType returns null in Unity C# code
Table Of Contents
How to write and run Edit Mode test and Play Mode test code using Unity Testing Framework (UTF) in Unity
How to write and run Edit Mode test and Play Mode test code using Unity Testing Framework (UTF) in Unity
Abstract
Abstract
Unity Testing Framework
Unity Testing Framework
Features
Features
Edit Mode
Edit Mode
Play Mode
Play Mode
How to run a test in Edit Mode
How to run a test in Edit Mode
asmdef configuration
asmdef configuration
Create new test code in Edit Mode
Create new test code in Edit Mode
Try to write normal NUnit test code
Try to write normal NUnit test code
Checking test execution results and outputting debug logs
Checking test execution results and outputting debug logs
How to write Nunit3
How to write Nunit3
Reference to other modules from test code in Edit Mode and Play Mode.
Reference to other modules from test code in Edit Mode and Play Mode.
Flow of running tests in Play Mode
Flow of running tests in Play Mode
Sample project structure
Sample project structure
Websites and references that were very helpful.
Websites and references that were very helpful.
Page History
Page History
Nodachisoft © 2021