public void SetupPersistentListeners(object runner) { UnityEventTools.AddPersistentListener((UnityEvent <ITest>)runner.GetType().GetField("testStartedEvent", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(runner), new UnityAction <ITest>(test => { if (!(test is TestMethod)) { return; } ourLogger.Verbose("TestStarted : {0}", test.FullName); var internalEvent = new TestInternalEvent(TestEventsSender.GetIdFromNUnitTest(test), "", 0, Status.Running, TestEventsSender.GetIdFromNUnitTest(test.Parent)); TestEventReceived(new TestEvent(EventType.TestStarted, internalEvent)); }) ); UnityEventTools.AddPersistentListener((UnityEvent <ITestResult>)runner.GetType().GetField("testFinishedEvent", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(runner), new UnityAction <ITestResult>(result => { if (!(result.Test is TestMethod)) { return; } var internalEvent = TestEventsSender.GetTestResult(result); TestEventReceived(new TestEvent(EventType.TestFinished, internalEvent)); })); UnityEventTools.AddPersistentListener((UnityEvent <ITestResult>)runner.GetType().GetField("runFinishedEvent", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(runner), new UnityAction <ITestResult>(result => { var internalEvent = new TestInternalEvent("", "", 0, Status.Success, ""); TestEventReceived(new TestEvent(EventType.RunFinished, internalEvent)); })); }
public void TryLaunchUnitTests() { try { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var testEditorAssembly = assemblies .FirstOrDefault(assembly => assembly.GetName().Name.Equals("UnityEditor.TestRunner")); var testEngineAssembly = assemblies .FirstOrDefault(assembly => assembly.GetName().Name.Equals("UnityEngine.TestRunner")); if (testEditorAssembly == null || testEngineAssembly == null) { ourLogger.Verbose( "Could not find UnityEditor.TestRunner or UnityEngine.TestRunner assemblies in current AppDomain"); return; } var launcherTypeString = myLaunch.TestMode == TestMode.Edit ? "UnityEditor.TestTools.TestRunner.EditModeLauncher" : "UnityEditor.TestTools.TestRunner.PlaymodeLauncher"; var launcherType = testEditorAssembly.GetType(launcherTypeString); if (launcherType == null) { string testEditorAssemblyProperties = testEditorAssembly.GetTypes().Select(a => a.Name).Aggregate((a, b) => a + ", " + b); throw new NullReferenceException($"Could not find {launcherTypeString} among {testEditorAssemblyProperties}"); } var filterType = testEngineAssembly.GetType("UnityEngine.TestTools.TestRunner.GUI.TestRunnerFilter"); if (filterType == null) { string testEngineAssemblyProperties = testEngineAssembly.GetTypes().Select(a => a.Name).Aggregate((a, b) => a + ", " + b); throw new NullReferenceException($"Could not find \"UnityEngine.TestTools.TestRunner.GUI.TestRunnerFilter\" among {testEngineAssemblyProperties}"); } var filter = Activator.CreateInstance(filterType); var fieldInfo = filter.GetType().GetField("testNames", BindingFlags.Instance | BindingFlags.Public); fieldInfo = fieldInfo ?? filter.GetType().GetField("names", BindingFlags.Instance | BindingFlags.Public); if (fieldInfo == null) { ourLogger.Verbose("Could not find testNames field via reflection"); return; } var testNameStrings = (object)myLaunch.TestNames.ToArray(); fieldInfo.SetValue(filter, testNameStrings); if (myLaunch.TestMode == TestMode.Play) { PlayModeSupport.PlayModeLauncherRun(filter, launcherType, testEditorAssembly, testEngineAssembly); } else { object launcher; if (UnityUtils.UnityVersion >= new Version(2018, 1)) { var enumType = testEngineAssembly.GetType("UnityEngine.TestTools.TestPlatform"); if (enumType == null) { ourLogger.Verbose("Could not find TestPlatform field via reflection"); return; } var assemblyProviderType = testEditorAssembly.GetType("UnityEditor.TestTools.TestRunner.TestInEditorTestAssemblyProvider"); var testPlatformVal = 2; // All = 255, // 0xFF, EditMode = 2, PlayMode = 4, if (assemblyProviderType != null) { var assemblyProvider = Activator.CreateInstance(assemblyProviderType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { Enum.ToObject(enumType, testPlatformVal) }, null); ourLogger.Log(LoggingLevel.INFO, assemblyProvider.ToString()); launcher = Activator.CreateInstance(launcherType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { filter, assemblyProvider }, null); } else { launcher = Activator.CreateInstance(launcherType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { filter, Enum.ToObject(enumType, testPlatformVal) }, null); } } else { launcher = Activator.CreateInstance(launcherType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new[] { filter }, null); } var runnerField = launcherType.GetField("m_EditModeRunner", BindingFlags.Instance | BindingFlags.NonPublic); if (runnerField == null) { ourLogger.Verbose("Could not find runnerField via reflection"); return; } var runner = runnerField.GetValue(launcher); SupportAbort(runner); if (!AdviseTestStarted(runner, "m_TestStartedEvent", test => { if (!(test is TestMethod)) { return; } ourLogger.Verbose("TestStarted : {0}", test.FullName); var tResult = new TestResult(TestEventsSender.GetIdFromNUnitTest(test), string.Empty, 0, Status.Running, TestEventsSender.GetIdFromNUnitTest(test.Parent)); TestEventsSender.TestStarted(myLaunch, tResult); })) { return; } if (!AdviseTestFinished(runner, "m_TestFinishedEvent", result => { if (!(result.Test is TestMethod)) { return; } var res = TestEventsSender.GetTestResult(result); TestEventsSender.TestFinished(myLaunch, TestEventsSender.GetTestResult(res)); })) { return; } if (!AdviseSessionFinished(runner, "m_RunFinishedEvent", result => { TestEventsSender.RunFinished(myLaunch); })) { return; } var runMethod = launcherType.GetMethod("Run", BindingFlags.Instance | BindingFlags.Public); if (runMethod == null) { ourLogger.Verbose("Could not find runMethod via reflection"); return; } //run! runMethod.Invoke(launcher, null); } } catch (Exception e) { ourLogger.Error(e, "Exception while launching Unity Editor tests."); } }