public void AddHistoryEntry(string what, HistoryEntryVisibility visibility) { HistoryEntries.Add(new HistoryEntry { What = what, Visibility = visibility, When = DateTime.Now }); TestLog.Debug("History entry added for {0}. {1}What : {2}", ToString(), Environment.NewLine, what); }
public void InitializeForExecution(IRunContext runContext, IFrameworkHandle frameworkHandle) { TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution started"); RunContext = runContext; FrameworkHandle = frameworkHandle; VsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext); CleanUpRegisteredChannels(); TestLog.Debug("KeepAlive: " + runContext.KeepAlive); TestLog.Debug("UseVsKeepEngineRunning: " + Settings.UseVsKeepEngineRunning); bool enableShutdown = true; if (Settings.UseVsKeepEngineRunning) { enableShutdown = !runContext.KeepAlive; } if (VsTestFilter.IsEmpty) { if (!(enableShutdown && !runContext .KeepAlive)) // Otherwise causes exception when run as commandline, illegal to enableshutdown when Keepalive is false, might be only VS2012 { frameworkHandle.EnableShutdownAfterTestRun = enableShutdown; } } TestLog.Debug("EnableShutdown: " + enableShutdown); }
public TestFilter CheckVsTestFilter(TestFilter filter, IDiscoveryConverter discovery, IVsTestFilter vsTestFilter) { // If we have a VSTest TestFilter, convert it to an nunit filter if (vsTestFilter == null || vsTestFilter.IsEmpty) { return(filter); } TestLog.Debug( $"TfsFilter used, length: {vsTestFilter.TfsTestCaseFilterExpression?.TestCaseFilterValue.Length}"); // NOTE This overwrites filter used in call var filterBuilder = CreateTestFilterBuilder(); if (Settings.DiscoveryMethod == DiscoveryMethod.Current) { filter = Settings.UseNUnitFilter ? filterBuilder.ConvertVsTestFilterToNUnitFilter(vsTestFilter) : filterBuilder.ConvertTfsFilterToNUnitFilter(vsTestFilter, discovery); } else { filter = filterBuilder .ConvertTfsFilterToNUnitFilter(vsTestFilter, discovery.LoadedTestCases); } Dump?.AddString($"\n\nTFSFilter: {vsTestFilter.TfsTestCaseFilterExpression.TestCaseFilterValue}\n"); Dump?.DumpVSInputFilter(filter, "(At Execution (TfsFilter)"); return(filter); }
public void Initialize(IRunContext runContext, IFrameworkHandle frameworkHandle) { base.Initialize(runContext, frameworkHandle); TestLog.Info(string.Format("NUnit Adapter {0}: Test execution started", AdapterVersion)); RunContext = runContext; FrameworkHandle = frameworkHandle; TfsFilter = new TfsTestFilter(runContext); // Ensure any channels registered by other adapters are unregistered CleanUpRegisteredChannels(); TestLog.Debug("Keepalive: " + runContext.KeepAlive); TestLog.Debug("UseVsKeepEngineRunning: " + Settings.UseVsKeepEngineRunning); bool enableShutdown = true; if (Settings.UseVsKeepEngineRunning) { enableShutdown = !runContext.KeepAlive; } if (TfsFilter.IsEmpty) { if (!(enableShutdown && !runContext.KeepAlive)) // Otherwise causes exception when run as commandline, illegal to enableshutdown when Keepalive is false, might be only VS2012 { frameworkHandle.EnableShutdownAfterTestRun = enableShutdown; } } TestLog.Debug("EnableShutdown: " + enableShutdown.ToString()); }
private void TestSort <T>(T[] data, Predicate <T, T> connector, T[] expected, T[] loops) { List <Node <T, object> > actualLoopNodes; List <T> actual = TopologicalSorter.Sort(data, connector, out actualLoopNodes); T[] actualLoops = null; if (actualLoopNodes != null) { actualLoops = actualLoopNodes .Where(n => n.OutgoingConnectionCount != 0) .Select(n => n.Item) .ToArray(); } AssertEx.HasSameElements(expected, actual); AssertEx.HasSameElements(loops, actualLoops); List <NodeConnection <T, object> > removedEdges; List <T> sortWithRemove = TopologicalSorter.Sort(data, connector, out removedEdges); Assert.AreEqual(sortWithRemove.Count, data.Length); if (loops == null) { Assert.AreEqual(sortWithRemove.Count, actual.Count); for (int i = 0; i < actual.Count; i++) { Assert.AreEqual(sortWithRemove[i], actual[i]); } } else { TestLog.Debug("Loops detected"); } }
/// <summary> /// Find a document in the same group of a document, with a specified DocumentType. /// Returns : /// * the closest document (the document in the innermost group), if multiple documents are found in the group. /// * null, if no document with the correct DocumentType is found in the group. /// * the input argument, if this.DocumentTypeToProcess is not set /// /// E.g. find the edi document associated with an invoice, find the .ser file associated with an invoice etc. /// </summary> protected Document GetDocumentToProcessFromInputDocument(Document inputDocument) { if (inputDocument == null) { TestLog.Warning("Cannot find document to process because {0} is not a Document", inputDocument); return(null); } string documentTypeToProcess = DocumentTypeToProcess; if (String.IsNullOrEmpty(documentTypeToProcess)) { return(inputDocument); } if (inputDocument.DocumentType == documentTypeToProcess) { return(inputDocument); } List <Document> documentsMatchingDocType = inputDocument.FindDocumentsInMyGroupsByType(documentTypeToProcess, 0); // return the document in the innermost group : if (documentsMatchingDocType.Count > 0) { if (documentsMatchingDocType.Count > 1) { TestLog.Debug("Found {0} documents matching DocumentType={1} in this group. Returning the document in innermost group : {2}", documentsMatchingDocType.Count, documentTypeToProcess, documentsMatchingDocType[0].Name); } return(documentsMatchingDocType[0]); } // default : return(null); }
public override TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery) { if (!discovery.IsDiscoveryMethodCurrent) { return(filter); } if ((VsTestFilter == null || VsTestFilter.IsEmpty) && filter != TestFilter.Empty) { if (discovery.NoOfLoadedTestCasesAboveLimit) { TestLog.Debug("Setting filter to empty due to number of testcases"); filter = TestFilter.Empty; } else { var filterBuilder = CreateTestFilterBuilder(); filter = filterBuilder.FilterByList(discovery.LoadedTestCases); } } else if (VsTestFilter != null && !VsTestFilter.IsEmpty && !Settings.UseNUnitFilter) { var s = VsTestFilter.TfsTestCaseFilterExpression.TestCaseFilterValue; var scount = s.Split('|', '&').Length; if (scount > Settings.AssemblySelectLimit) { TestLog.Debug("Setting filter to empty due to TfsFilter size"); filter = TestFilter.Empty; } } return(filter); }
public void PerformanceTest() { string param1 = "'(string, object[])'"; string param2 = "'(Exception, string, object[])'"; TestLog.InfoRegion("Information logs"); TestLog.Info("Message for {0} log parameters.", param1); try { throw new InvalidOperationException("Exception text."); } catch (Exception e) { TestLog.Info(e, "Message for {0} log parameters.", param2); } TestLog.InfoRegion("Error logs"); TestLog.Error("Message for {0} log parameters.", param1); try{ throw new InvalidOperationException("Exception text."); } catch (Exception e) { TestLog.Error(e, "Message for {0} log parameters.", param2); } TestLog.DebugRegion("Debug logs"); TestLog.Debug("Message for {0} log parameters.", param1); try { throw new InvalidOperationException("Exception text."); } catch (Exception e) { TestLog.Debug(e, "Message for {0} log parameters.", param2); } TestLog.InfoRegion("Warning logs"); TestLog.Warning("Message for {0} log parameters.", param1); try { throw new InvalidOperationException("Exception text."); } catch (Exception e) { TestLog.Warning(e, "Message for {0} log parameters.", param2); } TestLog.InfoRegion("Fatal error logs"); TestLog.FatalError("Message for {0} log parameters.", param1); try { throw new InvalidOperationException("Exception text."); } catch (Exception e) { TestLog.FatalError(e, "Message for {0} log parameters.", param2); } }
/// <summary> /// Move document from outputContainer to doneContainer. /// </summary> /// <param name="portfolio"></param> /// <param name="outputContainer"></param> /// <param name="doneContainer"></param> protected void MoveDocumentToContainer(Document document, Container container) { System.Diagnostics.Debug.Assert(Transaction.Current != null, "Cannot execute out of a transaction"); if (container == null) { throw new ArgumentNullException("container", "The container must be non-null."); } TestLog.Debug("Moving " + document + " from " + document.Container + " to " + container); document.Container = container; }
private void SetRunTypeByStrings() { RunType = !Settings.DesignMode ? Settings.DiscoveryMethod == DiscoveryMethod.Legacy ? RunType.CommandLineLegacy : Settings.UseNUnitFilter ? RunType.CommandLineCurrentNUnit : RunType.CommandLineCurrentVSTest : RunType.Ide; TestLog.Debug($"Runtype: {RunType}"); }
public void TestCacheType(DomainConfiguration config, Type expectedType) { var d = Domain.Build(config); using (var s = d.OpenSession()) { var cacheType = s.EntityStateCache.GetType(); TestLog.Debug("Session CacheType: {0}", cacheType.Name); Assert.IsTrue(cacheType.IsOfGenericType(expectedType)); } d.DisposeSafely(); }
/// <summary> /// Called by the VisualStudio IDE when selected tests are to be run. Never called from TFS Build, except (at least 2022, probably also 2019) when vstest.console uses /test: then this is being used. /// </summary> /// <param name="tests">The tests to be run.</param> /// <param name="runContext">The RunContext.</param> /// <param name="frameworkHandle">The FrameworkHandle.</param> public void RunTests(IEnumerable <TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle) { Initialize(runContext, frameworkHandle); CheckIfDebug(); InitializeForExecution(runContext, frameworkHandle); RunType = RunType.Ide; TestLog.Debug("RunTests by IEnumerable<TestCase>. RunType = Ide"); var timing = new TimingLogger(Settings, TestLog); Debug.Assert(NUnitEngineAdapter != null, "NUnitEngineAdapter is null"); Debug.Assert(NUnitEngineAdapter.EngineEnabled, "NUnitEngineAdapter TestEngine is null"); var assemblyGroups = tests.GroupBy(tc => tc.Source); if (IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(assemblyGroups)) { TestLog.Error( "Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration."); Unload(); return; } foreach (var assemblyGroup in assemblyGroups) { var assemblytiming = new TimingLogger(Settings, TestLog); try { string assemblyName = assemblyGroup.Key; string assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName); var filterBuilder = CreateTestFilterBuilder(); var filter = filterBuilder.FilterByList(assemblyGroup); RunAssembly(assemblyPath, assemblyGroup, filter); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning("Exception thrown executing tests", ex); } assemblytiming.LogTime($"Executing {assemblyGroup.Key} time "); } timing.LogTime("Total execution time"); TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete"); Unload(); }
// NOTE: an earlier version of this code had a FilterBuilder // property. This seemed to make sense, because we instantiate // it in two different places. However, the existence of an // NUnitTestFilterBuilder, containing a reference to an engine // service caused our second-level tests of the test executor // to throw an exception. So if you consider doing this, beware! #endregion #region ITestExecutor Implementation /// <summary> /// Called by the Visual Studio IDE to run all tests. Also called by TFS Build /// to run either all or selected tests. In the latter case, a filter is provided /// as part of the run context. /// </summary> /// <param name="sources">Sources to be run.</param> /// <param name="runContext">Context to use when executing the tests.</param> /// <param name="frameworkHandle">Test log to send results and messages through.</param> public void RunTests(IEnumerable <string> sources, IRunContext runContext, IFrameworkHandle frameworkHandle) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif Initialize(runContext, frameworkHandle); TestLog.Debug("RunTests by IEnumerable<string>"); InitializeForExecution(runContext, frameworkHandle); if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1) { TestLog.Error("Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration."); Unload(); return; } SetRunTypeByStrings(); var builder = CreateTestFilterBuilder(); TestFilter filter = null; if (RunType == RunType.CommandLineCurrentNUnit) { var vsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext); filter = builder.ConvertVsTestFilterToNUnitFilter(vsTestFilter); } if (filter == null) { filter = builder.FilterByWhere(Settings.Where); } foreach (string assemblyName in sources) { try { string assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName); RunAssembly(assemblyPath, null, filter); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning("Exception thrown executing tests", ex); } } TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete"); Unload(); }
public void Can_Write_Debug_Message_With_Default_Verbosity() { // Given var log = new TestLog(); // When log.Debug("Hello World"); // Then Assert.Equal(Verbosity.Diagnostic, log.Verbosity); Assert.Equal(LogLevel.Debug, log.Level); Assert.Equal("Hello World", log.Message); }
public void Can_Write_Debug_Message_With_Custom_Verbosity() { // Given var log = new TestLog(); // When log.Debug(Verbosity.Quiet, "Hello World"); // Then Assert.Equal(Verbosity.Quiet, log.Verbosity); Assert.Equal(LogLevel.Debug, log.Level); Assert.Equal("Hello World", log.Message); }
public void RemoveWithException() { using (var session = Domain.OpenSession()) { A a; C c; using (var t = session.OpenTransaction()) { a = new A(); c = new C(); a.C = c; TestLog.Debug(a.Key.ToString()); TestLog.Debug(c.Key.ToString()); a.Remove(); Session.Current.SaveChanges(); } } }
/// <summary> /// Called by the VisualStudio IDE when selected tests are to be run. Never called from TFS Build. /// </summary> /// <param name="tests">The tests to be run.</param> /// <param name="runContext">The RunContext.</param> /// <param name="frameworkHandle">The FrameworkHandle.</param> public void RunTests(IEnumerable <TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif Initialize(runContext, frameworkHandle); TestLog.Debug("RunTests by IEnumerable<TestCase>"); InitializeForExecution(runContext, frameworkHandle); Debug.Assert(NUnitEngineAdapter != null, "NUnitEngineAdapter is null"); Debug.Assert(NUnitEngineAdapter.EngineEnabled, "NUnitEngineAdapter TestEngine is null"); var assemblyGroups = tests.GroupBy(tc => tc.Source); if (Settings.InProcDataCollectorsAvailable && assemblyGroups.Count() > 1) { TestLog.Error("Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration."); Unload(); return; } foreach (var assemblyGroup in assemblyGroups) { try { string assemblyName = assemblyGroup.Key; string assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName); var filterBuilder = CreateTestFilterBuilder(); var filter = filterBuilder.FilterByList(assemblyGroup); RunAssembly(assemblyPath, assemblyGroup, filter); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning("Exception thrown executing tests", ex); } } TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete"); Unload(); }
public void ToRecordsetTest() { using (var session = Domain.OpenSession()) { using (session.OpenTransaction()) { var a1 = new A(); var a2 = new A(); var rs = a1.TypeInfo.Indexes.PrimaryIndex.GetQuery(); foreach (Tuple tuple in rs.GetRecordSet(Session.Current)) { var rs2 = a1.TypeInfo.Indexes.PrimaryIndex.GetQuery(); foreach (Tuple tuple2 in rs2.GetRecordSet(Session.Current)) { TestLog.Debug(tuple2.ToString()); } } // Rollback } } }
/// <summary> /// Propagate all the links that point to sourceDocument to destinationDocument /// </summary> /// <param name="sourceDocument"></param> /// <param name="destinationDocument"></param> protected void PropagateAllGroups(Document sourceDocument, Document destinationDocument) { TestLog.Debug("Propagating to document {0} all groups of document {1}.", destinationDocument, sourceDocument); //// Does the source document belong to any group(s) ? //QueryResult qr; //using (Query q = Session.CreateQuery("Select DocumentLink instances where {LinkSemantic}=@semantic and LinkDestination=@ourSource")) //{ // q.Parameters.Add("@semantic", LinkSemantic.GroupHeadToDocumentInGroup); // q.Parameters.Add("@ourSource", sourceDocument); // qr = q.Execute(); //} var qr = from link in Session.Demand().Query.All <DocumentLink>() where link.LinkSemantic == LinkSemantic.GroupHeadToDocumentInGroup where link.LinkDestination == sourceDocument select link; if (qr.Count() > 0) { foreach (DocumentLink link in qr) { if (destinationDocument == link.LinkDestination) { // The link we are about to create is already exactly the one which is already present. // This happens when we move a document which just received a link from some other source. // E.g. this document was just promoted head of a group by e.g. UnBundleEDIFACTOxl. continue; } // propagate all groups of sourceDocument to destinationDocument link.LinkSource.CreateNewLinkfromMe(destinationDocument, link.LinkSemantic); TestLog.Debug("Document/ID={0} inherits a link from Document/ID={1}. Head of the group is Document/ID={2}. (LinkSemantic={3})", destinationDocument.Id, sourceDocument.Id, link.LinkSource.Id, link.LinkSemantic); } } else { TestLog.Warning("Creating a new group from this document because no links point to it. (Document is {0})", sourceDocument); sourceDocument.CreateNewGroupAndAddThis(); } }
// NOTE: an earlier version of this code had a FilterBuilder // property. This seemed to make sense, because we instantiate // it in two different places. However, the existence of an // NUnitTestFilterBuilder, containing a reference to an engine // service caused our second-level tests of the test executor // to throw an exception. So if you consider doing this, beware! #endregion #region ITestExecutor Implementation /// <summary> /// Called by the Visual Studio IDE to run all tests. Also called by TFS Build /// to run either all or selected tests. In the latter case, a filter is provided /// as part of the run context. /// </summary> /// <param name="sources">Sources to be run.</param> /// <param name="runContext">Context to use when executing the tests.</param> /// <param name="frameworkHandle">Test log to send results and messages through</param> public void RunTests(IEnumerable <string> sources, IRunContext runContext, IFrameworkHandle frameworkHandle) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif Initialize(runContext, frameworkHandle); TestLog.Debug("RunTests by IEnumerable<string>"); InitializeForExecution(runContext, frameworkHandle); if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1) { TestLog.Error("Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration."); Unload(); return; } foreach (var assemblyName in sources) { try { var assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName); RunAssembly(assemblyPath, null, TestFilter.Empty); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning("Exception thrown executing tests", ex); } } TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete"); Unload(); }
public override TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery) { if (!discovery.IsDiscoveryMethodCurrent) { return(filter); } if (filter.IsEmpty()) { return(filter); } if (discovery.NoOfLoadedTestCasesAboveLimit) { TestLog.Debug("Setting filter to empty due to number of testcases"); filter = TestFilter.Empty; } else { var filterBuilder = CreateTestFilterBuilder(); filter = filterBuilder.FilterByList(discovery.LoadedTestCases); } return(filter); }
/// <summary> /// Create a new group whose head will be this document /// </summary> public void CreateNewGroupAndAddThis() { CreateNewLinkfromMe(this, LinkSemantic.GroupHeadToDocumentInGroup); TestLog.Debug("Starting a new group : head document is " + this); }
private void RunAssembly(string assemblyPath, TestFilter filter) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif var actionText = Debugger.IsAttached ? "Debugging " : "Running "; var 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)); } DumpXml dumpXml = null; if (Settings.DumpXmlTestResults) { dumpXml = new Dump.DumpXml(assemblyPath); } try { _activeRunner = GetRunnerFor(assemblyPath); var loadResult = _activeRunner.Explore(TestFilter.Empty); #if !NETCOREAPP1_0 dumpXml?.AddString(loadResult.AsString()); #endif if (loadResult.Name == "test-run") { loadResult = loadResult.FirstChild; } if (loadResult.GetAttribute("runstate") == "Runnable") { var nunitTestCases = loadResult.SelectNodes("//test-case"); using (var testConverter = new TestConverter(TestLog, assemblyPath, Settings.CollectSourceInformation)) { 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(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; } using (var listener = new NUnitEventListener(FrameworkHandle, testConverter, dumpXml)) { try { _activeRunner.Run(listener, filter); } catch (NullReferenceException) { // this happens during the run when CancelRun is called. TestLog.Debug("Nullref caught"); } } } } else { var msgNode = loadResult.SelectSingleNode("properties/property[@name='_SKIPREASON']"); if (msgNode != null && (new[] { "contains no tests", "Has no TestFixtures" }).Any(msgNode.GetAttribute("value").Contains)) { TestLog.Info("NUnit couldn't find any tests in " + assemblyPath); } else { TestLog.Info("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 (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 a NUnit project."); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Warning("Exception thrown executing tests in " + assemblyPath, ex); } finally { #if !NETCOREAPP1_0 dumpXml?.Dump4Execution(); #endif try { _activeRunner?.Dispose(); _activeRunner = null; } 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) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif Initialize(discoveryContext, messageLogger); TestLog.Info(string.Format("NUnit Adapter {0}: Test discovery starting", AdapterVersion)); // 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) { var sourceAssemblyPath = Path.IsPathRooted(sourceAssembly) ? sourceAssembly : Path.Combine(Directory.GetCurrentDirectory(), sourceAssembly); TestLog.Debug("Processing " + sourceAssembly); ITestRunner runner = null; try { runner = GetRunnerFor(sourceAssemblyPath); XmlNode topNode = runner.Explore(TestFilter.Empty); // Currently, this will always be the case but it might change if (topNode.Name == "test-run") { topNode = topNode.FirstChild; } if (topNode.GetAttribute("runstate") == "Runnable") { var testConverter = new TestConverter(TestLog, sourceAssemblyPath, Settings.CollectSourceInformation); int cases = ProcessTestCases(topNode, discoverySink, testConverter); TestLog.Debug(string.Format("Discovered {0} test cases", 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 { var msgNode = topNode.SelectSingleNode("properties/property[@name='_SKIPREASON']"); if (msgNode != null && (new[] { "contains no tests", "Has no TestFixtures" }).Any(msgNode.GetAttribute("value").Contains)) { TestLog.Info("Assembly contains no NUnit 3.0 tests: " + sourceAssembly); } else { TestLog.Info("NUnit failed to load " + sourceAssembly); } } } 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 occured. Not a problem if not an NUnit assembly. TestLog.Warning("Dependent Assembly " + ex.FileName + " of " + sourceAssembly + " not found. Can be ignored if not a 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 { if (runner != null) { if (runner.IsTestRunning) { runner.StopRun(true); } runner.Unload(); runner.Dispose(); } } } TestLog.Info(string.Format("NUnit Adapter {0}: Test discovery complete", AdapterVersion)); Unload(); }
protected override void OnSetFieldValue(FieldInfo field, object oldValue, object newValue) { TestLog.Debug("Entity field set. Field: {0}; Value: {1}", field.Name, newValue); }
private TestPackage CreateTestPackage(string assemblyName) { var package = new TestPackage(assemblyName); if (Settings.ShadowCopyFiles) { package.Settings[PackageSettings.ShadowCopyFiles] = "true"; TestLog.Debug(" Setting ShadowCopyFiles to true"); } if (Debugger.IsAttached) { package.Settings[PackageSettings.NumberOfTestWorkers] = 0; TestLog.Debug(" Setting NumberOfTestWorkers to zero for Debugging"); } else { int workers = Settings.NumberOfTestWorkers; if (workers >= 0) { package.Settings[PackageSettings.NumberOfTestWorkers] = workers; } } int timeout = Settings.DefaultTimeout; if (timeout > 0) { package.Settings[PackageSettings.DefaultTimeout] = timeout; } if (Settings.InternalTraceLevel != null) { package.Settings[PackageSettings.InternalTraceLevel] = Settings.InternalTraceLevel; } if (Settings.BasePath != null) { package.Settings[PackageSettings.BasePath] = Settings.BasePath; } if (Settings.PrivateBinPath != null) { package.Settings[PackageSettings.PrivateBinPath] = Settings.PrivateBinPath; } if (Settings.RandomSeed != -1) { package.Settings[PackageSettings.RandomSeed] = Settings.RandomSeed; } // Always run one assembly at a time in process in it's own domain package.Settings[PackageSettings.ProcessModel] = "InProcess"; package.Settings[PackageSettings.DomainUsage] = "Single"; // Set the work directory to the assembly location unless a setting is provided var workDir = Settings.WorkDirectory; if (workDir == null) { workDir = Path.GetDirectoryName(assemblyName); } else if (!Path.IsPathRooted(workDir)) { workDir = Path.Combine(Path.GetDirectoryName(assemblyName), workDir); } if (!Directory.Exists(workDir)) { Directory.CreateDirectory(workDir); } package.Settings[PackageSettings.WorkDirectory] = workDir; return(package); }
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(); }
private void RunAssembly(string assemblyName, TestFilter filter) { #if LAUNCHDEBUGGER if (!Debugger.IsAttached) { Debugger.Launch(); } #endif _activeRunner = GetRunnerFor(assemblyName); try { var loadResult = _activeRunner.Explore(TestFilter.Empty); if (loadResult.Name == "test-run") { loadResult = loadResult.FirstChild; } if (loadResult.GetAttribute("runstate") == "Runnable") { var nunitTestCases = loadResult.SelectNodes("//test-case"); using (var testConverter = new TestConverter(TestLog, assemblyName)) { 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(testNode)); } TestLog.Info(string.Format("NUnit3TestExecutor converted {0} of {1} NUnit test cases", loadedTestCases.Count, nunitTestCases.Count)); // 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 = new NUnitTestFilterBuilder(TestEngine.Services.GetService <ITestFilterService>()); filter = filterBuilder.ConvertTfsFilterToNUnitFilter(TfsFilter, loadedTestCases); } if (filter == NUnitTestFilterBuilder.NoTestsFound) { TestLog.Info("Skipping assembly - no matching test cases found"); return; } using (var listener = new NUnitEventListener(FrameworkHandle, testConverter)) { try { _activeRunner.Run(listener, filter); } catch (NullReferenceException) { // this happens during the run when CancelRun is called. TestLog.Debug("Nullref caught"); } } } } else { TestLog.Info("NUnit failed to load " + assemblyName); } } catch (BadImageFormatException) { // we skip the native c++ binaries that we don't support. TestLog.Warning("Assembly not supported: " + assemblyName); } catch (System.IO.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 " + assemblyName + " not found. Can be ignored if not a NUnit project."); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } TestLog.Error("Exception thrown executing tests in " + assemblyName, ex); } _activeRunner.Dispose(); _activeRunner = null; }
private TestPackage CreateTestPackage(string assemblyName) { var package = new TestPackage(assemblyName); if (Settings.ShadowCopyFiles) { package.Settings[PackageSettings.ShadowCopyFiles] = "true"; TestLog.Debug(" Setting ShadowCopyFiles to true"); } if (Debugger.IsAttached) { package.Settings[PackageSettings.NumberOfTestWorkers] = 0; TestLog.Debug(" Setting NumberOfTestWorkers to zero for Debugging"); } else { int workers = Settings.NumberOfTestWorkers; if (workers >= 0) { package.Settings[PackageSettings.NumberOfTestWorkers] = workers; } } package.Settings[PackageSettings.SynchronousEvents] = Settings.SynchronousEvents; int timeout = Settings.DefaultTimeout; if (timeout > 0) { package.Settings[PackageSettings.DefaultTimeout] = timeout; } if (Settings.InternalTraceLevel != null) { package.Settings[PackageSettings.InternalTraceLevel] = Settings.InternalTraceLevel; } if (Settings.BasePath != null) { package.Settings[PackageSettings.BasePath] = Settings.BasePath; } if (Settings.PrivateBinPath != null) { package.Settings[PackageSettings.PrivateBinPath] = Settings.PrivateBinPath; } if (Settings.RandomSeed.HasValue) { package.Settings[PackageSettings.RandomSeed] = Settings.RandomSeed; } if (Settings.TestProperties.Count > 0) { SetTestParameters(package.Settings, Settings.TestProperties); } // Always run one assembly at a time in process in its own domain package.Settings[PackageSettings.ProcessModel] = "InProcess"; if (Settings.DomainUsage != null) { package.Settings[PackageSettings.DomainUsage] = Settings.DomainUsage; } else { package.Settings[PackageSettings.DomainUsage] = "Single"; } if (Settings.DefaultTestNamePattern != null) { package.Settings[PackageSettings.DefaultTestNamePattern] = Settings.DefaultTestNamePattern; } else { // Force truncation of string arguments to test cases package.Settings[PackageSettings.DefaultTestNamePattern] = "{m}{a}"; } // Set the work directory to the assembly location unless a setting is provided var workDir = Settings.WorkDirectory; if (workDir == null) { workDir = Path.GetDirectoryName(assemblyName); } else if (!Path.IsPathRooted(workDir)) { workDir = Path.Combine(Path.GetDirectoryName(assemblyName), workDir); } if (!Directory.Exists(workDir)) { Directory.CreateDirectory(workDir); } package.Settings[PackageSettings.WorkDirectory] = workDir; return(package); }
private TestPackage CreateTestPackage(string assemblyName, IGrouping <string, TestCase> testCases) { var package = new TestPackage(assemblyName); if (Settings.ShadowCopyFiles) { package.Settings[PackageSettings.ShadowCopyFiles] = "true"; TestLog.Debug(" Setting ShadowCopyFiles to true"); } if (Debugger.IsAttached) { package.Settings[PackageSettings.NumberOfTestWorkers] = 0; TestLog.Debug(" Setting NumberOfTestWorkers to zero for Debugging"); } else { int workers = Settings.NumberOfTestWorkers; if (workers >= 0) { package.Settings[PackageSettings.NumberOfTestWorkers] = workers; } } if (Settings.PreFilter && testCases != null) { var prefilters = new List <string>(); foreach (TestCase testCase in testCases) { int end = testCase.FullyQualifiedName.IndexOfAny(new char[] { '(', '<' }); if (end > 0) { prefilters.Add(testCase.FullyQualifiedName.Substring(0, end)); } else { prefilters.Add(testCase.FullyQualifiedName); } } package.Settings[PackageSettings.LOAD] = prefilters; } package.Settings[PackageSettings.SynchronousEvents] = Settings.SynchronousEvents; int timeout = Settings.DefaultTimeout; if (timeout > 0) { package.Settings[PackageSettings.DefaultTimeout] = timeout; } if (Settings.InternalTraceLevel != null) { package.Settings[PackageSettings.InternalTraceLevel] = Settings.InternalTraceLevel; } if (Settings.BasePath != null) { package.Settings[PackageSettings.BasePath] = Settings.BasePath; } if (Settings.PrivateBinPath != null) { package.Settings[PackageSettings.PrivateBinPath] = Settings.PrivateBinPath; } if (Settings.RandomSeed.HasValue) { package.Settings[PackageSettings.RandomSeed] = Settings.RandomSeed; } if (Settings.TestProperties.Count > 0) { SetTestParameters(package.Settings, Settings.TestProperties); } // Always run one assembly at a time in process in its own domain package.Settings[PackageSettings.ProcessModel] = "InProcess"; if (Settings.DomainUsage != null) { package.Settings[PackageSettings.DomainUsage] = Settings.DomainUsage; } else { package.Settings[PackageSettings.DomainUsage] = "Single"; } if (Settings.DefaultTestNamePattern != null) { package.Settings[PackageSettings.DefaultTestNamePattern] = Settings.DefaultTestNamePattern; } else { // Force truncation of string arguments to test cases package.Settings[PackageSettings.DefaultTestNamePattern] = "{m}{a}"; } // Set the work directory to the assembly location unless a setting is provided var workDir = Settings.WorkDirectory; if (workDir == null) { workDir = Path.GetDirectoryName(assemblyName); } else if (!Path.IsPathRooted(workDir)) { workDir = Path.Combine(Path.GetDirectoryName(assemblyName), workDir); } if (!Directory.Exists(workDir)) { Directory.CreateDirectory(workDir); } package.Settings[PackageSettings.WorkDirectory] = workDir; WorkDir = workDir; // CreateTestOutputFolder(workDir); return(package); }