protected NUnitTestAdapter() { #if !NET35 AdapterVersion = typeof(NUnitTestAdapter).GetTypeInfo().Assembly.GetName().Version.ToString(); #else AdapterVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); #endif NUnitEngineAdapter = new NUnitEngineAdapter(); }
protected void Unload() { if (NUnitEngineAdapter == null) { return; } NUnitEngineAdapter.Dispose(); NUnitEngineAdapter = null; }
public void TestXmlFileNameGenerationNewOutputXmlFileForEachRun() { var logger = Substitute.For <ITestLogger>(); var settings = new AdapterSettings(logger); settings.Load("<RunSettings><NUnit><TestOutputXml>/my/work/dir</TestOutputXml><NewOutputXmlFileForEachRun>true</NewOutputXmlFileForEachRun></NUnit></RunSettings>"); var sut = new NUnitEngineAdapter(); sut.InitializeSettingsAndLogging(settings, logger); string path = sut.GetXmlFilePath("c:/", "assembly", "xml"); Assert.That(path, Is.EqualTo("c:/assembly.1.xml")); }
private void GenerateTestOutput(XmlNode testResults, string assemblyPath) { if (!Settings.UseTestOutputXml) { return; } string path = Path.Combine(TestOutputXmlFolder, $"{Path.GetFileNameWithoutExtension(assemblyPath)}.xml"); var resultService = NUnitEngineAdapter.GetService <IResultService>(); // Following null argument should work for nunit3 format. Empty array is OK as well. // If you decide to handle other formats in the runsettings, it needs more work. var resultWriter = resultService.GetResultWriter("nunit3", null); resultWriter.WriteResultFile(testResults, path); TestLog.Info($" Test results written to {path}"); }
public void Setup() { ctx = Substitute.For <IExecutionContext>(); var settings = Substitute.For <IAdapterSettings>(); settings.AssemblySelectLimit.Returns(10); ctx.Settings.Returns(settings); var engineAdapter = new NUnitEngineAdapter(); engineAdapter.Initialize(); ctx.EngineAdapter.Returns(engineAdapter); settings.DiscoveryMethod.Returns(DiscoveryMethod.Current); discovery = Substitute.For <IDiscoveryConverter>(); discovery.NoOfLoadedTestCases.Returns(1); discovery.IsDiscoveryMethodCurrent.Returns(true); discovery.LoadedTestCases.Returns(new List <TestCase> { new ("A", new Uri(NUnitTestAdapter.ExecutorUri), "line 23") });
// The Adapter is constructed using the default constructor. // We don't have any info to initialize it until one of the // ITestDiscovery or ITestExecutor methods is called. Each // Discover or Execute method must call this method. protected void Initialize(IDiscoveryContext context, IMessageLogger messageLogger) { NUnitEngineAdapter.Initialize(); TestLog = new TestLogger(messageLogger); Settings = new AdapterSettings(TestLog); NUnitEngineAdapter.InitializeSettingsAndLogging(Settings, TestLog); TestLog.InitSettings(Settings); try { Settings.Load(context); TestLog.Verbosity = Settings.Verbosity; InitializeForbiddenFolders(); SetCurrentWorkingDirectory(); } catch (Exception e) { TestLog.Warning("Error initializing RunSettings. Default settings will be used"); TestLog.Warning(e.ToString()); } }
private void RunAssembly(string assemblyPath, IGrouping <string, TestCase> testCases, TestFilter filter) { LogActionAndSelection(assemblyPath, filter); RestoreRandomSeed(assemblyPath); Dump = DumpXml.CreateDump(assemblyPath, testCases, Settings); try { var package = CreateTestPackage(assemblyPath, testCases); NUnitEngineAdapter.CreateRunner(package); CreateTestOutputFolder(); Dump?.StartDiscoveryInExecution(testCases, filter, package); // var discoveryResults = RunType == RunType.CommandLineCurrentNUnit ? null : NUnitEngineAdapter.Explore(filter); var discoveryResults = NUnitEngineAdapter.Explore(filter); Dump?.AddString(discoveryResults?.AsString() ?? " No discovery"); if (discoveryResults?.IsRunnable ?? true) { var discovery = new DiscoveryConverter(TestLog, Settings); discovery.Convert(discoveryResults, assemblyPath); if (!Settings.SkipExecutionWhenNoTests || discovery.AllTestCases.Any()) { var ea = ExecutionFactory.Create(this); ea.Run(filter, discovery, this); } else { TestLog.InfoNoTests(assemblyPath); } } else { TestLog.InfoNoTests(discoveryResults.HasNoNUnitTests, assemblyPath); } } catch (Exception ex) when(ex is BadImageFormatException || ex.InnerException is BadImageFormatException) { // we skip the native c++ binaries that we don't support. TestLog.Warning(" Assembly not supported: " + assemblyPath); } catch (FileNotFoundException ex) { // Probably from the GetExportedTypes in NUnit.core, attempting to find an assembly, not a problem if it is not NUnit here TestLog.Warning(" Dependent Assembly " + ex.FileName + " of " + assemblyPath + " not found. Can be ignored if not an NUnit project."); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning(" Exception thrown executing tests in " + assemblyPath, ex); } finally { Dump?.DumpForExecution(); try { NUnitEngineAdapter?.CloseRunner(); } catch (Exception ex) { // can happen if CLR throws CannotUnloadAppDomainException, for example // due to a long-lasting operation in a protected region (catch/finally clause). if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning($" Exception thrown unloading tests from {assemblyPath}", ex); } } }
public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger messageLogger, ITestCaseDiscoverySink discoverySink) { Initialize(discoveryContext, messageLogger); CheckIfDebug(); TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery starting"); // Ensure any channels registered by other adapters are unregistered CleanUpRegisteredChannels(); if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1) { TestLog.Error("Unexpected to discover tests in multiple assemblies when InProcDataCollectors specified in run configuration."); Unload(); return; } foreach (string sourceAssembly in sources) { string sourceAssemblyPath = Path.IsPathRooted(sourceAssembly) ? sourceAssembly : Path.Combine(Directory.GetCurrentDirectory(), sourceAssembly); TestLog.Debug("Processing " + sourceAssembly); if (Settings.DumpXmlTestDiscovery) { dumpXml = new DumpXml(sourceAssemblyPath); } try { var package = CreateTestPackage(sourceAssemblyPath, null); NUnitEngineAdapter.CreateRunner(package); var results = NUnitEngineAdapter.Explore(); dumpXml?.AddString(results.AsString()); if (results.IsRunnable) { int cases; using (var testConverter = new TestConverterForXml(TestLog, sourceAssemblyPath, Settings)) { var timing = new TimingLogger(Settings, TestLog); cases = ProcessTestCases(results, discoverySink, testConverter); timing.LogTime("Discovery/Processing/Converting:"); } TestLog.Debug($"Discovered {cases} test cases"); // Only save if seed is not specified in runsettings // This allows workaround in case there is no valid // location in which the seed may be saved. if (cases > 0 && !Settings.RandomSeedSpecified) { Settings.SaveRandomSeed(Path.GetDirectoryName(sourceAssemblyPath)); } } else { if (results.HasNoNUnitTests) { if (Settings.Verbosity > 0) { TestLog.Info("Assembly contains no NUnit 3.0 tests: " + sourceAssembly); } } else { TestLog.Info("NUnit failed to load " + sourceAssembly); } } } catch (NUnitEngineException e) { if (e.InnerException is BadImageFormatException) { // we skip the native c++ binaries that we don't support. TestLog.Warning("Assembly not supported: " + sourceAssembly); } else { TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, e); } } catch (BadImageFormatException) { // we skip the native c++ binaries that we don't support. TestLog.Warning("Assembly not supported: " + sourceAssembly); } catch (FileNotFoundException ex) { // Either the NUnit framework was not referenced by the test assembly // or some other error occurred. Not a problem if not an NUnit assembly. TestLog.Warning("Dependent Assembly " + ex.FileName + " of " + sourceAssembly + " not found. Can be ignored if not an NUnit project."); } catch (FileLoadException ex) { // Attempts to load an invalid assembly, or an assembly with missing dependencies TestLog.Warning("Assembly " + ex.FileName + " loaded through " + sourceAssembly + " failed. Assembly is ignored. Correct deployment of dependencies if this is an error."); } catch (TypeLoadException ex) { if (ex.TypeName == "NUnit.Framework.Api.FrameworkController") { TestLog.Warning(" Skipping NUnit 2.x test assembly"); } else { TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, ex); } } catch (Exception ex) { TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, ex); } finally { dumpXml?.DumpForDiscovery(); NUnitEngineAdapter?.CloseRunner(); } } TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery complete"); Unload(); }
public void StopRun() { NUnitEngineAdapter?.StopRun(); }
private NUnitTestFilterBuilder CreateTestFilterBuilder() { return(new (NUnitEngineAdapter.GetService <ITestFilterService>(), Settings)); }
private void RunAssembly(string assemblyPath, IGrouping <string, TestCase> testCases, TestFilter filter) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif string actionText = Debugger.IsAttached ? "Debugging " : "Running "; string selectionText = filter == null || filter == TestFilter.Empty ? "all" : "selected"; TestLog.Info(actionText + selectionText + " tests in " + assemblyPath); // No need to restore if the seed was in runsettings file if (!Settings.RandomSeedSpecified) { Settings.RestoreRandomSeed(Path.GetDirectoryName(assemblyPath)); } executionDumpXml = null; if (Settings.DumpXmlTestResults) { executionDumpXml = new DumpXml(assemblyPath); } try { var package = CreateTestPackage(assemblyPath, testCases); NUnitEngineAdapter.CreateRunner(package); CreateTestOutputFolder(); executionDumpXml?.AddString($"<NUnitDiscoveryInExecution>{assemblyPath}</NUnitExecution>\r\n\r\n"); var discoveryResults = NUnitEngineAdapter.Explore(filter); // _activeRunner.Explore(filter); executionDumpXml?.AddString(discoveryResults.AsString()); if (discoveryResults.IsRunnable) { var nunitTestCases = discoveryResults.TestCases(); using var testConverter = new TestConverter(TestLog, assemblyPath, Settings); var loadedTestCases = new List <TestCase>(); // As a side effect of calling TestConverter.ConvertTestCase, // the converter's cache of all test cases is populated as well. // All future calls to convert a test case may now use the cache. foreach (XmlNode testNode in nunitTestCases) { loadedTestCases.Add(testConverter.ConvertTestCase(new NUnitTestCase(testNode))); } TestLog.Info($" NUnit3TestExecutor converted {loadedTestCases.Count} of {nunitTestCases.Count} NUnit test cases"); // If we have a TFS Filter, convert it to an nunit filter if (TfsFilter != null && !TfsFilter.IsEmpty) { // NOTE This overwrites filter used in call var filterBuilder = CreateTestFilterBuilder(); filter = filterBuilder.ConvertTfsFilterToNUnitFilter(TfsFilter, loadedTestCases); } if (filter == NUnitTestFilterBuilder.NoTestsFound) { TestLog.Info(" Skipping assembly - no matching test cases found"); return; } executionDumpXml?.AddString($"<NUnitExecution>{assemblyPath}</NUnitExecution>\r\n"); using (var listener = new NUnitEventListener(FrameworkHandle, testConverter, this)) { try { var results = NUnitEngineAdapter.Run(listener, filter); GenerateTestOutput(results.TopNode, assemblyPath); } catch (NullReferenceException) { // this happens during the run when CancelRun is called. TestLog.Debug(" Null ref caught"); } } } else { TestLog.Info(discoveryResults.HasNoNUnitTests ? " NUnit couldn't find any tests in " + assemblyPath : " NUnit failed to load " + assemblyPath); } } catch (BadImageFormatException) { // we skip the native c++ binaries that we don't support. TestLog.Warning(" Assembly not supported: " + assemblyPath); } catch (NUnitEngineException e) { if (e.InnerException is BadImageFormatException) { // we skip the native c++ binaries that we don't support. TestLog.Warning(" Assembly not supported: " + assemblyPath); } throw; } catch (FileNotFoundException ex) { // Probably from the GetExportedTypes in NUnit.core, attempting to find an assembly, not a problem if it is not NUnit here TestLog.Warning(" Dependent Assembly " + ex.FileName + " of " + assemblyPath + " not found. Can be ignored if not an NUnit project."); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning(" Exception thrown executing tests in " + assemblyPath, ex); } finally { executionDumpXml?.Dump4Execution(); try { NUnitEngineAdapter?.CloseRunner(); } catch (Exception ex) { // can happen if CLR throws CannotUnloadAppDomainException, for example // due to a long-lasting operation in a protected region (catch/finally clause). if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning($" Exception thrown unloading tests from {assemblyPath}", ex); } } }