/// <summary>
        /// Run the specified testCases, rootSuite, test, context and reportToMonitor.
        /// </summary>
        /// <param name="testCases">Test cases.</param>
        /// <param name="rootSuite">Root suite.</param>
        /// <param name="test">Test.</param>
        /// <param name="context">Context.</param>
        /// <param name="reportToMonitor">Report to monitor.</param>
        /// <remarks>
        /// This is actual the code that executes the test cases.
        ///
        /// It uses the MonoDevelop built-in .NET remoting helper to execute the code of <seealso cref="XUnitTestRunner"/> in a separate process.
        ///
        /// If any debugging is required, simply comment out the remoting part, and call <seealso cref="XUnitTestRunner"/> directly,
        /// so that the code executes inside MonoDevelop.
        /// </remarks>
        UnitTestResult Run(List <XUnitTestCase> testCases, XUnitAssemblyTestSuite rootSuite, IExecutableTest test, TestContext context, bool reportToMonitor = true)
        {
#if EASY_DEBUGGING
            using (var session = test.CreateExecutionSession(reportToMonitor)) {
                var runner           = new XUnitRunner.XUnitRunner();
                var localTestMonitor = new LocalTestMonitor(context, rootSuite, rootSuite.Name, false);

                string[] nameFilter = new string[testCases.Count];
                for (var i = 0; i < testCases.Count; ++i)
                {
                    nameFilter[i] = testCases[i].TestInfo.Id;
                }

                var path = rootSuite.AssemblyPath;
                runner.Execute(path, nameFilter, localTestMonitor);
                return(session.Result);
            }
#else
            using (var session = test.CreateExecutionSession(reportToMonitor)) {
                using (var runner = new ExternalTestRunner()) {
                    runner.Connect(XUnitVersion.XUnit2, context.ExecutionContext.ExecutionHandler).Wait();
                    var localTestMonitor = new LocalTestMonitor(context, rootSuite, rootSuite.Name, false);

                    string[] nameFilter = new string[testCases.Count];
                    for (var i = 0; i < testCases.Count; ++i)
                    {
                        nameFilter[i] = testCases[i].TestInfo.Id;
                    }

                    var path = rootSuite.AssemblyPath;
                    var supportAssemblies = new List <string>();
                    var crashLogFile      = Path.GetTempFileName();
                    runner.Run(localTestMonitor, nameFilter, path, "", supportAssemblies, null, null, crashLogFile).Wait();
                }
                return(session.Result);
            }
#endif
        }
