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), test.Method.TypeInfo.Assembly.GetName().Name, "", 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));
            }));
        }
Beispiel #2
0
        private bool TryLaunchUnitTestsInAssembly(string[] testNames)
        {
            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(false);
                }

                var launcherTypeString = "UnityEditor.TestTools.TestRunner.EditModeLauncher";
                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(false);
                }
                fieldInfo.SetValue(filter, testNames);

                var clientController = ClientControllerWrapper.TryCreate(myLaunch.SessionId, myLaunch.ClientControllerInfo);
                clientController?.OnSessionStarted();

                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(false);
                    }

                    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
                    {
                        try
                        {
                            launcher = Activator.CreateInstance(launcherType,
                                                                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                                                                null, new[] { filter, Enum.ToObject(enumType, testPlatformVal) },
                                                                null);
                        }
                        catch (Exception) // Unity 2019.2+ with package com.unity.test-framework v 1.0.18 and 1.1.0 ctor was changed. in v 1.1.1 it was added back for compatibility
                        {
                            var apiFilterType      = testEditorAssembly.GetType("UnityEditor.TestTools.TestRunner.Api.Filter");
                            var apiFilter          = Activator.CreateInstance(apiFilterType);
                            var testNamesFieldInfo = apiFilter.GetType().GetField("testNames");
                            testNamesFieldInfo.SetValue(apiFilter, testNames);
                            var array = Array.CreateInstance(apiFilterType, 1);
                            array.SetValue(apiFilter, 0);
                            launcher = Activator.CreateInstance(launcherType, array, Enum.ToObject(enumType, testPlatformVal));
                        }
                    }
                }
                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(false);
                }

                var runner = runnerField.GetValue(launcher);
                SupportAbort(runner);

                var runLifetimeDef = Lifetime.Define(myConnectionLifetime);
                runLifetimeDef.Lifetime.OnTermination(() =>
                {
                    if (myConnectionLifetime.IsNotAlive)
                    {
                        TestEventsSender.RunFinished(myLaunch, new RunResult(false));
                    }
                });

                var runStarted = false;
                try
                {
                    if (!AdviseTestStarted(runner, "m_TestStartedEvent", test =>
                    {
                        if (!(test is TestMethod))
                        {
                            return;
                        }
                        ourLogger.Verbose("TestStarted : {0}", test.FullName);

                        var testId = TestEventsSender.GetIdFromNUnitTest(test);
                        var parentId = TestEventsSender.GetIdFromNUnitTest(test.Parent);
                        var tResult = new TestResult(testId, test.Method.TypeInfo.Assembly.GetName().Name, string.Empty, 0, Status.Running, parentId);

                        clientController?.OnTestStarted(testId);
                        TestEventsSender.TestStarted(myLaunch, tResult);
                    }))
                    {
                        return(false);
                    }

                    if (!AdviseTestFinished(runner, "m_TestFinishedEvent", result =>
                    {
                        if (!(result.Test is TestMethod))
                        {
                            return;
                        }

                        clientController?.OnTestFinished();
                        TestEventsSender.TestFinished(myLaunch, TestEventsSender.GetTestResult(result));
                    }))
                    {
                        return(false);
                    }

                    if (!AdviseSessionFinished(runner, "m_RunFinishedEvent", result =>
                    {
                        clientController?.OnSessionFinished();
                        runLifetimeDef.Terminate();
                        var runResult = new RunResult(Equals(result.ResultState, ResultState.Success));
                        TestEventsSender.RunFinished(myLaunch, runResult);
                    }))
                    {
                        return(false);
                    }

                    var runMethod = launcherType.GetMethod("Run", BindingFlags.Instance | BindingFlags.Public);
                    if (runMethod == null)
                    {
                        ourLogger.Verbose("Could not find runMethod via reflection");
                        return(false);
                    }

                    //run!
                    runMethod.Invoke(launcher, null);
                    runStarted = true;
                    return(true);
                }
                finally
                {
                    if (!runStarted)
                    {
                        runLifetimeDef.Terminate();
                    }
                }
            }
            catch (Exception e)
            {
                ourLogger.Error(e, "Exception while launching Unity Editor tests.");
                return(false);
            }
        }
Beispiel #3
0
        private void TryLaunchUnitTestsInAssembly(string[] testNames)
        {
            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;
                }
                fieldInfo.SetValue(filter, testNames);

                // todo: restore, once Unity fixes UnityEngine.TestTools.TestRunner.GUI.TestRunnerFilter.BuildNUnitFilter
                // Currently assemblyName filters are added with OR to testNames filers
//        var assemblyNamesFieldInfo = filter.GetType().GetField("assemblyNames", BindingFlags.Instance | BindingFlags.Public);
//        if (assemblyNamesFieldInfo == null)
//        {
//          ourLogger.Warn("Could not find assemblyNames field via reflection");
//          return;
//        }
//        assemblyNamesFieldInfo.SetValue(filter, new[] { assemblyName });

                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), test.Method.TypeInfo.Assembly.GetName().Name, 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.");
            }
        }