<PackageReference Include="NUnit" Version="3.0.0-rc-3" />

NUnitTestAssemblyRunner

Implementation of ITestAssemblyRunner
using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Execution; using System; using System.Collections; 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 AutoResetEvent _runComplete = new AutoResetEvent(false); private TextWriter _savedOut; private TextWriter _savedErr; private EventPump _pump; public static int DefaultLevelOfParallelism => Math.Max(Environment.ProcessorCount, 2); 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 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 settings) { Settings = settings; Randomizer.InitialSeed = GetInitialSeed(settings); return LoadedTest = _builder.Build(assemblyName, settings); } public ITest Load(Assembly assembly, IDictionary settings) { Settings = settings; Randomizer.InitialSeed = GetInitialSeed(settings); 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 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"); CreateTestExecutionContext(listener); TopLevelWorkItem = WorkItem.CreateWorkItem(LoadedTest, filter); TopLevelWorkItem.InitializeContext(Context); TopLevelWorkItem.Completed += OnRunCompleted; StartRun(listener); } public bool WaitForCompletion(int timeout) { return _runComplete.WaitOne(timeout, false); } public void StartRun(ITestListener listener) { _savedOut = Console.Out; _savedErr = Console.Error; Console.SetOut(new TextCapture(Console.Out)); Console.SetError(new TextCapture(Console.Error)); if (!Settings.Contains("SynchronousEvents") || !(bool)Settings["SynchronousEvents"]) { QueuingEventListener queuingEventListener = new QueuingEventListener(); Context.Listener = queuingEventListener; _pump = new EventPump(listener, queuingEventListener.Events); _pump.Start(); } if (!Debugger.IsAttached && Settings.Contains("DebugTests") && (bool)Settings["DebugTests"]) Debugger.Launch(); Context.Dispatcher.Dispatch(TopLevelWorkItem); } public void StopRun(bool force) { if (IsTestRunning) { Context.ExecutionStatus = ((!force) ? TestExecutionStatus.StopRequested : TestExecutionStatus.AbortRequested); if (force) Context.Dispatcher.CancelRun(); } } private void CreateTestExecutionContext(ITestListener listener) { Context = new TestExecutionContext(); if (Settings.Contains("DefaultTimeout")) Context.TestCaseTimeout = (int)Settings["DefaultTimeout"]; if (Settings.Contains("StopOnError")) Context.StopOnError = (bool)Settings["StopOnError"]; if (Settings.Contains("WorkDirectory")) Context.WorkDirectory = (string)Settings["WorkDirectory"]; else Context.WorkDirectory = Env.DefaultWorkDirectory; Context.Listener = listener; int levelOfParallelism = GetLevelOfParallelism(); if (levelOfParallelism > 0) { Context.Dispatcher = new ParallelWorkItemDispatcher(levelOfParallelism); if (LoadedTest.Properties.ContainsKey("ParallelScope")) Context.ParallelScope = ((ParallelScope)LoadedTest.Properties.Get("ParallelScope") & ~ParallelScope.Self); } else Context.Dispatcher = new SimpleWorkItemDispatcher(); } private void OnRunCompleted(object sender, EventArgs e) { if (_pump != null) _pump.Dispose(); 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; } private static int GetInitialSeed(IDictionary settings) { if (!settings.Contains("RandomSeed")) return new Random().Next(); return (int)settings["RandomSeed"]; } private int GetLevelOfParallelism() { if (!Settings.Contains("NumberOfTestWorkers")) { if (!LoadedTest.Properties.ContainsKey("LevelOfParallelism")) return DefaultLevelOfParallelism; return (int)LoadedTest.Properties.Get("LevelOfParallelism"); } return (int)Settings["NumberOfTestWorkers"]; } } }