예제 #2
0
        internal UnitTestResult RunUnitTest(UnitTest test, string suiteName, string pathName, string testName, TestContext testContext)
        {
            var runnerExe = GetCustomConsoleRunnerCommand();

            if (runnerExe != null)
            {
                return(RunWithConsoleRunner(runnerExe, test, suiteName, pathName, testName, testContext));
            }

            ExternalTestRunner runner       = (ExternalTestRunner)Runtime.ProcessService.CreateExternalProcessObject(typeof(ExternalTestRunner), testContext.ExecutionContext, UserAssemblyPaths);
            LocalTestMonitor   localMonitor = new LocalTestMonitor(testContext, test, suiteName, testName != null);

            ITestFilter filter = null;

            if (test != null)
            {
                if (test is UnitTestGroup)
                {
                    filter = new TestNameFilter(CollectTests((UnitTestGroup)test));
                }
                else
                {
                    filter = new TestNameFilter(test.TestId);
                }
            }
            else
            {
                NUnitCategoryOptions categoryOptions = (NUnitCategoryOptions)test.GetOptions(typeof(NUnitCategoryOptions));
                if (categoryOptions.EnableFilter && categoryOptions.Categories.Count > 0)
                {
                    string[] cats = new string [categoryOptions.Categories.Count];
                    categoryOptions.Categories.CopyTo(cats, 0);
                    filter = new CategoryFilter(cats);
                    if (categoryOptions.Exclude)
                    {
                        filter = new NotFilter(filter);
                    }
                }
            }

            RunData rd = new RunData();

            rd.Runner       = runner;
            rd.Test         = this;
            rd.LocalMonitor = localMonitor;
            testContext.Monitor.CancelRequested += new TestHandler(rd.Cancel);

            UnitTestResult result;

            try {
                if (string.IsNullOrEmpty(AssemblyPath))
                {
                    string msg = GettextCatalog.GetString("Could not get a valid path to the assembly. There may be a conflict in the project configurations.");
                    throw new Exception(msg);
                }
                System.Runtime.Remoting.RemotingServices.Marshal(localMonitor, null, typeof(IRemoteEventListener));

                string testRunnerAssembly, testRunnerType;
                GetCustomTestRunner(out testRunnerAssembly, out testRunnerType);

                result = runner.Run(localMonitor, filter, AssemblyPath, "", new List <string> (SupportAssemblies), testRunnerType, testRunnerAssembly);
                if (testName != null)
                {
                    result = localMonitor.SingleTestResult;
                }
            } catch (Exception ex) {
                if (!localMonitor.Canceled)
                {
                    LoggingService.LogError(ex.ToString());
                    if (localMonitor.RunningTest != null)
                    {
                        RuntimeErrorCleanup(testContext, localMonitor.RunningTest, ex);
                    }
                    else
                    {
                        testContext.Monitor.ReportRuntimeError(null, ex);
                        throw;
                    }
                    result = UnitTestResult.CreateFailure(ex);
                }
                else
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Canceled"), null);
                }
            } finally {
                testContext.Monitor.CancelRequested -= new TestHandler(rd.Cancel);
                runner.Dispose();
                System.Runtime.Remoting.RemotingServices.Disconnect(localMonitor);
            }

            return(result);
        }
        internal UnitTestResult RunUnitTest(UnitTest test, string suiteName, string pathName, string testName, TestContext testContext)
        {
            var runnerExe = GetCustomConsoleRunnerCommand();

            if (runnerExe != null)
            {
                return(RunWithConsoleRunner(runnerExe, test, suiteName, pathName, testName, testContext));
            }

            var console = testContext.ExecutionContext.ConsoleFactory.CreateConsole(
                OperationConsoleFactory.CreateConsoleOptions.Default.WithTitle(GettextCatalog.GetString("Unit Tests")));

            ExternalTestRunner runner = new ExternalTestRunner(Path.GetDirectoryName(AssemblyPath));

            runner.ProcessExecutionArchitecture = AssemblyUtilities.GetProcessExecutionArchitectureForAssembly(AssemblyPath);
            runner.Connect(NUnitVersion, testContext.ExecutionContext.ExecutionHandler, console).Wait();
            LocalTestMonitor localMonitor = new LocalTestMonitor(testContext, test, suiteName, testName != null);

            string[] filter = null;
            if (test != null)
            {
                if (test is UnitTestGroup && NUnitVersion == NUnitVersion.NUnit2)
                {
                    filter = CollectTests((UnitTestGroup)test);
                }
                else if (test.TestId != null)
                {
                    filter = new string [] { test.TestId };
                }
            }

            RunData rd = new RunData();

            rd.Runner       = runner;
            rd.Test         = this;
            rd.LocalMonitor = localMonitor;

            var cancelReg = testContext.Monitor.CancellationToken.Register(rd.Cancel);

            UnitTestResult result;
            var            crashLogFile = Path.GetTempFileName();

            try {
                if (string.IsNullOrEmpty(AssemblyPath))
                {
                    string msg = GettextCatalog.GetString("Could not get a valid path to the assembly. There may be a conflict in the project configurations.");
                    throw new Exception(msg);
                }

                string testRunnerAssembly, testRunnerType;
                GetCustomTestRunner(out testRunnerAssembly, out testRunnerType);

                testContext.Monitor.CancellationToken.ThrowIfCancellationRequested();

                var supportAssemblies = new List <string> (GetSupportAssembliesAsync().Result);
                result = runner.Run(localMonitor, filter, AssemblyPath, "", supportAssemblies, testRunnerType, testRunnerAssembly, crashLogFile).Result;
                if (testName != null)
                {
                    result = localMonitor.SingleTestResult;
                }

                ReportCrash(testContext, crashLogFile);
            } catch (Exception ex) {
                if (ReportCrash(testContext, crashLogFile))
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Unhandled exception"), null);
                }
                else if (!localMonitor.Canceled)
                {
                    LoggingService.LogError(ex.ToString());
                    if (localMonitor.RunningTest != null)
                    {
                        RuntimeErrorCleanup(testContext, localMonitor.RunningTest, ex);
                    }
                    else
                    {
                        testContext.Monitor.ReportRuntimeError(null, ex);
                        throw;
                    }
                    result = UnitTestResult.CreateFailure(ex);
                }
                else
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Canceled"), null);
                }
            } finally {
                // Dispose the runner before the console, to make sure the console is available until the runner is disposed.
                runner.Disconnect().Wait();
                runner.Dispose();
                if (console != null)
                {
                    console.Dispose();
                }
                cancelReg.Dispose();
                File.Delete(crashLogFile);
            }

            return(result);
        }
        /// <summary>
        /// Run the specified testCases, rootSuite, test, context and reportToMonitor.
        /// </summary>
        /// <param name="testCases">Test cases.</param>
        /// <param name="rootSuite">Root suite.</param>
        /// <param name="test">Test.</param>
        /// <param name="context">Context.</param>
        /// <param name="reportToMonitor">Report to monitor.</param>
        /// <remarks>
        /// This is actual the code that executes the test cases.
        ///
        /// It uses the MonoDevelop built-in .NET remoting helper to execute the code of <seealso cref="XUnitTestRunner"/> in a separate process.
        ///
        /// If any debugging is required, simply comment out the remoting part, and call <seealso cref="XUnitTestRunner"/> directly,
        /// so that the code executes inside MonoDevelop.
        /// </remarks>
        UnitTestResult Run(List <XUnitTestCase> testCases, XUnitAssemblyTestSuite rootSuite, IExecutableTest test, TestContext context, bool reportToMonitor = true)
        {
#if EASY_DEBUGGING
            using (var session = test.CreateExecutionSession(reportToMonitor)) {
                var runner           = new XUnitRunner.XUnitRunner();
                var localTestMonitor = new LocalTestMonitor(context, rootSuite, rootSuite.Name, false);

                string[] nameFilter = new string[testCases.Count];
                for (var i = 0; i < testCases.Count; ++i)
                {
                    nameFilter[i] = testCases[i].TestInfo.Id;
                }

                var path = rootSuite.AssemblyPath;
                runner.Execute(path, nameFilter, localTestMonitor);
                return(session.Result);
            }
#else
            using (var session = test.CreateExecutionSession(reportToMonitor)) {
                using (var runner = new ExternalTestRunner()) {
                    runner.Connect(XUnitVersion.XUnit2, context.ExecutionContext.ExecutionHandler).Wait();
                    var localTestMonitor = new LocalTestMonitor(context, rootSuite, rootSuite.Name, false);

                    string[] nameFilter = new string[testCases.Count];
                    for (var i = 0; i < testCases.Count; ++i)
                    {
                        nameFilter[i] = testCases[i].TestInfo.Id;
                    }

                    var path = rootSuite.AssemblyPath;
                    var supportAssemblies = new List <string>();

                    RunData rd = new RunData();
                    rd.Runner       = runner;
                    rd.LocalMonitor = localTestMonitor;

                    var cancelReg = context.Monitor.CancellationToken.Register(rd.Cancel);

                    UnitTestResult result;
                    var            crashLogFile = Path.GetTempFileName();

                    try {
                        context.Monitor.CancellationToken.ThrowIfCancellationRequested();

                        runner.Run(localTestMonitor, nameFilter, path, "", supportAssemblies, null, null, crashLogFile).Wait();
                    } catch (Exception ex) {
                        if (!localTestMonitor.Canceled)
                        {
                            LoggingService.LogError(ex.ToString());
                            result = UnitTestResult.CreateFailure(ex);
                        }
                        else
                        {
                            result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Canceled"), null);
                        }
                    } finally {
                        // Dispose the runner before the console, to make sure the console is available until the runner is disposed.
                        runner.Dispose();
                        cancelReg.Dispose();
                        File.Delete(crashLogFile);
                    }
                }
                return(session.Result);
            }
#endif
        }
        internal UnitTestResult RunUnitTest(UnitTest test, string suiteName, string pathName, string testName, TestContext testContext)
        {
            var runnerExe = GetCustomConsoleRunnerCommand();

            if (runnerExe != null)
            {
                return(RunWithConsoleRunner(runnerExe, test, suiteName, pathName, testName, testContext));
            }
            var console = IdeApp.Workbench?.ProgressMonitors.ConsoleFactory.CreateConsole();
            ExternalTestRunner runner       = (ExternalTestRunner)Runtime.ProcessService.CreateExternalProcessObject(typeof(ExternalTestRunner), testContext.ExecutionContext, UserAssemblyPaths, console);
            LocalTestMonitor   localMonitor = new LocalTestMonitor(testContext, test, suiteName, testName != null);

            ITestFilter filter = null;

            if (test != null)
            {
                if (test is UnitTestGroup)
                {
                    filter = new TestNameFilter(CollectTests((UnitTestGroup)test));
                }
                else
                {
                    filter = new TestNameFilter(test.TestId);
                }
            }

            RunData rd = new RunData();

            rd.Runner       = runner;
            rd.Test         = this;
            rd.LocalMonitor = localMonitor;
            testContext.Monitor.CancelRequested += new TestHandler(rd.Cancel);

            UnitTestResult result;
            var            crashLogFile = Path.GetTempFileName();

            try {
                if (string.IsNullOrEmpty(AssemblyPath))
                {
                    string msg = GettextCatalog.GetString("Could not get a valid path to the assembly. There may be a conflict in the project configurations.");
                    throw new Exception(msg);
                }
                System.Runtime.Remoting.RemotingServices.Marshal(localMonitor, null, typeof(IRemoteEventListener));

                string testRunnerAssembly, testRunnerType;
                GetCustomTestRunner(out testRunnerAssembly, out testRunnerType);

                result = runner.Run(localMonitor, filter, AssemblyPath, "", new List <string> (SupportAssemblies), testRunnerType, testRunnerAssembly, crashLogFile);
                if (testName != null)
                {
                    result = localMonitor.SingleTestResult;
                }

                ReportCrash(testContext, crashLogFile);
            } catch (Exception ex) {
                if (ReportCrash(testContext, crashLogFile))
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Unhandled exception"), null);
                }
                else if (!localMonitor.Canceled)
                {
                    LoggingService.LogError(ex.ToString());
                    if (localMonitor.RunningTest != null)
                    {
                        RuntimeErrorCleanup(testContext, localMonitor.RunningTest, ex);
                    }
                    else
                    {
                        testContext.Monitor.ReportRuntimeError(null, ex);
                        throw;
                    }
                    result = UnitTestResult.CreateFailure(ex);
                }
                else
                {
                    result = UnitTestResult.CreateFailure(GettextCatalog.GetString("Canceled"), null);
                }
            } finally {
                File.Delete(crashLogFile);
                testContext.Monitor.CancelRequested -= new TestHandler(rd.Cancel);
                runner.Dispose();
                System.Runtime.Remoting.RemotingServices.Disconnect(localMonitor);
            }

            return(result);
        }