You can run Play mode tests in a Platform-specific standalone Player. The [TestPlayerBuildModifier]
attribute provides a number of configurable options to control the properties of the Player built to run your tests.
You can change the BuildPlayerOptions for the test Player, to achieve custom behavior when running Play mode tests. Modifying the build options allows for changing the target location of the build as well as changing BuildOptions.
To modify the BuildPlayerOptions
, do the following:
ITestPlayerBuildModifier
TestPlayerBuildModifier
attribute on an assembly level.The following example demonstrates this:
using UnityEditor;
using UnityEditor.TestTools;
[assembly:TestPlayerBuildModifier(typeof(BuildModifier))]
public class BuildModifier : ITestPlayerBuildModifier
{
public BuildPlayerOptions ModifyOptions(BuildPlayerOptions playerOptions)
{
if (playerOptions.target == BuildTarget.iOS)
{
playerOptions.options |= BuildOptions.SymlinkLibraries; // Enable symlink libraries when running on iOS
}
playerOptions.options |= BuildOptions.AllowDebugging; // Enable allow Debugging flag on the test Player.
return playerOptions;
}
}
Note: When building the Player, it includes all TestPlayerBuildModifier
attributes across all loaded assemblies, independent of the currently used test filter. As the implementation references the UnityEditor
namespace, the code is typically implemented in an Editor only assembly, as the UnityEditor
namespace is not available otherwise.
It’s possible to use the Unity Editor to build the Player with tests but without running the tests. This allows for running the Player on another machine, for example. In this case, it is necessary to modify the Player to build and implement a custom handling of the test result.
You can use [TestPlayerBuildModifier]
to set the BuildOptions
to build the Player to a specific location but not run it. Combined with PostBuildCleanup, you can automatically exit the Editor on completion of the build. The following example demonstrates this:
using System;
using System.IO;
using System.Linq;
using Tests;
using UnityEditor;
using UnityEditor.TestTools;
using UnityEngine;
using UnityEngine.TestTools;
[assembly:TestPlayerBuildModifier(typeof(HeadlessPlayModeSetup))]
[assembly:PostBuildCleanup(typeof(HeadlessPlayModeSetup))]
namespace Tests
{
public class HeadlessPlayModeSetup : ITestPlayerBuildModifier, IPostBuildCleanup
{
private static bool s_RunningPlayerTests;
public BuildPlayerOptions ModifyOptions(BuildPlayerOptions playerOptions)
{
// Do not launch the player after the build completes.
playerOptions.options &= ~BuildOptions.AutoRunPlayer;
// Set the headlessBuildLocation to the output directory you desire. It does not need to be inside the project.
var headlessBuildLocation = Path.GetFullPath(Path.Combine(Application.dataPath, ".//..//PlayModeTestPlayer"));
var fileName = Path.GetFileName(playerOptions.locationPathName);
if (!string.IsNullOrEmpty(fileName))
{
headlessBuildLocation = Path.Combine(headlessBuildLocation, fileName);
}
playerOptions.locationPathName = headlessBuildLocation;
// Instruct the cleanup to exit the Editor if the run came from the command line.
// The variable is static because the cleanup is being invoked in a new instance of the class.
s_RunningPlayerTests = true;
return playerOptions;
}
public void Cleanup()
{
if (s_RunningPlayerTests && IsRunningTestsFromCommandLine())
{
// Exit the Editor on the next update, allowing for other PostBuildCleanup steps to run.
EditorApplication.update += () => { EditorApplication.Exit(0); };
}
}
private static bool IsRunningTestsFromCommandLine()
{
var commandLineArgs = Environment.GetCommandLineArgs();
return commandLineArgs.Any(value => value == "-runTests");
}
}
}
If the Editor is still running after the Play Mode tests have run, the Player tries to report the results back, using PlayerConnection, which has a reference to the IP address of the Editor machine, when built.
To implement a custom way of reporting the results of the test run, let one of the assemblies in the Player include a TestRunCallback
. At RunFinished
, it is possible to get the full test report as XML from the NUnit test result by calling result.ToXml(true)
. You can save the result and then save it on the device or send it to another machine as needed.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.