From 8ec937003cc24dee4060f8de67c96e35027817d2 Mon Sep 17 00:00:00 2001 From: Terje Sandstrom Date: Fri, 24 Jan 2020 22:30:45 +0100 Subject: [PATCH] Refactoring to get rid of xml all around the code --- .gitignore | 79 ++++++ NUnit3TestAdapter.sln | 1 + build.cake | 2 +- src/NUnitTestAdapter/NUnit.TestAdapter.csproj | 1 + .../NUnitEngine/NUnitResults.cs | 30 --- .../NUnitEngine/NUnitTestCase.cs | 59 +++++ .../NUnitEngine/NUnitTestEvent.cs | 233 ++++++++++++++++++ .../NUnitEngine/NUnitTestEventHeader.cs | 44 ++++ .../NUnitEngine/NUnitTestEventTestOutput.cs | 52 ++++ src/NUnitTestAdapter/NUnitEventListener.cs | 75 +++--- src/NUnitTestAdapter/TestConverter.cs | 103 ++++---- .../NUnit.TestAdapter.Tests.csproj | 8 +- .../NUnitEngineAdapterTests.cs | 12 + .../NUnitEngineTests/NUnitResultsTests.cs | 34 +++ .../NUnitEngineTests/NUnitTestCaseTests.cs | 35 +++ .../NUnitEngineTests/NUnitTestEventsTests.cs | 163 ++++++++++++ .../NUnitEventListenerTests.cs | 27 +- .../TestConverterTests.cs | 13 +- .../TestConverterTests_StaticHelpers.cs | 3 +- .../TestDiscoveryTests.cs | 15 +- 20 files changed, 833 insertions(+), 156 deletions(-) create mode 100644 src/NUnitTestAdapter/NUnitEngine/NUnitTestCase.cs create mode 100644 src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs create mode 100644 src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs create mode 100644 src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs create mode 100644 src/NUnitTestAdapterTests/NUnitEngineTests/NUnitEngineAdapterTests.cs create mode 100644 src/NUnitTestAdapterTests/NUnitEngineTests/NUnitResultsTests.cs create mode 100644 src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestCaseTests.cs create mode 100644 src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestEventsTests.cs diff --git a/.gitignore b/.gitignore index 34ee6d37..167fcb68 100644 --- a/.gitignore +++ b/.gitignore @@ -332,3 +332,82 @@ tools/ .history /Dump /src/NUnitTestAdapterTests/Dump +*.rsuser +# Mono auto generated files +mono_crash.* +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +[Ll]ogs/ +# Visual Studio 2015/2017 cache/options directory +# Visual Studio 2017 auto generated files +Generated\ Files/ +# NUnit +nunit-*.xml +# Benchmark Results +BenchmarkDotNet.Artifacts/ +# StyleCop +StyleCopReport.xml +# Files built by Visual Studio +*_h.h +*.iobj +*.ipdb +*_wpftmp.csproj +# Visual Studio Trace Files +*.e2e +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json +# Coverlet is a free, cross platform Code Coverage Tool +coverage*[.json, .xml, .info] +# Note: Comment the next line if you want to checkin your web deploy settings, +# NuGet Symbol Packages +*.snupkg +**/[Pp]ackages/* +!**/[Pp]ackages/build/ +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.appx +*.appxbundle +*.appxupload +!?*.[Cc]ache/ +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk +ServiceFabricBackup/ +*.rptproj.bak +*.ndf +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl +# CodeRush personal settings +.cr/personal +# tools/** +# !tools/packages.config +# Tabs Studio +*.tss +# Telerik's JustMock configuration file +*.jmconfig +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs +# OpenCover UI analysis results +OpenCover/ +# Azure Stream Analytics local run output +ASALocalRun/ +# MSBuild Binary and Structured Log +*.binlog +# NVidia Nsight GPU debugger configuration file +*.nvuser +# MFractors (Xamarin productivity tool) working folder +.mfractor/ +# Local History for Visual Studio +.localhistory/ +# BeatPulse healthcheck temp database +healthchecksdb +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/NUnit3TestAdapter.sln b/NUnit3TestAdapter.sln index a0f6ecd8..1bbc81b5 100644 --- a/NUnit3TestAdapter.sln +++ b/NUnit3TestAdapter.sln @@ -5,6 +5,7 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7CE30108-5D81-4850-BE6B-C8BCA35D3592}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + .gitignore = .gitignore appveyor.yml = appveyor.yml build.cake = build.cake build.cmd = build.cmd diff --git a/build.cake b/build.cake index 3cbb7b84..de82e534 100644 --- a/build.cake +++ b/build.cake @@ -13,7 +13,7 @@ var configuration = Argument("configuration", "Release"); ////////////////////////////////////////////////////////////////////// var version = "3.17.0"; -var modifier = ""; +var modifier = "-1"; var dbgSuffix = configuration.ToLower() == "debug" ? "-dbg" : ""; var packageVersion = version + modifier + dbgSuffix; diff --git a/src/NUnitTestAdapter/NUnit.TestAdapter.csproj b/src/NUnitTestAdapter/NUnit.TestAdapter.csproj index 0c1a1a23..16bc0894 100644 --- a/src/NUnitTestAdapter/NUnit.TestAdapter.csproj +++ b/src/NUnitTestAdapter/NUnit.TestAdapter.csproj @@ -2,6 +2,7 @@ NUnit3.TestAdapter + NUnit.VisualStudio.TestAdapter net35;netcoreapp2.1 diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs index 23a61dc9..f92a1641 100644 --- a/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs +++ b/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs @@ -47,34 +47,4 @@ public XmlNodeList TestCases() return TopNode.SelectNodes("//test-case"); } } - - public class NUnitTestCase - { - public XmlNode Node { get; } - - public bool IsNull => Node == null; - - public bool IsTestCase => !IsNull && Node.Name == "test-case"; - - public bool IsParameterizedMethod => Type == "ParameterizedMethod"; - - public string Id => Node.GetAttribute("id"); - - public string FullName => Node.GetAttribute("fullname"); - - public string Type => Node.GetAttribute("type"); - - public string Name => Node.GetAttribute("name"); - - public string ClassName => Node.GetAttribute("classname"); - - public string MethodName => Node.GetAttribute("methodname"); - - public NUnitTestCase(XmlNode testCase) - { - Node = testCase; - } - - public NUnitTestCase Parent() => new NUnitTestCase(Node.ParentNode); - } } \ No newline at end of file diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestCase.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestCase.cs new file mode 100644 index 00000000..df49a07b --- /dev/null +++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestCase.cs @@ -0,0 +1,59 @@ +// *********************************************************************** +// Copyright (c) 2020-2020 Charlie Poole, Terje Sandstrom +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +using System.Xml; +using NUnit.VisualStudio.TestAdapter.Dump; + +namespace NUnit.VisualStudio.TestAdapter.NUnitEngine +{ + public abstract class NUnitTestNode + { + public XmlNode Node { get; protected set; } + public string Id => Node.GetAttribute("id"); + public string FullName => Node.GetAttribute("fullname"); + public string Name => Node.GetAttribute("name"); + public bool IsNull => Node == null; + + protected NUnitTestNode(XmlNode node) + { + Node = node; + } + } + + + + public class NUnitTestCase : NUnitTestNode + { + public bool IsTestCase => !IsNull && Node.Name == "test-case"; + public bool IsParameterizedMethod => Type == "ParameterizedMethod"; + public string Type => Node.GetAttribute("type"); + public string ClassName => Node.GetAttribute("classname"); + public string MethodName => Node.GetAttribute("methodname"); + + public NUnitTestCase(XmlNode testCase) : base(testCase) + { + } + + public NUnitTestCase Parent() => new NUnitTestCase(Node.ParentNode); + } +} \ No newline at end of file diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs new file mode 100644 index 00000000..2fd5cf2e --- /dev/null +++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs @@ -0,0 +1,233 @@ +// *********************************************************************** +// Copyright (c) 2020-2020 Charlie Poole, Terje Sandstrom +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +using System; +using System.Globalization; +using System.Runtime.Serialization; +using System.Xml; + +namespace NUnit.VisualStudio.TestAdapter.NUnitEngine +{ + public interface INUnitTestEvent + { + XmlNode Node { get; } + } + + + public abstract class NUnitTestEvent : NUnitTestNode + { + public enum ResultType + { + Failed, + Success, + Skipped, + Warning, + NoIdea + } + + public enum SiteType + { + NoIdea, + Test, + Setup, + TearDown + } + public enum TestTypes + { + NoIdea, + TestFixture, + TestMethod + } + + public TestTypes TestType() + { + string type = Node.GetAttribute("type"); + switch (type) + { + case "TestFixture": + return TestTypes.TestFixture; + case "TestMethod": + return TestTypes.TestMethod; + default: + return TestTypes.NoIdea; + } + } + + public ResultType Result() + { + string res = Node.GetAttribute("result"); + switch (res) + { + case "Failed": + return ResultType.Failed; + case "Passed": + return ResultType.Success; + case "Skipped": + return ResultType.Skipped; + case "Warning": + return ResultType.Warning; + default: + return ResultType.NoIdea; + } + } + + public bool IsFailed => Result() == ResultType.Failed; + + public SiteType Site() + { + string site = Node.GetAttribute("site"); + switch (site) + { + case "SetUp": + return SiteType.Setup; + case "TearDown": + return SiteType.TearDown; + default: + return SiteType.NoIdea; + } + } + + public string Label => Node.GetAttribute("label"); + + public bool IsIgnored => Label == "Ignored"; + public string FailureMessage => Node.SelectSingleNode("failure/message")?.InnerText; + public string FailureStackTrace => Node.SelectSingleNode("failure/stack-trace")?.InnerText; + + public TimeSpan Duration => TimeSpan.FromSeconds(Node.GetAttribute("duration", 0.0)); + + protected NUnitTestEvent(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent)) + { } + + protected NUnitTestEvent(XmlNode node) : base(node) + { + } + + public string MethodName => Node.GetAttribute("methodname"); + public string ClassName => Node.GetAttribute("classname"); + public string Output => Node.SelectSingleNode("output")?.InnerText; + + public string ReasonMessage => Node.SelectSingleNode("reason/message")?.InnerText; + + public CheckedTime StartTime() + { + var startTime = Node.GetAttribute("start-time"); + if (startTime != null) + return new CheckedTime { Ok = true, Time = DateTimeOffset.Parse(startTime, CultureInfo.InvariantCulture) }; + return new CheckedTime { Ok = false, Time = DateTimeOffset.Now }; + } + + public CheckedTime EndTime() + { + string endTime = Node.GetAttribute("end-time"); + return endTime != null + ? new CheckedTime { Ok = true, Time = DateTimeOffset.Parse(endTime, CultureInfo.InvariantCulture) } + : new CheckedTime { Ok = false, Time = DateTimeOffset.Now }; + } + + public struct CheckedTime + { + public bool Ok; + public DateTimeOffset Time; + } + + + } + + /// + /// Handles the NUnit 'start-test' event. + /// + public class NUnitTestEventStartTest : NUnitTestEvent + { + public NUnitTestEventStartTest(INUnitTestEvent node) : this(node.Node) + { } + public NUnitTestEventStartTest(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent)) + { } + + public NUnitTestEventStartTest(XmlNode node) : base(node) + { + if (node.Name != "start-test") + throw new NUnitEventWrongTypeException($"Expected 'start-test', got {node.Name}"); + } + } + + /// + /// Handles the NUnit 'test-case' event. + /// + public class NUnitTestEventTestCase : NUnitTestEvent + { + public NUnitTestEventTestCase(INUnitTestEvent node) : this(node.Node) + { } + public NUnitTestEventTestCase(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent)) + { } + + public NUnitTestEventTestCase(XmlNode node) : base(node) + { + if (node.Name != "test-case") + throw new NUnitEventWrongTypeException($"Expected 'test-case', got {node.Name}"); + } + } + + /// + /// Handles the NUnit 'test-finished' event. + /// + public class NUnitTestEventTestFinished : NUnitTestEvent + { + public NUnitTestEventTestFinished(INUnitTestEvent node) : this(node.Node) + { } + public NUnitTestEventTestFinished(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent)) + { } + + public NUnitTestEventTestFinished(XmlNode node) : base(node) + { + if (node.Name != "test-finished") + throw new NUnitEventWrongTypeException($"Expected 'test-finished', got {node.Name}"); + } + } + + [Serializable] + public class NUnitEventWrongTypeException : Exception + { + // For guidelines regarding the creation of new exception types, see + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp + // and + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp + + public NUnitEventWrongTypeException() + { + } + + public NUnitEventWrongTypeException(string message) : base(message) + { + } + + public NUnitEventWrongTypeException(string message, Exception inner) : base(message, inner) + { + } + + protected NUnitEventWrongTypeException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } +} diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs new file mode 100644 index 00000000..9fda5857 --- /dev/null +++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs @@ -0,0 +1,44 @@ +using System.Xml; +using NUnit.VisualStudio.TestAdapter.Dump; + +namespace NUnit.VisualStudio.TestAdapter.NUnitEngine +{ + public class NUnitTestEventHeader : INUnitTestEvent + { + public enum EventType + { + NoIdea, + StartTest, + TestCase, + TestSuite, + TestOutput + } + public XmlNode Node { get; } + public string AsString() => Node.AsString(); + public string FullName => Node.GetAttribute("fullname"); + public string Name => Node.GetAttribute("name"); + public EventType Type { get; } + public NUnitTestEventHeader(string sNode) + { + Node = XmlHelper.CreateXmlNode(sNode); + switch (Node.Name) + { + case "start-test": + Type = EventType.StartTest; + break; + case "test-case": + Type = EventType.TestCase; + break; + case "test-suite": + Type = EventType.TestSuite; + break; + case "test-output": + Type = EventType.TestOutput; + break; + default: + Type = EventType.NoIdea; + break; + } + } + } +} \ No newline at end of file diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs new file mode 100644 index 00000000..15e5c3ed --- /dev/null +++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs @@ -0,0 +1,52 @@ +using System.Xml; + +namespace NUnit.VisualStudio.TestAdapter.NUnitEngine +{ + /// + /// Handles the 'test-output' event. + /// + public class NUnitTestEventTestOutput : NUnitTestEvent + { + public enum Streams + { + NoIdea, + Error, + Progress + } + + public Streams Stream { get; } + public string TestId => Node.GetAttribute("testid"); + + public string TestName => Node.GetAttribute("testname"); + + + public NUnitTestEventTestOutput(INUnitTestEvent theEvent) : this(theEvent.Node) + { + if (theEvent.Node.Name != "test-output") + throw new NUnitEventWrongTypeException($"Expected 'test-output', got {theEvent.Node.Name}"); + } + public NUnitTestEventTestOutput(XmlNode node) : base(node) + { + switch (node.GetAttribute("stream")) + { + case "Error": + Stream = Streams.Error; + break; + case "Progress": + Stream = Streams.Progress; + break; + default: + Stream = Streams.NoIdea; + break; + } + } + + /// + /// Returns the output information. + /// + public string Content => Node.InnerText; + + + + } +} \ No newline at end of file diff --git a/src/NUnitTestAdapter/NUnitEventListener.cs b/src/NUnitTestAdapter/NUnitEventListener.cs index aebf984d..ec93c7bb 100644 --- a/src/NUnitTestAdapter/NUnitEventListener.cs +++ b/src/NUnitTestAdapter/NUnitEventListener.cs @@ -33,6 +33,7 @@ using NUnit.Engine; using NUnit.VisualStudio.TestAdapter.Dump; using NUnit.VisualStudio.TestAdapter.Internal; +using NUnit.VisualStudio.TestAdapter.NUnitEngine; namespace NUnit.VisualStudio.TestAdapter { @@ -73,34 +74,38 @@ public NUnitEventListener(ITestExecutionRecorder recorder, ITestConverter testCo public void OnTestEvent(string report) { - var node = XmlHelper.CreateXmlNode(report); + var node = new NUnitTestEventHeader(report); #if NET35 dumpXml?.AddTestEvent(node.AsString()); #endif try { - switch (node.Name) + switch (node.Type) { - case "start-test": - TestStarted(node); + case NUnitTestEventHeader.EventType.StartTest: + var startNode = new NUnitTestEventStartTest(node); + TestStarted(startNode); break; - case "test-case": - TestFinished(node); + case NUnitTestEventHeader.EventType.TestCase: + var testFinishedNode = new NUnitTestEventTestCase(node); + TestFinished(testFinishedNode); break; - case "test-suite": - SuiteFinished(node); + case NUnitTestEventHeader.EventType.TestSuite: + var suiteFinishedNode = new NUnitTestEventTestFinished(node); + SuiteFinished(suiteFinishedNode); break; - case "test-output": - TestOutput(node); + case NUnitTestEventHeader.EventType.TestOutput: + var outputNode = new NUnitTestEventTestOutput(node); + TestOutput(outputNode); break; } } catch (Exception ex) { - _recorder.SendMessage(TestMessageLevel.Warning, $"Error processing {node.Name} event for {node.GetAttribute("fullname")}"); + _recorder.SendMessage(TestMessageLevel.Warning, $"Error processing {node.Name} event for {node.FullName}"); _recorder.SendMessage(TestMessageLevel.Warning, ex.ToString()); } } @@ -136,18 +141,18 @@ protected virtual void Dispose(bool disposing) } #endregion - public void TestStarted(XmlNode testNode) + public void TestStarted(NUnitTestEvent testNode) { - TestCase ourCase = _testConverter.GetCachedTestCase(testNode.GetAttribute("id")); + var ourCase = _testConverter.GetCachedTestCase(testNode.Id); // Simply ignore any TestCase not found in the cache if (ourCase != null) _recorder.RecordStart(ourCase); } - public void TestFinished(XmlNode resultNode) + public void TestFinished(NUnitTestEvent resultNode) { - var testId = resultNode.GetAttribute("id"); + var testId = resultNode.Id; if (_outputNodes.TryGetValue(testId, out var outputNodes)) { _outputNodes.Remove(testId); @@ -161,37 +166,31 @@ public void TestFinished(XmlNode resultNode) } } - public void SuiteFinished(XmlNode resultNode) + public void SuiteFinished(NUnitTestEvent resultNode) { - var result = resultNode.GetAttribute("result"); - var site = resultNode.GetAttribute("site"); - - if (result == "Failed") - { - if (site == "SetUp" || site == "TearDown") - { - _recorder.SendMessage( - TestMessageLevel.Warning, - $"{site} failed for test fixture {resultNode.GetAttribute("fullname")}"); + if (!resultNode.IsFailed) + return; + var site = resultNode.Site(); + if (site != NUnitTestEvent.SiteType.Setup && site != NUnitTestEvent.SiteType.TearDown) + return; + _recorder.SendMessage(TestMessageLevel.Warning, $"{site} failed for test fixture {resultNode.FullName}"); - var messageNode = resultNode.SelectSingleNode("failure/message"); - if (messageNode != null) - _recorder.SendMessage(TestMessageLevel.Warning, messageNode.InnerText); + string message = resultNode.FailureMessage; + if (!string.IsNullOrEmpty(message)) + _recorder.SendMessage(TestMessageLevel.Warning, message); - var stackNode = resultNode.SelectSingleNode("failure/stack-trace"); - if (stackNode != null) - _recorder.SendMessage(TestMessageLevel.Warning, stackNode.InnerText); - } - } + var stackNode = resultNode.FailureStackTrace; + if (!string.IsNullOrEmpty(stackNode)) + _recorder.SendMessage(TestMessageLevel.Warning, stackNode); } private static readonly string NL = Environment.NewLine; private static readonly int NL_LENGTH = NL.Length; private readonly IDumpXml dumpXml; - public void TestOutput(XmlNode outputNode) + public void TestOutput(NUnitTestEventTestOutput outputNode) { - var text = outputNode.InnerText; + string text = outputNode.Content; // Remove final newline since logger will add one if (text.EndsWith(NL)) @@ -203,7 +202,7 @@ public void TestOutput(XmlNode outputNode) } // ReSharper disable once StringLiteralTypo - var testId = outputNode.GetAttribute("testid"); + var testId = outputNode.TestId; if (!string.IsNullOrEmpty(testId)) { if (!_outputNodes.TryGetValue(testId, out var outputNodes)) @@ -212,7 +211,7 @@ public void TestOutput(XmlNode outputNode) _outputNodes.Add(testId, outputNodes); } - outputNodes.Add(outputNode); + outputNodes.Add(outputNode.Node); } _recorder.SendMessage(TestMessageLevel.Warning, text); diff --git a/src/NUnitTestAdapter/TestConverter.cs b/src/NUnitTestAdapter/TestConverter.cs index c45dd864..c4ddbb20 100644 --- a/src/NUnitTestAdapter/TestConverter.cs +++ b/src/NUnitTestAdapter/TestConverter.cs @@ -36,7 +36,7 @@ namespace NUnit.VisualStudio.TestAdapter public interface ITestConverter { TestCase GetCachedTestCase(string id); - TestConverter.TestResultSet GetVsTestResults(XmlNode resultNode, ICollection outputNodes); + TestConverter.TestResultSet GetVsTestResults(NUnitTestEvent resultNode, ICollection outputNodes); } public sealed class TestConverter : IDisposable, ITestConverter @@ -104,36 +104,36 @@ public TestCase GetCachedTestCase(string id) private static readonly string NL = Environment.NewLine; - public TestResultSet GetVsTestResults(XmlNode resultNode, ICollection outputNodes) + public TestResultSet GetVsTestResults(NUnitTestEvent resultNode, ICollection outputNodes) { var results = new List(); - var testcaseResult = GetBasicResult(resultNode, outputNodes); + var testCaseResult = GetBasicResult(resultNode, outputNodes); - if (testcaseResult != null) + if (testCaseResult != null) { - if (testcaseResult.Outcome == TestOutcome.Failed || testcaseResult.Outcome == TestOutcome.NotFound) + if (testCaseResult.Outcome == TestOutcome.Failed || testCaseResult.Outcome == TestOutcome.NotFound) { - testcaseResult.ErrorMessage = resultNode.SelectSingleNode("failure/message")?.InnerText; - testcaseResult.ErrorStackTrace = resultNode.SelectSingleNode("failure/stack-trace")?.InnerText; + testCaseResult.ErrorMessage = resultNode.FailureMessage; + testCaseResult.ErrorStackTrace = resultNode.FailureStackTrace; // find stacktrace in assertion nodes if not defined (seems .netcore2.0 doesn't provide stack-trace for Assert.Fail("abc")) - if (testcaseResult.ErrorStackTrace == null) + if (testCaseResult.ErrorStackTrace == null) { string stackTrace = string.Empty; - foreach (XmlNode assertionStacktraceNode in resultNode.SelectNodes("assertions/assertion/stack-trace")) + foreach (XmlNode assertionStacktraceNode in resultNode.Node.SelectNodes("assertions/assertion/stack-trace")) { stackTrace += assertionStacktraceNode.InnerText; } - testcaseResult.ErrorStackTrace = stackTrace; + testCaseResult.ErrorStackTrace = stackTrace; } } - else if (testcaseResult.Outcome == TestOutcome.Skipped || testcaseResult.Outcome == TestOutcome.None) + else if (testCaseResult.Outcome == TestOutcome.Skipped || testCaseResult.Outcome == TestOutcome.None) { - testcaseResult.ErrorMessage = resultNode.SelectSingleNode("reason/message")?.InnerText; + testCaseResult.ErrorMessage = resultNode.ReasonMessage; } - results.Add(testcaseResult); + results.Add(testCaseResult); } if (results.Count == 0) @@ -143,7 +143,7 @@ public TestResultSet GetVsTestResults(XmlNode resultNode, ICollection o results.Add(result); } - return new TestResultSet { TestCaseResult = testcaseResult, TestResults = results }; + return new TestResultSet { TestCaseResult = testCaseResult, TestResults = results }; } public struct TestResultSet @@ -226,48 +226,49 @@ private TestCase MakeTestCaseFromXmlNode(NUnitTestCase testNode) return testCase; } - private VSTestResult MakeTestResultFromLegacyXmlNode(XmlNode resultNode, IEnumerable outputNodes) + private VSTestResult MakeTestResultFromLegacyXmlNode(NUnitTestEvent resultNode, IEnumerable outputNodes) { - VSTestResult ourResult = GetBasicResult(resultNode, outputNodes); - if (ourResult != null) + var ourResult = GetBasicResult(resultNode, outputNodes); + if (ourResult == null) + return null; + + var node = resultNode.Node.SelectSingleNode("failure") ?? resultNode.Node.SelectSingleNode("reason"); + + string message = node?.SelectSingleNode("message")?.InnerText; + // If we're running in the IDE, remove any caret line from the message + // since it will be displayed using a variable font and won't make sense. + if (!string.IsNullOrEmpty(message) && NUnitTestAdapter.IsRunningUnderIde) { - var node = resultNode.SelectSingleNode("failure") ?? resultNode.SelectSingleNode("reason"); - - string message = node?.SelectSingleNode("message")?.InnerText; - // If we're running in the IDE, remove any caret line from the message - // since it will be displayed using a variable font and won't make sense. - if (!string.IsNullOrEmpty(message) && NUnitTestAdapter.IsRunningUnderIde) - { - string pattern = NL + " -*\\^" + NL; - message = Regex.Replace(message, pattern, NL, RegexOptions.Multiline); - } - - ourResult.ErrorMessage = message; - ourResult.ErrorStackTrace = node?.SelectSingleNode("stack-trace")?.InnerText; + string pattern = NL + " -*\\^" + NL; + message = Regex.Replace(message, pattern, NL, RegexOptions.Multiline); } + ourResult.ErrorMessage = message; + ourResult.ErrorStackTrace = node?.SelectSingleNode("stack-trace")?.InnerText; + return ourResult; } - private VSTestResult GetBasicResult(XmlNode resultNode, IEnumerable outputNodes) + private VSTestResult GetBasicResult(NUnitTestEvent resultNode, IEnumerable outputNodes) { - var vsTest = GetCachedTestCase(resultNode.GetAttribute("id")); - if (vsTest == null) return null; + var vsTest = GetCachedTestCase(resultNode.Id); + if (vsTest == null) + return null; var vsResult = new VSTestResult(vsTest) { DisplayName = vsTest.DisplayName, Outcome = GetTestOutcome(resultNode), - Duration = TimeSpan.FromSeconds(resultNode.GetAttribute("duration", 0.0)) + Duration = resultNode.Duration }; - var startTime = resultNode.GetAttribute("start-time"); - if (startTime != null) - vsResult.StartTime = DateTimeOffset.Parse(startTime, CultureInfo.InvariantCulture); + var startTime = resultNode.StartTime(); + if (startTime.Ok) + vsResult.StartTime = startTime.Time; - var endTime = resultNode.GetAttribute("end-time"); - if (endTime != null) - vsResult.EndTime = DateTimeOffset.Parse(endTime, CultureInfo.InvariantCulture); + var endTime = resultNode.EndTime(); + if (endTime.Ok) + vsResult.EndTime = endTime.Time; // TODO: Remove this when NUnit provides a better duration if (vsResult.Duration == TimeSpan.Zero && (vsResult.Outcome == TestOutcome.Passed || vsResult.Outcome == TestOutcome.Failed)) @@ -278,11 +279,11 @@ private VSTestResult GetBasicResult(XmlNode resultNode, IEnumerable out FillResultFromOutputNodes(outputNodes, vsResult); // Add stdOut messages from TestFinished element to vstest result - var outputNode = resultNode.SelectSingleNode("output"); - if (outputNode != null) - vsResult.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, outputNode.InnerText)); + var output = resultNode.Output; + if (!string.IsNullOrEmpty(output)) + vsResult.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, output)); - var attachmentSet = ParseAttachments(resultNode); + var attachmentSet = ParseAttachments(resultNode.Node); if (attachmentSet.Attachments.Count > 0) vsResult.Attachments.Add(attachmentSet); @@ -353,17 +354,17 @@ private AttachmentSet ParseAttachments(XmlNode resultNode) } // Public for testing - public static TestOutcome GetTestOutcome(XmlNode resultNode) + public static TestOutcome GetTestOutcome(NUnitTestEvent resultNode) { - switch (resultNode.GetAttribute("result")) + switch (resultNode.Result()) { - case "Passed": + case NUnitTestEvent.ResultType.Success: return TestOutcome.Passed; - case "Failed": + case NUnitTestEvent.ResultType.Failed: return TestOutcome.Failed; - case "Skipped": - return resultNode.GetAttribute("label") == "Ignored" ? TestOutcome.Skipped : TestOutcome.None; - case "Warning": + case NUnitTestEvent.ResultType.Skipped: + return resultNode.IsIgnored ? TestOutcome.Skipped : TestOutcome.None; + case NUnitTestEvent.ResultType.Warning: return TestOutcome.Skipped; default: return TestOutcome.None; diff --git a/src/NUnitTestAdapterTests/NUnit.TestAdapter.Tests.csproj b/src/NUnitTestAdapterTests/NUnit.TestAdapter.Tests.csproj index e23f21fa..b24f6c31 100644 --- a/src/NUnitTestAdapterTests/NUnit.TestAdapter.Tests.csproj +++ b/src/NUnitTestAdapterTests/NUnit.TestAdapter.Tests.csproj @@ -4,8 +4,8 @@ true NUnit.VisualStudio.TestAdapter.Tests NUnit.VisualStudio.TestAdapter.Tests - net46;netcoreapp2.1 - + + net46 true true @@ -38,10 +38,6 @@ - - - - diff --git a/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitEngineAdapterTests.cs b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitEngineAdapterTests.cs new file mode 100644 index 00000000..f33e172c --- /dev/null +++ b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitEngineAdapterTests.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NUnit.VisualStudio.TestAdapter.Tests.NUnitEngineTests +{ + public class NUnitEngineAdapterTests + { + } +} diff --git a/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitResultsTests.cs b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitResultsTests.cs new file mode 100644 index 00000000..ee12aec9 --- /dev/null +++ b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitResultsTests.cs @@ -0,0 +1,34 @@ +// *********************************************************************** +// Copyright (c) 2020-2020 Charlie Poole, Terje Sandstrom +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NUnit.VisualStudio.TestAdapter.Tests.NUnitEngineTests +{ + public class NUnitResultsTests + { } +} diff --git a/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestCaseTests.cs b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestCaseTests.cs new file mode 100644 index 00000000..814c17f7 --- /dev/null +++ b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestCaseTests.cs @@ -0,0 +1,35 @@ +// *********************************************************************** +// Copyright (c) 2020-2020 Charlie Poole, Terje Sandstrom +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NUnit.VisualStudio.TestAdapter.Tests.NUnitEngineTests +{ + public class NUnitTestCaseTests + { + } +} diff --git a/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestEventsTests.cs b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestEventsTests.cs new file mode 100644 index 00000000..6aacc5c9 --- /dev/null +++ b/src/NUnitTestAdapterTests/NUnitEngineTests/NUnitTestEventsTests.cs @@ -0,0 +1,163 @@ +// *********************************************************************** +// Copyright (c) 2020-2020 Charlie Poole, Terje Sandstrom +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// *********************************************************************** + +using NUnit.Framework; +using NUnit.VisualStudio.TestAdapter.NUnitEngine; + +namespace NUnit.VisualStudio.TestAdapter.Tests.NUnitEngineTests +{ + public class NUnitTestEventsTests + { + private string startSuite = @""; + + [Test] + public void ThatTestEventIsParsedForStartSuite() + { + var sut = new NUnitTestEventStartTest(startSuite); + Assert.Multiple(() => + { + Assert.That(sut.FullName, Is.EqualTo("NUnitTestDemo.SimpleTests")); + Assert.That(sut.TestType(), Is.EqualTo(NUnitTestEventStartTest.TestTypes.TestFixture)); + Assert.That(sut.Name, Is.EqualTo("SimpleTests")); + Assert.That(sut.TestType, Is.EqualTo(NUnitTestEvent.TestTypes.TestFixture)); + Assert.That(sut.Id, Is.EqualTo("0-1073")); + }); + } + + private string startTest = @""; + + [Test] + public void ThatTestEventIsParsedForStartTest() + { + var sut = new NUnitTestEventStartTest(startTest); + Assert.Multiple(() => + { + Assert.That(sut.FullName, Is.EqualTo("NUnitTestDemo.SetUpFixture.TestFixture2.Test2")); + Assert.That(sut.TestType(), Is.EqualTo(NUnitTestEventStartTest.TestTypes.TestMethod)); + Assert.That(sut.Name, Is.EqualTo("Test2")); + Assert.That(sut.TestType, Is.EqualTo(NUnitTestEvent.TestTypes.TestMethod)); + Assert.That(sut.Id, Is.EqualTo("0-1139")); + }); + } + + private string testCaseFailing = + @" + + + + + + + + + + + + + +"; + [Test] + public void ThatTestEventIsParsedForFailingTestCase() + { + var sut = new NUnitTestEventTestCase(testCaseFailing); + Assert.Multiple(() => + { + Assert.That(sut.FullName, Is.EqualTo("NUnitTestDemo.SimpleTests.TestFails")); + Assert.That(sut.TestType(), Is.EqualTo(NUnitTestEvent.TestTypes.NoIdea)); + Assert.That(sut.Name, Is.EqualTo("TestFails")); + Assert.That(sut.Id, Is.EqualTo("0-1076")); + Assert.That(sut.Result, Is.EqualTo(NUnitTestEvent.ResultType.Failed)); + Assert.That(sut.Duration, Is.GreaterThan(0.001)); + Assert.That(sut.StartTime().Ok); + Assert.That(sut.EndTime().Ok); + }); + } + + private string testCaseSucceeds = @" + + + +"; + [Test] + public void ThatTestEventIsParsedForSuccessTestCase() + { + var sut = new NUnitTestEventTestCase(testCaseSucceeds); + Assert.Multiple(() => + { + Assert.That(sut.FullName, Is.EqualTo("NUnitTestDemo.AsyncTests.AsyncTaskTestSucceeds")); + Assert.That(sut.TestType(), Is.EqualTo(NUnitTestEvent.TestTypes.NoIdea)); + Assert.That(sut.Name, Is.EqualTo("AsyncTaskTestSucceeds")); + Assert.That(sut.Id, Is.EqualTo("0-1006")); + Assert.That(sut.Result, Is.EqualTo(NUnitTestEvent.ResultType.Success)); + }); + } + + private string testSuiteFinished = @" + + + +"; + [Test] + public void ThatTestEventIsParsedForFinishSuite() + { + var sut = new NUnitTestEventTestFinished(testSuiteFinished); + Assert.Multiple(() => + { + Assert.That(sut.FullName, Is.EqualTo("NUnitTestDemo.TextOutputTests")); + Assert.That(sut.TestType(), Is.EqualTo(NUnitTestEvent.TestTypes.TestFixture)); + Assert.That(sut.Name, Is.EqualTo("TextOutputTests")); + Assert.That(sut.Id, Is.EqualTo("0-1094")); + Assert.That(sut.Result, Is.EqualTo(NUnitTestEvent.ResultType.Success)); + }); + } + + private readonly string testCaseSucceedsWithOutput = @" + + + + +"; + [Test] + public void ThatTestEventIsParsedForSuccessTestCaseWithOutput() + { + var sut = new NUnitTestEventTestCase(testCaseSucceedsWithOutput); + Assert.Multiple(() => + { + Assert.That(sut.FullName, Is.EqualTo("NUnitTestDemo.SimpleTests.TestSucceeds")); + Assert.That(sut.TestType(), Is.EqualTo(NUnitTestEvent.TestTypes.NoIdea)); + Assert.That(sut.Name, Is.EqualTo("TestSucceeds")); + Assert.That(sut.Id, Is.EqualTo("0-1074")); + Assert.That(sut.Result, Is.EqualTo(NUnitTestEvent.ResultType.Success)); + Assert.That(sut.MethodName, Is.EqualTo("TestSucceeds")); + Assert.That(sut.ClassName, Is.EqualTo("NUnitTestDemo.SimpleTests")); + }); + } + } +} diff --git a/src/NUnitTestAdapterTests/NUnitEventListenerTests.cs b/src/NUnitTestAdapterTests/NUnitEventListenerTests.cs index 920f1b3c..3ab894de 100644 --- a/src/NUnitTestAdapterTests/NUnitEventListenerTests.cs +++ b/src/NUnitTestAdapterTests/NUnitEventListenerTests.cs @@ -23,9 +23,6 @@ using System; using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; #if NET35 using System.Runtime.Remoting; #endif @@ -88,11 +85,9 @@ public void TestStarted_CallsRecordStartCorrectly() [Test] public void TestFinished_CallsRecordEnd_Then_RecordResult() { - listener.TestFinished(FakeTestData.GetResultNode()); - Assert.AreEqual(2, testLog.Events.Count); - Assert.AreEqual( - FakeFrameworkHandle.EventType.RecordEnd, - testLog.Events[0].EventType); + listener.TestFinished(new NUnitTestEventTestCase(FakeTestData.GetResultNode().AsString())); + Assert.That(testLog.Events.Count, Is.EqualTo(2)); + Assert.That(testLog.Events[0].EventType, Is.EqualTo(FakeFrameworkHandle.EventType.RecordEnd)); Assert.AreEqual( FakeFrameworkHandle.EventType.RecordResult, testLog.Events[1].EventType); @@ -101,11 +96,9 @@ public void TestFinished_CallsRecordEnd_Then_RecordResult() [Test] public void TestFinished_CallsRecordEndCorrectly() { - listener.TestFinished(FakeTestData.GetResultNode()); + listener.TestFinished(new NUnitTestEventTestCase(FakeTestData.GetResultNode().AsString())); Assume.That(testLog.Events.Count, Is.EqualTo(2)); - Assume.That( - testLog.Events[0].EventType, - Is.EqualTo(FakeFrameworkHandle.EventType.RecordEnd)); + Assume.That(testLog.Events[0].EventType, Is.EqualTo(FakeFrameworkHandle.EventType.RecordEnd)); VerifyTestCase(testLog.Events[0].TestCase); Assert.AreEqual(TestOutcome.Passed, testLog.Events[0].TestOutcome); @@ -114,11 +107,9 @@ public void TestFinished_CallsRecordEndCorrectly() [Test] public void TestFinished_CallsRecordResultCorrectly() { - listener.TestFinished(FakeTestData.GetResultNode()); + listener.TestFinished(new NUnitTestEventTestCase(FakeTestData.GetResultNode().AsString())); Assume.That(testLog.Events.Count, Is.EqualTo(2)); - Assume.That( - testLog.Events[1].EventType, - Is.EqualTo(FakeFrameworkHandle.EventType.RecordResult)); + Assume.That(testLog.Events[1].EventType, Is.EqualTo(FakeFrameworkHandle.EventType.RecordResult)); VerifyTestResult(testLog.Events[1].TestResult); } @@ -245,7 +236,7 @@ public void ThatNormalTestOutputIsOutput() sut.OnTestEvent(TestFinish); recorder.Received().SendMessage(Arg.Any(), Arg.Is(x => x.StartsWith("Whatever"))); - converter.Received().GetVsTestResults(Arg.Any(), Arg.Is>(x => x.Count == 1)); + converter.Received().GetVsTestResults(Arg.Any(), Arg.Is>(x => x.Count == 1)); } [Test] @@ -256,7 +247,7 @@ public void ThatNormalTestOutputIsError() sut.OnTestEvent(TestFinish); recorder.Received().SendMessage(Arg.Any(), Arg.Is(x => x.StartsWith("Whatever"))); - converter.Received().GetVsTestResults(Arg.Any(), Arg.Is>(x => x.Count == 1)); + converter.Received().GetVsTestResults(Arg.Any(), Arg.Is>(x => x.Count == 1)); } [Test] diff --git a/src/NUnitTestAdapterTests/TestConverterTests.cs b/src/NUnitTestAdapterTests/TestConverterTests.cs index e70f3235..517492eb 100644 --- a/src/NUnitTestAdapterTests/TestConverterTests.cs +++ b/src/NUnitTestAdapterTests/TestConverterTests.cs @@ -29,6 +29,7 @@ using Microsoft.VisualStudio.TestPlatform.ObjectModel; using NSubstitute; using NUnit.Framework; +using NUnit.VisualStudio.TestAdapter.Dump; using NUnit.VisualStudio.TestAdapter.NUnitEngine; namespace NUnit.VisualStudio.TestAdapter.Tests @@ -124,7 +125,7 @@ public void ConvertedTestCaseIsCached() [Test] public void CannotMakeTestResultWhenTestCaseIsNotInCache() { - var fakeResultNode = FakeTestData.GetResultNode(); + var fakeResultNode = new NUnitTestEventTestCase(FakeTestData.GetResultNode()); var results = testConverter.GetVsTestResults(fakeResultNode, Enumerable.Empty().ToList()); Assert.That(results.TestResults.Count, Is.EqualTo(0)); } @@ -134,7 +135,7 @@ public void CanMakeTestResultFromNUnitTestResult() { // This should put the TestCase in the cache var cachedTestCase = testConverter.ConvertTestCase(fakeTestNode); - var fakeResultNode = FakeTestData.GetResultNode(); + var fakeResultNode = new NUnitTestEventTestCase(FakeTestData.GetResultNode()); var testResults = testConverter.GetVsTestResults(fakeResultNode, Enumerable.Empty().ToList()); var testResult = testResults.TestResults[0]; @@ -164,7 +165,7 @@ public void CanMakeTestResultFromNUnitTestResult() public void CanMakeTestResultFromNUnitTestResult2(string output, string expectedMessages) { var cachedTestCase = testConverter.ConvertTestCase(fakeTestNode); - var fakeResultNode = FakeTestData.GetResultNode(); + var fakeResultNode = new NUnitTestEventTestCase(FakeTestData.GetResultNode()); var outputNodes = output.Split(';').Select(i => XmlHelper.CreateXmlNode(i.Trim())).ToList(); var testResults = testConverter.GetVsTestResults(fakeResultNode, outputNodes); var testResult = testResults.TestResults[0]; @@ -179,11 +180,11 @@ public void CanMakeTestResultFromNUnitTestResult2(string output, string expected public void Attachments_CorrectAmountOfConvertedAttachments() { var cachedTestCase = testConverter.ConvertTestCase(fakeTestNode); - var fakeResultNode = FakeTestData.GetResultNode(); + var fakeResultNode = new NUnitTestEventTestCase(FakeTestData.GetResultNode()); var testResults = testConverter.GetVsTestResults(fakeResultNode, Enumerable.Empty().ToList()); - var fakeAttachments = fakeResultNode.SelectNodes("attachments/attachment") + var fakeAttachments = fakeResultNode.Node.SelectNodes("attachments/attachment") .OfType() .Where(n => !string.IsNullOrEmpty(n.SelectSingleNode("filePath")?.InnerText)) .ToArray(); @@ -206,7 +207,7 @@ public void Attachments_AllFilePathesStartWithFileScheme() const string errorMessage = "Path must start with file:// uri scheme"; var cachedTestCase = testConverter.ConvertTestCase(fakeTestNode); - var fakeResultNode = FakeTestData.GetResultNode(); + var fakeResultNode = new NUnitTestEventTestCase(FakeTestData.GetResultNode().AsString()); var testResults = testConverter.GetVsTestResults(fakeResultNode, Enumerable.Empty().ToList()); diff --git a/src/NUnitTestAdapterTests/TestConverterTests_StaticHelpers.cs b/src/NUnitTestAdapterTests/TestConverterTests_StaticHelpers.cs index 4205a344..4f889e2d 100644 --- a/src/NUnitTestAdapterTests/TestConverterTests_StaticHelpers.cs +++ b/src/NUnitTestAdapterTests/TestConverterTests_StaticHelpers.cs @@ -24,6 +24,7 @@ using System.Xml; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using NUnit.Framework; +using NUnit.VisualStudio.TestAdapter.NUnitEngine; namespace NUnit.VisualStudio.TestAdapter.Tests { @@ -41,7 +42,7 @@ public class TestConverterTestsStaticHelpers [TestCase("", ExpectedResult = TestOutcome.Skipped)] public TestOutcome ResultStateToTestOutcome(string result) { - var resultNode = XmlHelper.CreateXmlNode(result); + var resultNode = new NUnitTestEventTestCase(XmlHelper.CreateXmlNode(result)); return TestConverter.GetTestOutcome(resultNode); } } diff --git a/src/NUnitTestAdapterTests/TestDiscoveryTests.cs b/src/NUnitTestAdapterTests/TestDiscoveryTests.cs index 233ff941..e15c202d 100644 --- a/src/NUnitTestAdapterTests/TestDiscoveryTests.cs +++ b/src/NUnitTestAdapterTests/TestDiscoveryTests.cs @@ -191,11 +191,16 @@ public void WhenAssemblyIsNative() context, messageLoggerStub, this); - Assert.That(testcaseWasSent, Is.False); - Assert.That(messageLoggerStub.WarningMessages.Count(), Is.EqualTo(1)); - Assert.That(!messageLoggerStub.ErrorMessages.Any()); - var warningmsg = messageLoggerStub.WarningMessages.Select(o => o.Item2).Single(); - Assert.That(warningmsg, Does.Contain("Assembly not supported")); + Assert.Multiple(() => + { + Assert.That(testcaseWasSent, Is.False); + Assert.That(messageLoggerStub.WarningMessages.Count(), Is.EqualTo(1)); + Assert.That(!messageLoggerStub.ErrorMessages.Any()); + string warningmsg = messageLoggerStub.WarningMessages.Select(o => o.Item2).FirstOrDefault(); + Assert.That(warningmsg, Is.Not.Null); + if (!string.IsNullOrEmpty(warningmsg)) + Assert.That(warningmsg, Does.Contain("Assembly not supported")); + }); } #endif