- Home /
How to Run Editor Test Runner test from editor script in 5.6?
Basically, I would like a post build script that runs all of our unit tests and prints out the results in the debug log. However, in Unity 5.6, I can not find any way of doing this programmatically (aside from the command line). Is there any way to trigger these tests from a custom editor script?
Answer by Tomek-Paszek · Apr 25, 2017 at 01:36 PM
The class is not public but if you really want to, you can reflect the Batch class and invoke it.
Answer by mplavcan · Apr 18, 2018 at 09:07 PM
Apologies for recognizing an old thread, but this is still the most relevant match in the answers database, even after a year, and I have additional detail to add to this approach:
Reflecting the code in Batch is not sufficient. Here' s an implementation of that:
static void RunAllUnitTests()
{
string testPlatform = "editmode";
string resultFilePath = "ManualRunUnitTestRun.xml";
string[] testFilters = { };
string[] testCategories = { };
var assembly = Assembly.Load("UnityEditor.TestRunner");
var batchType = assembly.GetType("UnityEditor.TestTools.TestRunner.Batch");
var runTestsMethod = batchType.GetMethod("RunTests", BindingFlags.Static | BindingFlags.NonPublic);
runTestsMethod.Invoke(null, new object[] {testPlatform, resultFilePath, testFilters, testCategories});
}
While this code does correctly run the unit tests, any invocation of Batch.RunTests() completes by quitting the editor. Until this is addressed, test runs cannot be automated.
(The automated quit is there because the command-line run of -editorTests, yes?)
Since the class is intentionally hidden, it's not a "bug", per se, but it is hindering automation of testing. I would like to see the quit behavior separated from the test run, so an automated build script could both run the tests and build the code, without need for multiple editor invocations.
Answer by chrpetry · Aug 03, 2018 at 08:35 AM
Is there any news on this?
I would also like to execute tests via script (right before a build script? :) )
A boolean result or a List of boolean test results would be great!
Answer by mityugovmaxim · Jul 23, 2019 at 11:42 AM
public static void RunTests(string[] _Categories, Action<ITestResult> _Finished = null)
{
var engineAssembly = Assembly.Load("UnityEngine.TestRunner");
var editorAssembly = Assembly.Load("UnityEditor.TestRunner");
Type filterType = engineAssembly.GetType("UnityEngine.TestTools.TestRunner.GUI.TestRunnerFilter");
FieldInfo filterCategories = filterType.GetField("categories");
object filter = Activator.CreateInstance(filterType);
filterCategories.SetValue(filter, _Categories);
Type launcherType = editorAssembly.GetType("UnityEditor.TestTools.TestRunner.EditModeLauncher");
MethodInfo launchMethod = launcherType.GetMethod("Run");
FieldInfo runnerField = launcherType.GetField("m_EditModeRunner", BindingFlags.NonPublic | BindingFlags.Instance);
object launcher = Activator.CreateInstance(launcherType, filter);
object runner = runnerField.GetValue(launcher);
Type runnerType = runner.GetType();
FieldInfo finishedField = runnerType.GetField("m_RunFinishedEvent", BindingFlags.NonPublic | BindingFlags.Instance);
object finishedCallback = finishedField.GetValue(runner);
Type finishedType = finishedCallback.GetType();
MethodInfo finishedSubscribe = finishedType.GetMethod("AddListener");
finishedSubscribe.Invoke(finishedCallback, new object[] { CreateAction(_Finished) });
launchMethod.Invoke(launcher, new object[] { });
}
That looks somewhat promising. Where is the "CreateAction()" function from? I can't find any assembly for this.
I am unable to execute the above code in 2018.3:
NullReferenceException: Object reference not set to an instance of an object
Also: ITestResult is an internal interface, so it would also need to be extracted via reflection. CreateAction() is probably unnecessary, as it could be handled a different way. It appears to be an extension method of $$anonymous$$ethodInfo:
Can you please explain how the above example addresses the existing issues?