<PackageReference Include="NUnit" Version="3.7.1" />

NUnitTestAssemblyRunner

Implementation of ITestAssemblyRunner
using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Execution; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Threading; namespace NUnit.Framework.Api { public class NUnitTestAssemblyRunner : ITestAssemblyRunner { private static Logger log = InternalTrace.GetLogger("DefaultTestAssemblyRunner"); private ITestAssemblyBuilder _builder; private ManualResetEvent _runComplete = new ManualResetEvent(false); private TextWriter _savedOut; private TextWriter _savedErr; public ITest LoadedTest { get; set; } public ITestResult Result { get { if (TopLevelWorkItem != null) return TopLevelWorkItem.Result; return null; } } public bool IsTestLoaded => LoadedTest != null; public bool IsTestRunning { get { if (TopLevelWorkItem != null) return TopLevelWorkItem.State == WorkItemState.Running; return false; } } public bool IsTestComplete { get { if (TopLevelWorkItem != null) return TopLevelWorkItem.State == WorkItemState.Complete; return false; } } private IDictionary<string, object> Settings { get; set; } private WorkItem TopLevelWorkItem { get; set; } private TestExecutionContext Context { get; set; } public NUnitTestAssemblyRunner(ITestAssemblyBuilder builder) { _builder = builder; } public ITest Load(string assemblyName, IDictionary<string, object> settings) { Settings = settings; if (settings.ContainsKey("RandomSeed")) Randomizer.InitialSeed = (int)settings["RandomSeed"]; return LoadedTest = _builder.Build(assemblyName, settings); } public ITest Load(Assembly assembly, IDictionary<string, object> settings) { Settings = settings; if (settings.ContainsKey("RandomSeed")) Randomizer.InitialSeed = (int)settings["RandomSeed"]; return LoadedTest = _builder.Build(assembly, settings); } public int CountTestCases(ITestFilter filter) { if (LoadedTest == null) throw new InvalidOperationException("The CountTestCases method was called but no test has been loaded"); return CountTestCases(LoadedTest, filter); } public ITest ExploreTests(ITestFilter filter) { if (LoadedTest == null) throw new InvalidOperationException("The ExploreTests method was called but no test has been loaded"); if (filter == TestFilter.Empty) return LoadedTest; return new TestAssembly(LoadedTest as TestAssembly, filter); } public ITestResult Run(ITestListener listener, ITestFilter filter) { RunAsync(listener, filter); WaitForCompletion(-1); return Result; } public void RunAsync(ITestListener listener, ITestFilter filter) { log.Info("Running tests"); if (LoadedTest == null) throw new InvalidOperationException("The Run method was called but no test has been loaded"); _runComplete.Reset(); CreateTestExecutionContext(listener); TopLevelWorkItem = WorkItemBuilder.CreateWorkItem(LoadedTest, filter, true); TopLevelWorkItem.InitializeContext(Context); TopLevelWorkItem.Completed += OnRunCompleted; StartRun(listener); } public bool WaitForCompletion(int timeout) { return _runComplete.WaitOne(timeout); } public void StopRun(bool force) { if (IsTestRunning) { Context.ExecutionStatus = ((!force) ? TestExecutionStatus.StopRequested : TestExecutionStatus.AbortRequested); Context.Dispatcher.CancelRun(force); } } private void StartRun(ITestListener listener) { _savedOut = Console.Out; _savedErr = Console.Error; Console.SetOut(new TextCapture(Console.Out)); Console.SetError(new EventListenerTextWriter("Error", Console.Error)); if (!Debugger.IsAttached && Settings.ContainsKey("DebugTests") && (bool)Settings["DebugTests"]) try { Debugger.Launch(); } catch (NotImplementedException) { TopLevelWorkItem.MarkNotRunnable("Debugger unavailable on this platform."); return; } Context.Dispatcher.Start(TopLevelWorkItem); } private void CreateTestExecutionContext(ITestListener listener) { Context = new TestExecutionContext(); if (Settings.ContainsKey("DefaultTimeout")) Context.TestCaseTimeout = (int)Settings["DefaultTimeout"]; if (Settings.ContainsKey("StopOnError")) Context.StopOnError = (bool)Settings["StopOnError"]; Context.Listener = listener; Context.Dispatcher = new SimpleWorkItemDispatcher(); } private void OnRunCompleted(object sender, EventArgs e) { Console.SetOut(_savedOut); Console.SetError(_savedErr); _runComplete.Set(); } private int CountTestCases(ITest test, ITestFilter filter) { if (!test.IsSuite) return 1; int num = 0; foreach (ITest test2 in test.Tests) { if (filter.Pass(test2)) num += CountTestCases(test2, filter); } return num; } } }