From 8e55178d25aa1454acfb66c1c93c79bd730ba3b2 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Sun, 20 Apr 2025 05:32:34 -0700 Subject: [PATCH 01/10] Remove SafeAttributeAccess, which duplicates code in XmlHelper --- .../nunit4-console/SafeAttributeAccess.cs | 71 ------------------- .../nunit4-netcore-console.csproj | 1 - 2 files changed, 72 deletions(-) delete mode 100644 src/NUnitConsole/nunit4-console/SafeAttributeAccess.cs diff --git a/src/NUnitConsole/nunit4-console/SafeAttributeAccess.cs b/src/NUnitConsole/nunit4-console/SafeAttributeAccess.cs deleted file mode 100644 index 009bbb25a..000000000 --- a/src/NUnitConsole/nunit4-console/SafeAttributeAccess.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt - -using System; -using System.Globalization; -using System.Xml; - -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] - internal sealed class ExtensionAttribute : Attribute - { - } -} - -namespace NUnit.ConsoleRunner -{ - /// - /// SafeAttributeAccess provides an extension method for accessing XML attributes. - /// - public static class SafeAttributeAccess - { - /// - /// Gets the value of the given attribute. - /// - /// The result. - /// The name. - /// - public static string? GetAttribute(this XmlNode result, string name) - { - XmlAttribute? attr = result.Attributes?[name]; - - return attr is null ? null : attr.Value; - } - - /// - /// Gets the value of the given attribute as a double. - /// - /// The result. - /// The name. - /// The default value. - /// - public static double GetAttribute(this XmlNode result, string name, double defaultValue) - { - XmlAttribute? attr = result.Attributes?[name]; - - return attr is null - ? defaultValue - : double.Parse(attr.Value, System.Globalization.CultureInfo.InvariantCulture); - } - - /// - /// Gets the value of the given attribute as a DateTime. - /// - /// The result. - /// The name. - /// The default value. - /// - public static DateTime GetAttribute(this XmlNode result, string name, DateTime defaultValue) - { - string? dateStr = GetAttribute(result, name); - if (dateStr is null) - return defaultValue; - - DateTime date; - if (!DateTime.TryParse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AllowWhiteSpaces, out date)) - return defaultValue; - - return date; - } - } -} diff --git a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj index 5bd6728b6..4c571e87b 100644 --- a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj +++ b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj @@ -53,7 +53,6 @@ - From bd0024fb60070a1ad356f366d2d73d7496aa918f Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Sun, 20 Apr 2025 05:46:30 -0700 Subject: [PATCH 02/10] Move ResultSummary to nunit.common --- .../nunit.common}/ResultSummary.cs | 4 +--- .../nunit4-netcore-console/nunit4-netcore-console.csproj | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) rename src/{NUnitConsole/nunit4-console => NUnitCommon/nunit.common}/ResultSummary.cs (98%) diff --git a/src/NUnitConsole/nunit4-console/ResultSummary.cs b/src/NUnitCommon/nunit.common/ResultSummary.cs similarity index 98% rename from src/NUnitConsole/nunit4-console/ResultSummary.cs rename to src/NUnitCommon/nunit.common/ResultSummary.cs index ecdadc945..c45540670 100644 --- a/src/NUnitConsole/nunit4-console/ResultSummary.cs +++ b/src/NUnitCommon/nunit.common/ResultSummary.cs @@ -1,11 +1,9 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System; -using System.Globalization; using System.Xml; -using NUnit.ConsoleRunner.Utilities; -namespace NUnit.ConsoleRunner +namespace NUnit { /// /// Summary description for ResultSummary. diff --git a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj index 4c571e87b..8f0482abc 100644 --- a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj +++ b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj @@ -52,7 +52,6 @@ - From b2f97d3aac652adc7c25c66628c886337cf0e11d Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Sun, 20 Apr 2025 05:59:50 -0700 Subject: [PATCH 03/10] Rename ConsoleTestResult as ClientTestResult and move to nunit.common --- .../nunit.common/ClientTestResult.cs} | 10 +++++----- src/NUnitConsole/nunit4-console/ResultReporter.cs | 8 ++++---- .../nunit4-netcore-console.csproj | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) rename src/{NUnitConsole/nunit4-console/ConsoleTestResult.cs => NUnitCommon/nunit.common/ClientTestResult.cs} (94%) diff --git a/src/NUnitConsole/nunit4-console/ConsoleTestResult.cs b/src/NUnitCommon/nunit.common/ClientTestResult.cs similarity index 94% rename from src/NUnitConsole/nunit4-console/ConsoleTestResult.cs rename to src/NUnitCommon/nunit.common/ClientTestResult.cs index 247c4ab14..7aca978d2 100644 --- a/src/NUnitConsole/nunit4-console/ConsoleTestResult.cs +++ b/src/NUnitCommon/nunit.common/ClientTestResult.cs @@ -6,13 +6,13 @@ using System.Xml; using NUnit.TextDisplay; -namespace NUnit.ConsoleRunner +namespace NUnit { /// /// ConsoleTestResult represents the result of one test being /// displayed in the console report. /// - public class ConsoleTestResult + public class ClientTestResult { private static readonly char[] EOL_CHARS = new char[] { '\r', '\n' }; @@ -23,7 +23,7 @@ public class ConsoleTestResult /// /// An XmlNode representing the result /// Integer index used in the report listing - public ConsoleTestResult(XmlNode resultNode, int reportIndex) + public ClientTestResult(XmlNode resultNode, int reportIndex) { _resultNode = resultNode; ReportID = reportIndex.ToString(); @@ -32,7 +32,7 @@ public ConsoleTestResult(XmlNode resultNode, int reportIndex) Label = resultNode.GetAttribute("label"); Site = resultNode.GetAttribute("site"); - Status = Label ?? Result ?? "Unkown"; + Status = Label ?? Result ?? "Unknown"; if (Status == "Failed" || Status == "Error") if (Site == "SetUp" || Site == "TearDown") Status = Site + " " + Status; @@ -73,7 +73,7 @@ public List Assertions XmlNodeList? assertions = _resultNode.SelectNodes("assertions/assertion"); if (assertions is not null) foreach (XmlNode assertion in assertions) - Assertions.Add(new ConsoleTestResult.AssertionResult(assertion)); + Assertions.Add(new ClientTestResult.AssertionResult(assertion)); } return _assertions; diff --git a/src/NUnitConsole/nunit4-console/ResultReporter.cs b/src/NUnitConsole/nunit4-console/ResultReporter.cs index 03150d15c..49dac0b29 100644 --- a/src/NUnitConsole/nunit4-console/ResultReporter.cs +++ b/src/NUnitConsole/nunit4-console/ResultReporter.cs @@ -165,7 +165,7 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) { case "test-case": if (resultState == "Failed" || resultState == "Warning") - new ConsoleTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); return; case "test-run": @@ -181,7 +181,7 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) { // Report failure of the entire theory and then go on // to list the individual cases that failed - new ConsoleTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); } else { @@ -203,7 +203,7 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) // Only report errors in the current test method, setup or teardown if (site == "SetUp" || site == "TearDown" || site == "Test") - new ConsoleTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); // Do not list individual "failed" tests after a one-time setup failure if (site == "SetUp") @@ -234,7 +234,7 @@ private void WriteNotRunResults(XmlNode resultNode) string? status = resultNode.GetAttribute("result"); if (status == "Skipped") - new ConsoleTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); break; diff --git a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj index 8f0482abc..b40a015dc 100644 --- a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj +++ b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj @@ -43,7 +43,6 @@ - From 70a40c9d161b38d491a38172c6cbfe76d68abbee Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Sun, 20 Apr 2025 06:28:06 -0700 Subject: [PATCH 04/10] Move ResultReporter to nunit.common --- .../TextDisplay}/ResultReporterTests.cs | 6 ++--- .../nunit.common.tests.csproj | 1 + .../TextDisplay}/ResultReporter.cs | 23 ++++++++----------- .../nunit4-console.tests/BadFileTests.cs | 2 +- .../nunit4-console/ConsoleRunner.cs | 2 +- .../nunit4-console/TestEventHandler.cs | 4 +--- .../nunit4-netcore-console.csproj | 1 - 7 files changed, 16 insertions(+), 23 deletions(-) rename src/{NUnitConsole/nunit4-console.tests => NUnitCommon/nunit.common.tests/TextDisplay}/ResultReporterTests.cs (97%) rename src/{NUnitConsole/nunit4-console => NUnitCommon/nunit.common/TextDisplay}/ResultReporter.cs (95%) diff --git a/src/NUnitConsole/nunit4-console.tests/ResultReporterTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs similarity index 97% rename from src/NUnitConsole/nunit4-console.tests/ResultReporterTests.cs rename to src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs index a5d6934a7..64d4c92c3 100644 --- a/src/NUnitConsole/nunit4-console.tests/ResultReporterTests.cs +++ b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs @@ -5,14 +5,12 @@ using System.IO; using System.Text; using System.Xml; -using NUnit.ConsoleRunner.Options; using NUnit.Engine; using NUnit.Framework; using NUnit.Framework.Api; using NUnit.TestData.Assemblies; -using NUnit.TextDisplay; -namespace NUnit.ConsoleRunner +namespace NUnit.TextDisplay { public class ResultReporterTests { @@ -51,7 +49,7 @@ public void CreateReporter() { _report = new StringBuilder(); var writer = new ExtendedTextWrapper(new StringWriter(_report)); - _reporter = new ResultReporter(_result, writer, ConsoleMocks.Options()); + _reporter = new ResultReporter(_result, writer); } [Test] diff --git a/src/NUnitCommon/nunit.common.tests/nunit.common.tests.csproj b/src/NUnitCommon/nunit.common.tests/nunit.common.tests.csproj index e6aaaa5fb..2cf43ee28 100644 --- a/src/NUnitCommon/nunit.common.tests/nunit.common.tests.csproj +++ b/src/NUnitCommon/nunit.common.tests/nunit.common.tests.csproj @@ -7,6 +7,7 @@ + diff --git a/src/NUnitConsole/nunit4-console/ResultReporter.cs b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs similarity index 95% rename from src/NUnitConsole/nunit4-console/ResultReporter.cs rename to src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs index 49dac0b29..ec6f58985 100644 --- a/src/NUnitConsole/nunit4-console/ResultReporter.cs +++ b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs @@ -1,21 +1,18 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System; -using System.Collections.Generic; using System.Globalization; using System.Xml; -using NUnit.ConsoleRunner.Options; -using NUnit.TextDisplay; -namespace NUnit.ConsoleRunner +namespace NUnit.TextDisplay { public class ResultReporter { - public ResultReporter(XmlNode resultNode, ExtendedTextWriter writer, ConsoleOptions options) + public ResultReporter(XmlNode resultNode, ExtendedTextWriter writer, bool stopOnError = false) { ResultNode = resultNode; Writer = writer; - Options = options; + StopOnError = stopOnError; string? overallResult = resultNode.GetAttribute("result"); if (overallResult == "Skipped") @@ -32,8 +29,8 @@ public ResultReporter(XmlNode resultNode, ExtendedTextWriter writer, ConsoleOpti private int ReportIndex { get; set; } private XmlNode ResultNode { get; set; } private ExtendedTextWriter Writer { get; set; } - private ConsoleOptions Options { get; set; } private string OverallResult { get; set; } + private bool StopOnError { get; set; } /// /// Reports the results to the console @@ -53,7 +50,7 @@ public void ReportResults() WriteSummaryReport(); } - internal void WriteRunSettingsReport() + public void WriteRunSettingsReport() { var firstSuite = ResultNode.SelectSingleNode("test-suite"); if (firstSuite is not null) @@ -150,11 +147,11 @@ public void WriteErrorsFailuresAndWarningsReport() WriteErrorsFailuresAndWarnings(ResultNode); - if (Options.StopOnError) - { - Writer.WriteLine(ColorStyle.Failure, "Execution terminated after first error"); - Writer.WriteLine(); - } + //if (Options.StopOnError) + //{ + // Writer.WriteLine(ColorStyle.Failure, "Execution terminated after first error"); + // Writer.WriteLine(); + //} } private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) diff --git a/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs b/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs index 2bbdaab44..17fa7042e 100644 --- a/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs +++ b/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs @@ -36,7 +36,7 @@ public void MissingFileTest(string filename, string message) var result = runner.Run(this, TestFilter.Empty); var sb = new StringBuilder(); var writer = new ExtendedTextWrapper(new StringWriter(sb)); - var reporter = new ResultReporter(result, writer, ConsoleMocks.Options()); + var reporter = new ResultReporter(result, writer); reporter.WriteErrorsFailuresAndWarningsReport(); var report = sb.ToString(); diff --git a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs index bd7ffed3f..3a3aa4b40 100644 --- a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs +++ b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs @@ -271,7 +271,7 @@ private int RunTests(TestPackage package, TestFilter filter) if (result is not null) { - var reporter = new ResultReporter(result, writer, _options); + var reporter = new ResultReporter(result, writer, _options.StopOnError); reporter.ReportResults(); foreach (var spec in _options.ResultOutputSpecifications) diff --git a/src/NUnitConsole/nunit4-console/TestEventHandler.cs b/src/NUnitConsole/nunit4-console/TestEventHandler.cs index 3993d6fb4..862d446b6 100644 --- a/src/NUnitConsole/nunit4-console/TestEventHandler.cs +++ b/src/NUnitConsole/nunit4-console/TestEventHandler.cs @@ -1,12 +1,10 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt -using System; using System.Xml; using NUnit.Common; using NUnit.Engine; -using NUnit.TextDisplay; -namespace NUnit.ConsoleRunner +namespace NUnit.TextDisplay { /// /// TestEventHandler processes events from the running diff --git a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj index b40a015dc..fd7076134 100644 --- a/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj +++ b/src/NUnitConsole/nunit4-netcore-console/nunit4-netcore-console.csproj @@ -50,7 +50,6 @@ - From 1927f38afd3e7e4ba716014ff9433e840fda8626 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Sun, 20 Apr 2025 08:54:11 -0700 Subject: [PATCH 05/10] Move more tests to nunit.common.tests --- .../nunit.common.tests}/ExceptionHelperTests.cs | 7 +++---- .../nunit.common.tests/TextDisplay}/ColorConsoleTests.cs | 0 .../nunit.common.tests/TextDisplay}/ColorStyleTests.cs | 0 .../TextDisplay}/ExtendedTextWrapperTests.cs | 0 4 files changed, 3 insertions(+), 4 deletions(-) rename src/{NUnitConsole/nunit4-console.tests => NUnitCommon/nunit.common.tests}/ExceptionHelperTests.cs (93%) rename src/{NUnitConsole/nunit4-console.tests => NUnitCommon/nunit.common.tests/TextDisplay}/ColorConsoleTests.cs (100%) rename src/{NUnitConsole/nunit4-console.tests => NUnitCommon/nunit.common.tests/TextDisplay}/ColorStyleTests.cs (100%) rename src/{NUnitConsole/nunit4-console.tests => NUnitCommon/nunit.common.tests/TextDisplay}/ExtendedTextWrapperTests.cs (100%) diff --git a/src/NUnitConsole/nunit4-console.tests/ExceptionHelperTests.cs b/src/NUnitCommon/nunit.common.tests/ExceptionHelperTests.cs similarity index 93% rename from src/NUnitConsole/nunit4-console.tests/ExceptionHelperTests.cs rename to src/NUnitCommon/nunit.common.tests/ExceptionHelperTests.cs index 2fa3f1c29..f1a3d2fdb 100644 --- a/src/NUnitConsole/nunit4-console.tests/ExceptionHelperTests.cs +++ b/src/NUnitCommon/nunit.common.tests/ExceptionHelperTests.cs @@ -4,11 +4,10 @@ using System.Collections.Generic; using System.IO; using System.Reflection; -using NUnit.Common; using NUnit.Engine; using NUnit.Framework; -namespace NUnit.ConsoleRunner +namespace NUnit { internal class ExceptionHelperTests { @@ -53,8 +52,8 @@ private static IEnumerable TestCases yield return new TestCaseData(exception3, new[] { typeof(InvalidOperationException), typeof(FileNotFoundException), typeof(AccessViolationException) }) .SetName("{m}(Multiple InnerExceptions)"); - var relfectionException = new ReflectionTypeLoadException(new[] { typeof(ExceptionHelperTests) }, new[] { new FileNotFoundException() }); - yield return new TestCaseData(relfectionException, new[] { typeof(ReflectionTypeLoadException), typeof(FileNotFoundException) }) + var reflectionException = new ReflectionTypeLoadException(new[] { typeof(ExceptionHelperTests) }, new[] { new FileNotFoundException() }); + yield return new TestCaseData(reflectionException, new[] { typeof(ReflectionTypeLoadException), typeof(FileNotFoundException) }) .SetName("{m}(LoaderException)"); } } diff --git a/src/NUnitConsole/nunit4-console.tests/ColorConsoleTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ColorConsoleTests.cs similarity index 100% rename from src/NUnitConsole/nunit4-console.tests/ColorConsoleTests.cs rename to src/NUnitCommon/nunit.common.tests/TextDisplay/ColorConsoleTests.cs diff --git a/src/NUnitConsole/nunit4-console.tests/ColorStyleTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ColorStyleTests.cs similarity index 100% rename from src/NUnitConsole/nunit4-console.tests/ColorStyleTests.cs rename to src/NUnitCommon/nunit.common.tests/TextDisplay/ColorStyleTests.cs diff --git a/src/NUnitConsole/nunit4-console.tests/ExtendedTextWrapperTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ExtendedTextWrapperTests.cs similarity index 100% rename from src/NUnitConsole/nunit4-console.tests/ExtendedTextWrapperTests.cs rename to src/NUnitCommon/nunit.common.tests/TextDisplay/ExtendedTextWrapperTests.cs From eb2c1a34218a1d0f5e14bc21a89bb3ad9ee07685 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Mon, 21 Apr 2025 02:17:43 -0700 Subject: [PATCH 06/10] Convert ResultReporter to static class --- .../nunit.agent.core/AgentDirectRunner.cs | 12 +- .../TextDisplay/ResultReporterTests.cs | 52 ++--- src/NUnitCommon/nunit.common/ResultSummary.cs | 22 ++- .../TextDisplay/ResultReporter.cs | 178 ++++++++---------- .../nunit4-console.tests/BadFileTests.cs | 3 +- .../nunit4-console/ConsoleRunner.cs | 12 +- 6 files changed, 138 insertions(+), 141 deletions(-) diff --git a/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs b/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs index 3189156b5..71f6a7d9c 100644 --- a/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs +++ b/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs @@ -30,7 +30,7 @@ public void ExecuteTestsDirectly() { var testFile = _options.Files[0]; - WriteHeader(); + WriteHeader(OutWriter); TestPackage package = new TestPackage(testFile).SubPackages[0]; @@ -66,7 +66,7 @@ public void ExecuteTestsDirectly() Environment.Exit(AgentExitCodes.OK); } - private void WriteHeader() + private static void WriteHeader(ExtendedTextWriter outWriter) { var ea = Assembly.GetEntryAssembly(); if (ea is not null) @@ -75,11 +75,11 @@ private void WriteHeader() var version = GetAttribute(ea)?.Version; var copyright = GetAttribute(ea)?.Copyright; - OutWriter.WriteLine(ColorStyle.Header, $"{title} {version}"); + outWriter.WriteLine(ColorStyle.Header, $"{title} {version}"); if (copyright is not null) - OutWriter.WriteLine(ColorStyle.SubHeader, copyright); - OutWriter.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); - OutWriter.WriteLine(); + outWriter.WriteLine(ColorStyle.SubHeader, copyright); + outWriter.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); + outWriter.WriteLine(); } } diff --git a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs index 64d4c92c3..fde914de9 100644 --- a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs +++ b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs @@ -15,7 +15,6 @@ namespace NUnit.TextDisplay public class ResultReporterTests { private XmlNode _result; - private ResultReporter _reporter; private StringBuilder _report; [OneTimeSetUp] @@ -49,13 +48,15 @@ public void CreateReporter() { _report = new StringBuilder(); var writer = new ExtendedTextWrapper(new StringWriter(_report)); - _reporter = new ResultReporter(_result, writer); } [Test] public void ReportSequenceTest() { - var report = GetReport(_reporter.ReportResults); + var sb = new StringBuilder(); + var writer = new ExtendedTextWrapper(new StringWriter(sb)); + ResultReporter.ReportResults(new ResultSummary(_result), writer); + var report = sb.ToString(); var reportSequence = new[] { @@ -93,12 +94,15 @@ public void SummaryReportTest() }; #pragma warning restore SA1137 // Elements should have the same indentation - var actualSummary = GetReportLines(_reporter.WriteSummaryReport); - Assert.That(actualSummary, Is.EqualTo(expected)); + var report = new StringBuilder(); + var writer = new ExtendedTextWrapper(new StringWriter(report)); + ResultReporter.WriteSummaryReport(_result, new ResultSummary(_result), writer); + var lines = GetReportLines(report.ToString()); + Assert.That(lines, Is.EqualTo(expected)); } [Test] - public void ErrorsAndFailuresReportTest() + public void ErrorsFailuresAndWarningsReportTest() { var nl = Environment.NewLine; @@ -119,12 +123,14 @@ public void ErrorsAndFailuresReportTest() "No suitable constructor was found" }; - var actualErrorFailuresReport = GetReport(_reporter.WriteErrorsFailuresAndWarningsReport); + var sb = new StringBuilder(); + var writer = new ExtendedTextWrapper(new StringWriter(sb)); + ResultReporter.WriteErrorsFailuresAndWarningsReport(_result, writer); - foreach (var ex in expected) - { - Assert.That(actualErrorFailuresReport, Does.Contain(ex)); - } + var report = sb.ToString(); + + foreach (var item in expected) + Assert.That(report.Contains(item)); } [Test] @@ -156,8 +162,11 @@ public void TestsNotRunTest() string.Empty }; - var report = GetReportLines(_reporter.WriteNotRunReport); - Assert.That(report, Is.EqualTo(expected)); + var report = new StringBuilder(); + var writer = new ExtendedTextWrapper(new StringWriter(report)); + ResultReporter.WriteNotRunReport(_result, writer); + var lines = GetReportLines(report.ToString()); + Assert.That(lines, Is.EqualTo(expected)); } [Test, Explicit("Displays failure behavior")] @@ -177,8 +186,11 @@ public void TestParameterSettingsWrittenCorrectly() " 2 -> |c|" }; - var report = GetReportLines(_reporter.WriteRunSettingsReport); - Assert.That(report, Is.SupersetOf(expected)); + var report = new StringBuilder(); + var writer = new ExtendedTextWrapper(new StringWriter(report)); + ResultReporter.WriteRunSettingsReport(_result, writer); + var lines = GetReportLines(report.ToString()); + Assert.That(lines, Is.SupersetOf(expected)); } private static TestEngineResult AddMetadata(TestEngineResult input) @@ -186,15 +198,9 @@ private static TestEngineResult AddMetadata(TestEngineResult input) return input.Aggregate("test-run start-time=\"2015-10-19 02:12:28Z\" end-time=\"2015-10-19 02:12:29Z\" duration=\"0.348616\"", string.Empty, string.Empty, string.Empty); } - private string GetReport(TestDelegate del) - { - del(); - return _report.ToString(); - } - - private List GetReportLines(TestDelegate del) + private static List GetReportLines(string report) { - var rdr = new StringReader(GetReport(del)); + var rdr = new StringReader(report.ToString()); string? line; var lines = new List(); diff --git a/src/NUnitCommon/nunit.common/ResultSummary.cs b/src/NUnitCommon/nunit.common/ResultSummary.cs index c45540670..f49db6e8d 100644 --- a/src/NUnitCommon/nunit.common/ResultSummary.cs +++ b/src/NUnitCommon/nunit.common/ResultSummary.cs @@ -10,16 +10,30 @@ namespace NUnit /// public class ResultSummary { - public ResultSummary(XmlNode result) + public ResultSummary(XmlNode resultNode) { - if (result.Name != "test-run") - throw new InvalidOperationException("Expected as top-level element but was <" + result.Name + ">"); + if (resultNode.Name != "test-run") + throw new InvalidOperationException("Expected as top-level element but was <" + resultNode.Name + ">"); InitializeCounters(); - Summarize(result, false); + Summarize(resultNode, false); + + string? overallResult = resultNode.GetAttribute("result"); + if (overallResult == "Skipped") + OverallResult = "Warning"; + if (overallResult is null) + OverallResult = "Unknown"; + else + OverallResult = overallResult; + + ResultNode = resultNode; } + public XmlNode ResultNode { get; } + + public string OverallResult { get; } + /// /// Gets the number of test cases for which results /// have been summarized. Any tests excluded by use of diff --git a/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs index ec6f58985..b87ef2639 100644 --- a/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs +++ b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs @@ -6,155 +6,133 @@ namespace NUnit.TextDisplay { - public class ResultReporter + public static class ResultReporter { - public ResultReporter(XmlNode resultNode, ExtendedTextWriter writer, bool stopOnError = false) - { - ResultNode = resultNode; - Writer = writer; - StopOnError = stopOnError; - - string? overallResult = resultNode.GetAttribute("result"); - if (overallResult == "Skipped") - OverallResult = "Warning"; - if (overallResult is null) - OverallResult = "Unknown"; - else - OverallResult = overallResult; - Summary = new ResultSummary(resultNode); - } - - public ResultSummary Summary { get; private set; } - - private int ReportIndex { get; set; } - private XmlNode ResultNode { get; set; } - private ExtendedTextWriter Writer { get; set; } - private string OverallResult { get; set; } - private bool StopOnError { get; set; } - /// /// Reports the results to the console /// - public void ReportResults() + public static void ReportResults(ResultSummary summary, ExtendedTextWriter writer, bool stopOnError = false) { - Writer.WriteLine(); + writer.WriteLine(); + + var topLevelResult = summary.ResultNode; - if (Summary.ExplicitCount + Summary.SkipCount + Summary.IgnoreCount > 0) - WriteNotRunReport(); + if (summary.ExplicitCount + summary.SkipCount + summary.IgnoreCount > 0) + WriteNotRunReport(topLevelResult, writer); - if (OverallResult == "Failed" || Summary.WarningCount > 0) - WriteErrorsFailuresAndWarningsReport(); + if (summary.OverallResult == "Failed" || summary.WarningCount > 0) + WriteErrorsFailuresAndWarningsReport(topLevelResult, writer, stopOnError); - WriteRunSettingsReport(); + WriteRunSettingsReport(topLevelResult, writer); - WriteSummaryReport(); + WriteSummaryReport(topLevelResult, summary, writer); } - public void WriteRunSettingsReport() + public static void WriteRunSettingsReport(XmlNode topLevelResult, ExtendedTextWriter writer) { - var firstSuite = ResultNode.SelectSingleNode("test-suite"); + var firstSuite = topLevelResult.SelectSingleNode("test-suite"); if (firstSuite is not null) { var settings = firstSuite.SelectNodes("settings/setting"); if (settings is not null && settings.Count > 0) { - Writer.WriteLine(ColorStyle.SectionHeader, "Run Settings"); + writer.WriteLine(ColorStyle.SectionHeader, "Run Settings"); foreach (XmlNode node in settings) - WriteSettingsNode(node); + WriteSettingsNode(node, writer); - Writer.WriteLine(); + writer.WriteLine(); } } } - private void WriteSettingsNode(XmlNode node) + private static void WriteSettingsNode(XmlNode node, ExtendedTextWriter writer) { var items = node.SelectNodes("item"); var name = node.GetAttribute("name"); var val = node.GetAttribute("value") ?? string.Empty; if (items is null || items.Count == 0) - Writer.WriteLabelLine($" {name}:", $" |{val}|"); + writer.WriteLabelLine($" {name}:", $" |{val}|"); else { - Writer.WriteLabelLine($" {name}:", string.Empty); + writer.WriteLabelLine($" {name}:", string.Empty); foreach (XmlNode item in items) { var key = item.GetAttribute("key"); var value = item.GetAttribute("value"); - Writer.WriteLine(ColorStyle.Value, $" {key} -> |{value}|"); + writer.WriteLine(ColorStyle.Value, $" {key} -> |{value}|"); } } } - public void WriteSummaryReport() + public static void WriteSummaryReport(XmlNode topLevelResult, ResultSummary summary, ExtendedTextWriter writer) { const string INDENT4 = " "; const string INDENT8 = " "; - ColorStyle overall = OverallResult == "Passed" + ColorStyle resultColor = summary.OverallResult == "Passed" ? ColorStyle.Pass - : OverallResult == "Failed" || OverallResult == "Unknown" + : summary.OverallResult == "Failed" || summary.OverallResult == "Unknown" ? ColorStyle.Failure - : OverallResult == "Warning" + : summary.OverallResult == "Warning" ? ColorStyle.Warning : ColorStyle.Output; - Writer.WriteLine(ColorStyle.SectionHeader, "Test Run Summary"); - Writer.WriteLabelLine(INDENT4 + "Overall result: ", OverallResult, overall); + writer.WriteLine(ColorStyle.SectionHeader, "Test Run Summary"); + writer.WriteLabelLine(INDENT4 + "Overall result: ", summary.OverallResult, resultColor); - WriteSummaryCount(INDENT4 + "Test Count: ", Summary.TestCount); - WriteSummaryCount(", Pass: ", Summary.PassCount); - WriteSummaryCount(", Fail: ", Summary.FailedCount, ColorStyle.Failure); - WriteSummaryCount(", Warn: ", Summary.WarningCount, ColorStyle.Warning); - WriteSummaryCount(", Inconclusive: ", Summary.InconclusiveCount); - WriteSummaryCount(", Skip: ", Summary.TotalSkipCount); - Writer.WriteLine(); + WriteSummaryCount(writer, INDENT4 + "Test Count: ", summary.TestCount); + WriteSummaryCount(writer, ", Pass: ", summary.PassCount); + WriteSummaryCount(writer, ", Fail: ", summary.FailedCount, ColorStyle.Failure); + WriteSummaryCount(writer, ", Warn: ", summary.WarningCount, ColorStyle.Warning); + WriteSummaryCount(writer, ", Inconclusive: ", summary.InconclusiveCount); + WriteSummaryCount(writer, ", Skip: ", summary.TotalSkipCount); + writer.WriteLine(); - if (Summary.FailedCount > 0) + if (summary.FailedCount > 0) { - WriteSummaryCount(INDENT8 + "Failed Tests - Failures: ", Summary.FailureCount); - WriteSummaryCount(", Errors: ", Summary.ErrorCount, ColorStyle.Error); - WriteSummaryCount(", Invalid: ", Summary.InvalidCount); - Writer.WriteLine(); + WriteSummaryCount(writer, INDENT8 + "Failed Tests - Failures: ", summary.FailureCount); + WriteSummaryCount(writer, ", Errors: ", summary.ErrorCount, ColorStyle.Error); + WriteSummaryCount(writer, ", Invalid: ", summary.InvalidCount); + writer.WriteLine(); } - if (Summary.TotalSkipCount > 0) + if (summary.TotalSkipCount > 0) { - WriteSummaryCount(INDENT8 + "Skipped Tests - Ignored: ", Summary.IgnoreCount); - WriteSummaryCount(", Explicit: ", Summary.ExplicitCount); - WriteSummaryCount(", Other: ", Summary.SkipCount); - Writer.WriteLine(); + WriteSummaryCount(writer, INDENT8 + "Skipped Tests - Ignored: ", summary.IgnoreCount); + WriteSummaryCount(writer, ", Explicit: ", summary.ExplicitCount); + WriteSummaryCount(writer, ", Other: ", summary.SkipCount); + writer.WriteLine(); } - var duration = ResultNode.GetAttribute("duration", 0.0); - var startTime = ResultNode.GetAttribute("start-time", DateTime.MinValue); - var endTime = ResultNode.GetAttribute("end-time", DateTime.MaxValue); + var duration = topLevelResult.GetAttribute("duration", 0.0); + var startTime = topLevelResult.GetAttribute("start-time", DateTime.MinValue); + var endTime = topLevelResult.GetAttribute("end-time", DateTime.MaxValue); - Writer.WriteLabelLine(INDENT4 + "Start time: ", startTime.ToString("u")); - Writer.WriteLabelLine(INDENT4 + "End time: ", endTime.ToString("u")); - Writer.WriteLabelLine(INDENT4 + "Duration: ", string.Format(NumberFormatInfo.InvariantInfo, "{0:0.000} seconds", duration)); - Writer.WriteLine(); + writer.WriteLabelLine(INDENT4 + "Start time: ", startTime.ToString("u")); + writer.WriteLabelLine(INDENT4 + "End time: ", endTime.ToString("u")); + writer.WriteLabelLine(INDENT4 + "Duration: ", string.Format(NumberFormatInfo.InvariantInfo, "{0:0.000} seconds", duration)); + writer.WriteLine(); } - public void WriteErrorsFailuresAndWarningsReport() + public static void WriteErrorsFailuresAndWarningsReport(XmlNode resultNode, ExtendedTextWriter writer, bool stopOnError = false) { - ReportIndex = 0; - Writer.WriteLine(ColorStyle.SectionHeader, "Errors, Failures and Warnings"); - Writer.WriteLine(); + int reportIndex = 0; + writer.WriteLine(ColorStyle.SectionHeader, "Errors, Failures and Warnings"); + writer.WriteLine(); - WriteErrorsFailuresAndWarnings(ResultNode); + WriteErrorsFailuresAndWarnings(resultNode, writer, ref reportIndex); - //if (Options.StopOnError) - //{ - // Writer.WriteLine(ColorStyle.Failure, "Execution terminated after first error"); - // Writer.WriteLine(); - //} + if (stopOnError) + { + writer.WriteLine(ColorStyle.Failure, "Execution terminated after first error"); + writer.WriteLine(); + } } - private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) + private static void WriteErrorsFailuresAndWarnings(XmlNode resultNode, ExtendedTextWriter writer, ref int reportIndex) { string? resultState = resultNode.GetAttribute("result"); @@ -162,12 +140,12 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) { case "test-case": if (resultState == "Failed" || resultState == "Warning") - new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++reportIndex).WriteResult(writer); return; case "test-run": foreach (XmlNode childResult in resultNode.ChildNodes) - WriteErrorsFailuresAndWarnings(childResult); + WriteErrorsFailuresAndWarnings(childResult, writer, ref reportIndex); break; case "test-suite": @@ -178,7 +156,7 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) { // Report failure of the entire theory and then go on // to list the individual cases that failed - new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++reportIndex).WriteResult(writer); } else { @@ -200,7 +178,7 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) // Only report errors in the current test method, setup or teardown if (site == "SetUp" || site == "TearDown" || site == "Test") - new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++reportIndex).WriteResult(writer); // Do not list individual "failed" tests after a one-time setup failure if (site == "SetUp") @@ -209,21 +187,21 @@ private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) } foreach (XmlNode childResult in resultNode.ChildNodes) - WriteErrorsFailuresAndWarnings(childResult); + WriteErrorsFailuresAndWarnings(childResult, writer, ref reportIndex); break; } } - public void WriteNotRunReport() + public static void WriteNotRunReport(XmlNode resultNode, ExtendedTextWriter writer) { - ReportIndex = 0; - Writer.WriteLine(ColorStyle.SectionHeader, "Tests Not Run"); - Writer.WriteLine(); - WriteNotRunResults(ResultNode); + int reportIndex = 0; + writer.WriteLine(ColorStyle.SectionHeader, "Tests Not Run"); + writer.WriteLine(); + WriteNotRunResults(resultNode, writer, ref reportIndex); } - private void WriteNotRunResults(XmlNode resultNode) + private static void WriteNotRunResults(XmlNode resultNode, ExtendedTextWriter writer, ref int reportIndex) { switch (resultNode.Name) { @@ -231,27 +209,27 @@ private void WriteNotRunResults(XmlNode resultNode) string? status = resultNode.GetAttribute("result"); if (status == "Skipped") - new ClientTestResult(resultNode, ++ReportIndex).WriteResult(Writer); + new ClientTestResult(resultNode, ++reportIndex).WriteResult(writer); break; case "test-suite": case "test-run": foreach (XmlNode childResult in resultNode.ChildNodes) - WriteNotRunResults(childResult); + WriteNotRunResults(childResult, writer, ref reportIndex); break; } } - private void WriteSummaryCount(string label, int count) + private static void WriteSummaryCount(ExtendedTextWriter writer, string label, int count) { - Writer.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture)); + writer.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture)); } - private void WriteSummaryCount(string label, int count, ColorStyle color) + private static void WriteSummaryCount(ExtendedTextWriter writer, string label, int count, ColorStyle color) { - Writer.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture), count > 0 ? color : ColorStyle.Value); + writer.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture), count > 0 ? color : ColorStyle.Value); } } } diff --git a/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs b/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs index 17fa7042e..720a711a4 100644 --- a/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs +++ b/src/NUnitConsole/nunit4-console.tests/BadFileTests.cs @@ -36,9 +36,8 @@ public void MissingFileTest(string filename, string message) var result = runner.Run(this, TestFilter.Empty); var sb = new StringBuilder(); var writer = new ExtendedTextWrapper(new StringWriter(sb)); - var reporter = new ResultReporter(result, writer); - reporter.WriteErrorsFailuresAndWarningsReport(); + ResultReporter.WriteErrorsFailuresAndWarningsReport(result, writer); var report = sb.ToString(); Assert.That(report, Contains.Substring($"1) Invalid : {fullname}")); diff --git a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs index 3a3aa4b40..337ccc57d 100644 --- a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs +++ b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs @@ -271,8 +271,8 @@ private int RunTests(TestPackage package, TestFilter filter) if (result is not null) { - var reporter = new ResultReporter(result, writer, _options.StopOnError); - reporter.ReportResults(); + var summary = new ResultSummary(result); + ResultReporter.ReportResults(summary, writer, _options.StopOnError); foreach (var spec in _options.ResultOutputSpecifications) { @@ -292,16 +292,16 @@ private int RunTests(TestPackage package, TestFilter filter) writer.WriteLine(ColorStyle.Warning, Environment.NewLine + ExceptionHelper.BuildMessage(unloadException)); } - if (reporter.Summary.UnexpectedError) + if (summary.UnexpectedError) return ConsoleRunner.UNEXPECTED_ERROR; - if (reporter.Summary.InvalidAssemblies > 0) + if (summary.InvalidAssemblies > 0) return ConsoleRunner.INVALID_ASSEMBLY; - if (reporter.Summary.InvalidTestFixtures > 0) + if (summary.InvalidTestFixtures > 0) return ConsoleRunner.INVALID_TEST_FIXTURE; - var failureCount = reporter.Summary.FailureCount + reporter.Summary.ErrorCount + reporter.Summary.InvalidCount; + var failureCount = summary.FailureCount + summary.ErrorCount + summary.InvalidCount; return Math.Min(failureCount, MAXIMUM_RETURN_CODE_ALLOWED); } From bc71e6d00aea13fb31c0b22eb9431488650d3db0 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Mon, 21 Apr 2025 09:12:13 -0700 Subject: [PATCH 07/10] Add WriteHeader method; Refactor tests --- .../TextDisplay/ResultReporterTests.cs | 78 +++++++++---------- .../TextDisplay/ResultReporter.cs | 23 +++++- src/NUnitConsole/nunit4-console/Program.cs | 28 +------ 3 files changed, 60 insertions(+), 69 deletions(-) diff --git a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs index fde914de9..747f57290 100644 --- a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs +++ b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs @@ -15,7 +15,26 @@ namespace NUnit.TextDisplay public class ResultReporterTests { private XmlNode _result; - private StringBuilder _report; + + private StringBuilder _reportBuilder; + private ExtendedTextWrapper _writer; + + private string ReportOutput => _reportBuilder.ToString(); + + private List ReportLines + { + get + { + var rdr = new StringReader(ReportOutput); + + string? line; + var lines = new List(); + while ((line = rdr.ReadLine()) is not null) + lines.Add(line); + + return lines; + } + } [OneTimeSetUp] public void CreateResult() @@ -44,19 +63,19 @@ public void CreateResult() } [SetUp] - public void CreateReporter() + public void SetUp() { - _report = new StringBuilder(); - var writer = new ExtendedTextWrapper(new StringWriter(_report)); + _reportBuilder = new StringBuilder(); + _writer = new ExtendedTextWrapper(new StringWriter(_reportBuilder)); } + [TearDown] + public void TearDown() => _writer.Dispose(); + [Test] public void ReportSequenceTest() { - var sb = new StringBuilder(); - var writer = new ExtendedTextWrapper(new StringWriter(sb)); - ResultReporter.ReportResults(new ResultSummary(_result), writer); - var report = sb.ToString(); + ResultReporter.ReportResults(new ResultSummary(_result), _writer); var reportSequence = new[] { @@ -69,7 +88,7 @@ public void ReportSequenceTest() foreach (string title in reportSequence) { - var index = report.IndexOf(title); + var index = ReportOutput.IndexOf(title); Assert.That(index > 0, "Report not found: " + title); Assert.That(index > last, "Report out of sequence: " + title); last = index; @@ -94,11 +113,8 @@ public void SummaryReportTest() }; #pragma warning restore SA1137 // Elements should have the same indentation - var report = new StringBuilder(); - var writer = new ExtendedTextWrapper(new StringWriter(report)); - ResultReporter.WriteSummaryReport(_result, new ResultSummary(_result), writer); - var lines = GetReportLines(report.ToString()); - Assert.That(lines, Is.EqualTo(expected)); + ResultReporter.WriteSummaryReport(new ResultSummary(_result), _writer); + Assert.That(ReportLines, Is.EqualTo(expected)); } [Test] @@ -123,14 +139,10 @@ public void ErrorsFailuresAndWarningsReportTest() "No suitable constructor was found" }; - var sb = new StringBuilder(); - var writer = new ExtendedTextWrapper(new StringWriter(sb)); - ResultReporter.WriteErrorsFailuresAndWarningsReport(_result, writer); - - var report = sb.ToString(); + ResultReporter.WriteErrorsFailuresAndWarningsReport(_result, _writer); foreach (var item in expected) - Assert.That(report.Contains(item)); + Assert.That(ReportOutput.Contains(item)); } [Test] @@ -162,11 +174,8 @@ public void TestsNotRunTest() string.Empty }; - var report = new StringBuilder(); - var writer = new ExtendedTextWrapper(new StringWriter(report)); - ResultReporter.WriteNotRunReport(_result, writer); - var lines = GetReportLines(report.ToString()); - Assert.That(lines, Is.EqualTo(expected)); + ResultReporter.WriteNotRunReport(_result, _writer); + Assert.That(ReportLines, Is.EqualTo(expected)); } [Test, Explicit("Displays failure behavior")] @@ -186,28 +195,13 @@ public void TestParameterSettingsWrittenCorrectly() " 2 -> |c|" }; - var report = new StringBuilder(); - var writer = new ExtendedTextWrapper(new StringWriter(report)); - ResultReporter.WriteRunSettingsReport(_result, writer); - var lines = GetReportLines(report.ToString()); - Assert.That(lines, Is.SupersetOf(expected)); + ResultReporter.WriteRunSettingsReport(_result, _writer); + Assert.That(ReportLines, Is.SupersetOf(expected)); } private static TestEngineResult AddMetadata(TestEngineResult input) { return input.Aggregate("test-run start-time=\"2015-10-19 02:12:28Z\" end-time=\"2015-10-19 02:12:29Z\" duration=\"0.348616\"", string.Empty, string.Empty, string.Empty); } - - private static List GetReportLines(string report) - { - var rdr = new StringReader(report.ToString()); - - string? line; - var lines = new List(); - while ((line = rdr.ReadLine()) is not null) - lines.Add(line); - - return lines; - } } } \ No newline at end of file diff --git a/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs index b87ef2639..a0994dcb0 100644 --- a/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs +++ b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs @@ -1,13 +1,30 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System; +using System.Diagnostics; using System.Globalization; +using System.Reflection; using System.Xml; namespace NUnit.TextDisplay { public static class ResultReporter { + public static void WriteHeader(ExtendedTextWriter writer) + { + Assembly entryAssembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); + var versionBlock = FileVersionInfo.GetVersionInfo(entryAssembly.ManifestModule.FullyQualifiedName); + + var header = $"{versionBlock.ProductName} {versionBlock.ProductVersion}"; + + var configurationAttributes = entryAssembly.GetCustomAttribute(); + + writer.WriteLine(ColorStyle.Header, header); + writer.WriteLine(ColorStyle.SubHeader, versionBlock.LegalCopyright ?? "No Copyright statement found"); + writer.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); + writer.WriteLine(); + } + /// /// Reports the results to the console /// @@ -25,7 +42,7 @@ public static void ReportResults(ResultSummary summary, ExtendedTextWriter write WriteRunSettingsReport(topLevelResult, writer); - WriteSummaryReport(topLevelResult, summary, writer); + WriteSummaryReport(summary, writer); } public static void WriteRunSettingsReport(XmlNode topLevelResult, ExtendedTextWriter writer) @@ -68,11 +85,13 @@ private static void WriteSettingsNode(XmlNode node, ExtendedTextWriter writer) } } - public static void WriteSummaryReport(XmlNode topLevelResult, ResultSummary summary, ExtendedTextWriter writer) + public static void WriteSummaryReport(ResultSummary summary, ExtendedTextWriter writer) { const string INDENT4 = " "; const string INDENT8 = " "; + var topLevelResult = summary.ResultNode; + ColorStyle resultColor = summary.OverallResult == "Passed" ? ColorStyle.Pass : summary.OverallResult == "Failed" || summary.OverallResult == "Unknown" diff --git a/src/NUnitConsole/nunit4-console/Program.cs b/src/NUnitConsole/nunit4-console/Program.cs index fbb58e00b..70f10229d 100644 --- a/src/NUnitConsole/nunit4-console/Program.cs +++ b/src/NUnitConsole/nunit4-console/Program.cs @@ -46,7 +46,7 @@ public static int Main(string[] args) } catch (OptionException ex) { - WriteHeader(); + ResultReporter.WriteHeader(OutWriter); WriteErrorMessage(string.Format(ex.Message, ex.OptionName)); return ConsoleRunner.INVALID_ARG; } @@ -59,7 +59,7 @@ public static int Main(string[] args) } catch (Exception error) { - WriteHeader(); + ResultReporter.WriteHeader(OutWriter); WriteErrorMessage(string.Format("Unsupported Encoding, {0}", error.Message)); return ConsoleRunner.INVALID_ARG; } @@ -68,7 +68,7 @@ public static int Main(string[] args) try { if (Options.ShowVersion || !Options.NoHeader) - WriteHeader(); + ResultReporter.WriteHeader(OutWriter); if (Options.ShowHelp || args.Length == 0) { @@ -171,28 +171,6 @@ public static int Main(string[] args) } } - private static void WriteHeader() - { - Assembly entryAssembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); - var versionBlock = FileVersionInfo.GetVersionInfo(entryAssembly.ManifestModule.FullyQualifiedName); - - var header = $"{versionBlock.ProductName} {versionBlock.ProductVersion}"; - - var configurationAttributes = entryAssembly.GetCustomAttributes().ToArray(); - - if (configurationAttributes.Length > 0) - { - string configuration = ((AssemblyConfigurationAttribute)configurationAttributes[0]).Configuration; - if (!string.IsNullOrEmpty(configuration)) - header += $" ({configuration})"; - } - - OutWriter.WriteLine(ColorStyle.Header, header); - OutWriter.WriteLine(ColorStyle.SubHeader, versionBlock.LegalCopyright ?? "No Copyright statement found"); - OutWriter.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); - OutWriter.WriteLine(); - } - private static void WriteHelpText() { OutWriter.WriteLine(); From 86b835da201f0e5d9d5e3f4078061ab08ca525b3 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Tue, 22 Apr 2025 17:11:12 -0700 Subject: [PATCH 08/10] AgentRunner using ResultReporter --- .../AgentDirectRunnerTests.cs | 12 +- .../Drivers/NUnitFrameworkDriverTests.cs | 2 +- .../Runners/TestAgentRunnerTests.cs | 2 +- .../nunit.agent.core/AgentDirectRunner.cs | 253 +----------------- .../TextDisplay/ResultReporterTests.cs | 16 +- src/NUnitCommon/nunit.common/ResultSummary.cs | 13 +- src/TestData/mock-assembly/MockAssembly.cs | 28 +- 7 files changed, 46 insertions(+), 280 deletions(-) diff --git a/src/NUnitCommon/nunit.agent.core.tests/AgentDirectRunnerTests.cs b/src/NUnitCommon/nunit.agent.core.tests/AgentDirectRunnerTests.cs index 0c11f86b5..0999afd13 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/AgentDirectRunnerTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/AgentDirectRunnerTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Text; +using NUnit.Common; using NUnit.Framework; using NUnit.TestData.Assemblies; @@ -28,6 +29,7 @@ private static void RunTestUnderTestBed(string testAssembly) #else string agentExe = Path.ChangeExtension(agentAssembly, ".exe"); #endif + MockAssembly.DisplayCounts(); var startInfo = new ProcessStartInfo(agentExe); startInfo.Arguments = testAssembly; @@ -39,16 +41,10 @@ private static void RunTestUnderTestBed(string testAssembly) if (process is not null) { process.WaitForExit(); - - string output = process.StandardOutput.ReadToEnd(); - int index = output.IndexOf("Test Run Summary"); - if (index > 0) - output = output.Substring(index); - - Console.WriteLine(output); Console.WriteLine($"Agent process exited with rc={process.ExitCode}"); - if (index < 0) + string output = process.StandardOutput.ReadToEnd(); + if (!output.Contains("Test Run Summary")) Assert.Fail("No Summary Report found"); } } diff --git a/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs b/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs index a47091bf9..c7c041fac 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs @@ -107,7 +107,7 @@ public void RunTestsAction_AfterLoad_ReturnsRunnableSuite() Assert.That(result.GetAttribute("runstate"), Is.EqualTo("Runnable")); Assert.That(result.GetAttribute("testcasecount"), Is.EqualTo(MockAssembly.Tests.ToString())); Assert.That(result.GetAttribute("result"), Is.EqualTo("Failed")); - Assert.That(result.GetAttribute("passed"), Is.EqualTo(MockAssembly.PassedInAttribute.ToString())); + Assert.That(result.GetAttribute("passed"), Is.EqualTo(MockAssembly.Passed.ToString())); Assert.That(result.GetAttribute("failed"), Is.EqualTo(MockAssembly.Failed.ToString())); Assert.That(result.GetAttribute("skipped"), Is.EqualTo(MockAssembly.Skipped.ToString())); Assert.That(result.GetAttribute("inconclusive"), Is.EqualTo(MockAssembly.Inconclusive.ToString())); diff --git a/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs b/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs index 1e1b12f27..c886af4db 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs @@ -114,7 +114,7 @@ private static void CheckRunResult(TestEngineResult result) private static void CheckRunResult(XmlNode result) { CheckBasicResult(result); - Assert.That(result.GetAttribute("passed", 0), Is.EqualTo(MockAssembly.PassedInAttribute)); + Assert.That(result.GetAttribute("passed", 0), Is.EqualTo(MockAssembly.Passed)); Assert.That(result.GetAttribute("failed", 0), Is.EqualTo(MockAssembly.Failed)); Assert.That(result.GetAttribute("skipped", 0), Is.EqualTo(MockAssembly.Skipped)); Assert.That(result.GetAttribute("inconclusive", 0), Is.EqualTo(MockAssembly.Inconclusive)); diff --git a/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs b/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs index 71f6a7d9c..560b8f10f 100644 --- a/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs +++ b/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs @@ -1,9 +1,7 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System; -using System.Globalization; using System.IO; -using System.Reflection; using System.Xml; using NUnit.TextDisplay; using NUnit.Engine; @@ -17,7 +15,6 @@ public class AgentDirectRunner private AgentOptions _options; private ColorConsoleWriter OutWriter { get; } = new ColorConsoleWriter(); - private int ReportIndex { get; set; } public AgentDirectRunner(AgentOptions options) { @@ -30,7 +27,7 @@ public void ExecuteTestsDirectly() { var testFile = _options.Files[0]; - WriteHeader(OutWriter); + ResultReporter.WriteHeader(OutWriter); TestPackage package = new TestPackage(testFile).SubPackages[0]; @@ -40,18 +37,9 @@ public void ExecuteTestsDirectly() var runner = new LocalTestRunner(package); #endif var xmlResult = runner.Run(null, TestFilter.Empty).Xml; + var summary = new ResultSummary(xmlResult); - WriteRunSettingsReport(xmlResult); - - var result = xmlResult.GetAttribute("result"); - if (result == "Failed" || result == "Warning") - WriteErrorsFailuresAndWarningsReport(xmlResult); - - int notrunCount = int.Parse(xmlResult.GetAttribute("skipped") ?? "0"); - if (notrunCount > 0) - WriteNotRunReport(xmlResult); - - WriteSummaryReport(xmlResult); + ResultReporter.ReportResults(summary, OutWriter); var pathToResultFile = Path.Combine(_options.WorkDirectory, "TestResult.xml"); WriteResultFile(xmlResult, pathToResultFile); @@ -66,241 +54,6 @@ public void ExecuteTestsDirectly() Environment.Exit(AgentExitCodes.OK); } - private static void WriteHeader(ExtendedTextWriter outWriter) - { - var ea = Assembly.GetEntryAssembly(); - if (ea is not null) - { - var title = GetAttribute(ea)?.Title; - var version = GetAttribute(ea)?.Version; - var copyright = GetAttribute(ea)?.Copyright; - - outWriter.WriteLine(ColorStyle.Header, $"{title} {version}"); - if (copyright is not null) - outWriter.WriteLine(ColorStyle.SubHeader, copyright); - outWriter.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); - outWriter.WriteLine(); - } - } - - private static TAttr? GetAttribute(Assembly assembly) - where TAttr : Attribute - { - return assembly?.GetCustomAttribute(); - } - - internal void WriteRunSettingsReport(XmlNode resultNode) - { - var settings = resultNode.SelectNodes("settings/setting"); - - if (settings is not null && settings.Count > 0) - { - OutWriter.WriteLine(ColorStyle.SectionHeader, "Run Settings"); - settings.ForEachNode(WriteSettingsNode); - OutWriter.WriteLine(); - } - } - - private void WriteSettingsNode(XmlNode node) - { - var items = node.SelectNodes("item"); - var name = node.GetAttribute("name"); - var val = node.GetAttribute("value") ?? string.Empty; - - if (items is not null) - { - OutWriter.WriteLabelLine($" {name}:", items.Count > 0 ? string.Empty : $" {val}"); - - items.ForEachNode((item) => - { - var key = item.GetAttribute("key"); - var value = item.GetAttribute("value"); - OutWriter.WriteLine(ColorStyle.Value, $" {key} -> {value}"); - }); - } - } - - public void WriteSummaryReport(XmlNode resultNode) - { - var overallResult = resultNode.GetAttribute("result") ?? "Unknown"; - if (overallResult == "Skipped") - overallResult = "Warning"; - - ColorStyle resultColor = overallResult == "Passed" - ? ColorStyle.Pass - : overallResult == "Failed" || overallResult == "Unknown" - ? ColorStyle.Failure - : overallResult == "Warning" - ? ColorStyle.Warning - : ColorStyle.Output; - - OutWriter.WriteLine(ColorStyle.SectionHeader, "Test Run Summary"); - OutWriter.WriteLabelLine(overallResult, resultColor); - - int cases = resultNode.GetAttribute("testcasecount", 0); - int passed = resultNode.GetAttribute("passed", 0); - int failed = resultNode.GetAttribute("failed", 0); - int warnings = resultNode.GetAttribute("warnings", 0); - int inconclusive = resultNode.GetAttribute("inconclusive", 0); - int skipped = resultNode.GetAttribute("skipped", 0); - - WriteSummaryCount(" Test Cases: ", cases); - WriteSummaryCount(", Passed: ", passed); - WriteSummaryCount(", Failed: ", failed, ColorStyle.Failure); - WriteSummaryCount(", Warnings: ", warnings, ColorStyle.Warning); - WriteSummaryCount(", Inconclusive: ", inconclusive); - WriteSummaryCount(", Skipped: ", skipped); - OutWriter.WriteLine(); - - var duration = resultNode.GetAttribute("duration", 0.0); - var startTime = resultNode.GetAttribute("start-time", DateTime.MinValue); - var endTime = resultNode.GetAttribute("end-time", DateTime.MaxValue); - - OutWriter.WriteLabelLine(" Start time: ", startTime.ToString("u")); - OutWriter.WriteLabelLine(" End time: ", endTime.ToString("u")); - OutWriter.WriteLabelLine(" Duration: ", string.Format(NumberFormatInfo.InvariantInfo, "{0:0.000} seconds", duration)); - OutWriter.WriteLine(); - } - - public void WriteErrorsFailuresAndWarningsReport(XmlNode resultNode) - { - ReportIndex = 0; - OutWriter.WriteLine(ColorStyle.SectionHeader, "Errors, Failures and Warnings"); - OutWriter.WriteLine(); - - WriteErrorsFailuresAndWarnings(resultNode); - } - - private void WriteErrorsFailuresAndWarnings(XmlNode resultNode) - { - const string OLD_NUNIT_CHILD_HAD_ERRORS_MESSAGE = "One or more child tests had errors"; - const string OLD_NUNIT_CHILD_HAD_WARNINGS_MESSAGE = "One or more child tests had errors"; - - string resultState = resultNode.GetAttribute("result") ?? string.Empty; - - switch (resultNode.Name) - { - case "test-case": - if (resultState == "Failed" || resultState == "Warning") - DisplayResultItem(resultNode); - return; - - // Not present in this agent but retain for use with other agents - case "test-run": - resultNode.ForEachChildNode(WriteErrorsFailuresAndWarnings); - break; - - case "test-suite": - if (resultState == "Failed" || resultState == "Warning") - { - var suiteType = resultNode.GetAttribute("type"); - if (suiteType == "Theory") - { - // Report failure of the entire theory and then go on - // to list the individual cases that failed - DisplayResultItem(resultNode); - } - else - { - // Where did this happen? Default is in the current test. - var site = resultNode.GetAttribute("site"); - - // Correct a problem in some framework versions, whereby warnings and some failures - // are promulgated to the containing suite without setting the FailureSite. - if (site is null) - { - if (resultNode.SelectSingleNode("reason/message")?.InnerText == OLD_NUNIT_CHILD_HAD_WARNINGS_MESSAGE || - resultNode.SelectSingleNode("failure/message")?.InnerText == OLD_NUNIT_CHILD_HAD_ERRORS_MESSAGE) - { - site = "Child"; - } - else - site = "Test"; - } - - // Only report errors in the current test method, setup or teardown - if (site == "SetUp" || site == "TearDown" || site == "Test") - { - DisplayResultItem(resultNode); - } - - // Do not list individual "failed" tests after a one-time setup failure - if (site == "SetUp") - return; - } - } - - resultNode.ForEachChildNode(WriteErrorsFailuresAndWarnings); - - break; - } - } - - public void WriteNotRunReport(XmlNode resultNode) - { - ReportIndex = 0; - OutWriter.WriteLine(ColorStyle.SectionHeader, "Tests Not Run"); - OutWriter.WriteLine(); - WriteNotRunResults(resultNode); - } - - private void WriteNotRunResults(XmlNode resultNode) - { - switch (resultNode.Name) - { - case "test-case": - string? status = resultNode.GetAttribute("result"); - - if (status == "Skipped") - DisplayResultItem(resultNode); - - break; - - case "test-suite": - case "test-run": - resultNode.ForEachChildNode(WriteNotRunResults); - - break; - } - } - - private static readonly char[] EOL_CHARS = new char[] { '\r', '\n' }; - - private void DisplayResultItem(XmlNode resultNode) - { - string? resultState = resultNode.GetAttribute("result"); - string? fullName = resultNode.GetAttribute("fullname"); - string? message = (resultNode.SelectSingleNode("failure/message") ?? resultNode.SelectSingleNode("reason/message"))?.InnerText.Trim(EOL_CHARS); - - OutWriter.WriteLine(GetColorStyle(), - string.Format($"{++ReportIndex}) {resultState} : {fullName}")); - if (!string.IsNullOrEmpty(message)) - OutWriter.WriteLine(ColorStyle.Output, message); - var stackTrace = resultNode.SelectSingleNode("failure/stack-trace")?.InnerText; - if (!string.IsNullOrEmpty(stackTrace)) - OutWriter.WriteLine(stackTrace); - OutWriter.WriteLine(); - - ColorStyle GetColorStyle() - { - return resultState == "Failed" - ? ColorStyle.Failure - : resultState == "Warning" - ? ColorStyle.Warning - : ColorStyle.Output; - } - } - - private void WriteSummaryCount(string label, int count) - { - OutWriter.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture)); - } - - private void WriteSummaryCount(string label, int count, ColorStyle color) - { - OutWriter.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture), count > 0 ? color : ColorStyle.Value); - } - public static void WriteResultFile(XmlNode resultNode, string outputPath) { using (var stream = new FileStream(outputPath, FileMode.Create, FileAccess.Write)) diff --git a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs index 747f57290..e258ba1de 100644 --- a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs +++ b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs @@ -103,9 +103,9 @@ public void SummaryReportTest() { "Test Run Summary", " Overall result: Failed", - $" Test Count: {MockAssembly.Tests}, Pass: {MockAssembly.Passed}, Fail: 11, Warn: 1, Inconclusive: 1, Skip: 7", - " Failed Tests - Failures: 1, Errors: 7, Invalid: 3", - " Skipped Tests - Ignored: 4, Explicit: 3, Other: 0", + $" Test Count: {MockAssembly.Tests}, Pass: {MockAssembly.Passed}, Fail: {MockAssembly.Failed}, Warn: {MockAssembly.Warnings}, Inconclusive: {MockAssembly.Inconclusive}, Skip: {MockAssembly.Skipped}", + $" Failed Tests - Failures: {MockAssembly.Failed_Other}, Errors: {MockAssembly.Failed_Error}, Invalid: {MockAssembly.Failed_NotRunnable}", + $" Skipped Tests - Ignored: 4, Explicit: 3, Other: 0", " Start time: 2015-10-19 02:12:28Z", " End time: 2015-10-19 02:12:29Z", " Duration: 0.349 seconds", @@ -178,11 +178,11 @@ public void TestsNotRunTest() Assert.That(ReportLines, Is.EqualTo(expected)); } - [Test, Explicit("Displays failure behavior")] - public void WarningsOnlyDisplayOnce() - { - Assert.Warn("Just a warning"); - } + //[Test, Explicit("Displays failure behavior")] + //public void WarningsOnlyDisplayOnce() + //{ + // Assert.Warn("Just a warning"); + //} [Test] public void TestParameterSettingsWrittenCorrectly() diff --git a/src/NUnitCommon/nunit.common/ResultSummary.cs b/src/NUnitCommon/nunit.common/ResultSummary.cs index f49db6e8d..d8c5fba54 100644 --- a/src/NUnitCommon/nunit.common/ResultSummary.cs +++ b/src/NUnitCommon/nunit.common/ResultSummary.cs @@ -12,8 +12,8 @@ public class ResultSummary { public ResultSummary(XmlNode resultNode) { - if (resultNode.Name != "test-run") - throw new InvalidOperationException("Expected as top-level element but was <" + resultNode.Name + ">"); + if (resultNode.Name != "test-run" && resultNode.Name != "test-suite") + throw new InvalidOperationException("Expected or as top-level element but was <" + resultNode.Name + ">"); InitializeCounters(); @@ -216,10 +216,11 @@ private void Summarize(XmlNode node, bool failedInFixtureTearDown) InvalidAssemblies++; UnexpectedError = true; } - if ((type == "SetUpFixture" || type == "TestFixture") && status == "Failed" && label == "Error" && site == "TearDown") - { - failedInFixtureTearDown = true; - } + // TODO: This seems wrong and causes failures. Leaving it commented while awaiting feedback. + //if ((type == "SetUpFixture" || type == "TestFixture") && status == "Failed" && label == "Error" && site == "TearDown") + //{ + // failedInFixtureTearDown = true; + //} Summarize(node.ChildNodes, failedInFixtureTearDown); break; diff --git a/src/TestData/mock-assembly/MockAssembly.cs b/src/TestData/mock-assembly/MockAssembly.cs index 96c825f7d..4171b58aa 100644 --- a/src/TestData/mock-assembly/MockAssembly.cs +++ b/src/TestData/mock-assembly/MockAssembly.cs @@ -65,18 +65,18 @@ public class MockAssembly public const int ExplicitFixtures = 1; public const int SuitesRun = Suites - ExplicitFixtures; + public const int PassedButFailedInTearDown = FixtureWithDispose.Tests + + FixtureWithOneTimeTearDown.Tests + + TestSetUpFixture.SetUpFixture.TestsInNamespace; + public const int Passed = MockTestFixture.Passed + Singletons.OneTestCase.Tests + TestAssembly.MockTestFixture.Tests + FixtureWithTestCases.Tests + ParameterizedFixture.Tests + GenericFixtureConstants.Tests - + AccessesCurrentTestContextDuringDiscovery.Tests; - - public const int PassedInAttribute = Passed - + FixtureWithDispose.Tests - + FixtureWithOneTimeTearDown.Tests - + TestSetUpFixture.SetUpFixture.TestsInNamespace; + + AccessesCurrentTestContextDuringDiscovery.Tests + + PassedButFailedInTearDown; public const int Skipped_Ignored = MockTestFixture.Skipped_Ignored + IgnoredFixture.Tests; public const int Skipped_Explicit = MockTestFixture.Skipped_Explicit + ExplicitFixture.Tests; @@ -92,6 +92,22 @@ public class MockAssembly public const int Inconclusive = MockTestFixture.Inconclusive; public static readonly string AssemblyPath = AssemblyHelper.GetAssemblyPath(typeof(MockAssembly).Assembly); + + // Method run manually to verify that the counts are set up correctly + public static void DisplayCounts() + { + Console.WriteLine($"Test Count: {Tests}"); + Console.WriteLine($" Passed: {Passed}"); + Console.WriteLine($" Failed: {Failed}"); + Console.WriteLine($" Failures: {Failed_Other}"); + Console.WriteLine($" Errors: {Failed_Error}"); + Console.WriteLine($" Invalid: {Failed_NotRunnable}"); + Console.WriteLine($" Warnings: {Warnings}"); + Console.WriteLine($" Skipped: {Skipped}"); + Console.WriteLine($" Explicit: {Skipped_Explicit}"); + Console.WriteLine($" Ignored: {Skipped_Ignored}"); + Console.WriteLine($" Inconclusive: {Inconclusive}"); + } } [TestFixture(Description="Fake Test Fixture")] From dbf62c01e2abf944ac5992ad411fc391c401a941 Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Wed, 23 Apr 2025 09:37:44 -0700 Subject: [PATCH 09/10] Changes from code review --- .../NotRunnableFrameworkDriverTests.cs | 1 - .../Runners/TestAgentRunnerTests.cs | 1 - .../nunit.agent.core/AgentDirectRunner.cs | 1 + .../nunit.agent.core/Drivers/DriverService.cs | 1 + .../nunit.agent.core/NUnitAgent.cs | 1 + .../nunit.agent.core/Runners/DomainManager.cs | 1 + .../Remoting}/TcpChannelUtilsTests.cs | 2 +- .../nunit.common.tests/PathUtilTests.cs | 2 +- .../TextDisplay/ResultReporterTests.cs | 17 +-- .../nunit.common/AgentExitCodes.cs | 2 +- ...ils.ObservableServerChannelSinkProvider.cs | 2 +- .../Transports/Remoting}/TcpChannelUtils.cs | 3 +- src/NUnitCommon/nunit.common/DotNet.cs | 2 +- .../nunit.common/FrameworkIdentifers.cs | 2 +- .../Modernization/StringExtensions.cs | 2 +- src/NUnitCommon/nunit.common/PathUtils.cs | 2 +- src/NUnitCommon/nunit.common/ResultSummary.cs | 2 +- .../nunit.common/RuntimeInformation.cs | 110 ------------------ .../nunit.common/TestPackageExtensions.cs | 1 + .../{ => TextDisplay}/ClientTestResult.cs | 7 +- .../TextDisplay/ResultReporter.cs | 3 +- .../ExtensionSelectorTests.cs | 2 +- .../nunit.extensibility/AddinsFileEntry.cs | 1 + .../nunit4-console/ConsoleOptions.cs | 1 - .../nunit4-console/ConsoleRunner.cs | 2 +- .../nunit4-console/Options/Options.cs | 2 - .../nunit4-console/TestEventHandler.cs | 4 +- .../nunit4-netcore-console/Program.cs | 28 +---- .../Services}/ProcessUtilsTests.cs | 3 +- .../TestEngineResultTests.cs | 1 - src/NUnitEngine/nunit.engine/Runtime.cs | 1 + .../nunit.engine/Services/AgentProcess.cs | 1 + .../nunit.engine/Services}/ProcessUtils.cs | 2 +- .../Services/RuntimeFrameworkService.cs | 1 + .../RuntimeLocators/NetCoreRuntimeLocator.cs | 2 +- .../nunit.engine/Services/TestAgency.cs | 1 + 36 files changed, 39 insertions(+), 178 deletions(-) rename src/NUnitCommon/nunit.common.tests/{ => Communication/Transports/Remoting}/TcpChannelUtilsTests.cs (98%) rename src/NUnitCommon/nunit.common/{ => Communitcation/Transports/Remoting}/TcpChannelUtils.ObservableServerChannelSinkProvider.cs (98%) rename src/NUnitCommon/nunit.common/{ => Communitcation/Transports/Remoting}/TcpChannelUtils.cs (99%) delete mode 100644 src/NUnitCommon/nunit.common/RuntimeInformation.cs rename src/NUnitCommon/nunit.common/{ => TextDisplay}/ClientTestResult.cs (96%) rename src/{NUnitCommon/nunit.common.tests => NUnitEngine/nunit.engine.tests/Services}/ProcessUtilsTests.cs (98%) rename src/{NUnitCommon/nunit.common => NUnitEngine/nunit.engine/Services}/ProcessUtils.cs (99%) diff --git a/src/NUnitCommon/nunit.agent.core.tests/Drivers/NotRunnableFrameworkDriverTests.cs b/src/NUnitCommon/nunit.agent.core.tests/Drivers/NotRunnableFrameworkDriverTests.cs index d876291d2..5b9fd54c8 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/Drivers/NotRunnableFrameworkDriverTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/Drivers/NotRunnableFrameworkDriverTests.cs @@ -6,7 +6,6 @@ using NUnit.Framework; using NUnit.Framework.Internal; using NUnit.Engine.Extensibility; -using NUnit.Engine.Internal; using System; namespace NUnit.Engine.Drivers diff --git a/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs b/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs index c886af4db..af212f49b 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using System.Xml; -using NUnit.Engine.Internal; using NUnit.Framework; using NUnit.TestData; using NUnit.TestData.Assemblies; diff --git a/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs b/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs index 560b8f10f..6f8795068 100644 --- a/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs +++ b/src/NUnitCommon/nunit.agent.core/AgentDirectRunner.cs @@ -4,6 +4,7 @@ using System.IO; using System.Xml; using NUnit.TextDisplay; +using NUnit.Common; using NUnit.Engine; using NUnit.Engine.Runners; diff --git a/src/NUnitCommon/nunit.agent.core/Drivers/DriverService.cs b/src/NUnitCommon/nunit.agent.core/Drivers/DriverService.cs index db6bb3116..0099c5bb4 100644 --- a/src/NUnitCommon/nunit.agent.core/Drivers/DriverService.cs +++ b/src/NUnitCommon/nunit.agent.core/Drivers/DriverService.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; +using NUnit.Common; using NUnit.Engine.Extensibility; using TestCentric.Metadata; diff --git a/src/NUnitCommon/nunit.agent.core/NUnitAgent.cs b/src/NUnitCommon/nunit.agent.core/NUnitAgent.cs index 236b8058a..62f13c083 100644 --- a/src/NUnitCommon/nunit.agent.core/NUnitAgent.cs +++ b/src/NUnitCommon/nunit.agent.core/NUnitAgent.cs @@ -5,6 +5,7 @@ using System.IO; using System.Security; using System.Reflection; +using NUnit.Common; using NUnit.Engine.Agents; #if NETFRAMEWORK diff --git a/src/NUnitCommon/nunit.agent.core/Runners/DomainManager.cs b/src/NUnitCommon/nunit.agent.core/Runners/DomainManager.cs index 6cc9e8b11..ce7dd0bdb 100644 --- a/src/NUnitCommon/nunit.agent.core/Runners/DomainManager.cs +++ b/src/NUnitCommon/nunit.agent.core/Runners/DomainManager.cs @@ -11,6 +11,7 @@ using System.Security.Policy; using System.Security.Principal; using System.Linq; +using NUnit.Common; namespace NUnit.Engine.Runners { diff --git a/src/NUnitCommon/nunit.common.tests/TcpChannelUtilsTests.cs b/src/NUnitCommon/nunit.common.tests/Communication/Transports/Remoting/TcpChannelUtilsTests.cs similarity index 98% rename from src/NUnitCommon/nunit.common.tests/TcpChannelUtilsTests.cs rename to src/NUnitCommon/nunit.common.tests/Communication/Transports/Remoting/TcpChannelUtilsTests.cs index 0f0bb16c7..c07b59d0c 100644 --- a/src/NUnitCommon/nunit.common.tests/TcpChannelUtilsTests.cs +++ b/src/NUnitCommon/nunit.common.tests/Communication/Transports/Remoting/TcpChannelUtilsTests.cs @@ -8,7 +8,7 @@ using NUnit.Framework; using NUnit.Framework.Constraints; -namespace NUnit.Engine.Internal +namespace NUnit.Engine.Communication.Transports.Remoting { [TestFixture] [Parallelizable(ParallelScope.None)] // GetTcpChannel affects the whole AppDomain diff --git a/src/NUnitCommon/nunit.common.tests/PathUtilTests.cs b/src/NUnitCommon/nunit.common.tests/PathUtilTests.cs index 5389fe9fb..11b6821c2 100644 --- a/src/NUnitCommon/nunit.common.tests/PathUtilTests.cs +++ b/src/NUnitCommon/nunit.common.tests/PathUtilTests.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; using NUnit.Framework; -namespace NUnit.Engine.Internal +namespace NUnit.Common { [TestFixture] public class PathUtilsTests diff --git a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs index e258ba1de..b0dfb83b6 100644 --- a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs +++ b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs @@ -5,6 +5,7 @@ using System.IO; using System.Text; using System.Xml; +using NUnit.Common; using NUnit.Engine; using NUnit.Framework; using NUnit.Framework.Api; @@ -19,13 +20,11 @@ public class ResultReporterTests private StringBuilder _reportBuilder; private ExtendedTextWrapper _writer; - private string ReportOutput => _reportBuilder.ToString(); - private List ReportLines { get { - var rdr = new StringReader(ReportOutput); + var rdr = new StringReader(_reportBuilder.ToString()); string? line; var lines = new List(); @@ -86,9 +85,10 @@ public void ReportSequenceTest() int last = -1; + string reportOutput = _reportBuilder.ToString(); foreach (string title in reportSequence) { - var index = ReportOutput.IndexOf(title); + var index = reportOutput.IndexOf(title); Assert.That(index > 0, "Report not found: " + title); Assert.That(index > last, "Report out of sequence: " + title); last = index; @@ -141,8 +141,9 @@ public void ErrorsFailuresAndWarningsReportTest() ResultReporter.WriteErrorsFailuresAndWarningsReport(_result, _writer); + string reportOutput = _reportBuilder.ToString(); foreach (var item in expected) - Assert.That(ReportOutput.Contains(item)); + Assert.That(reportOutput.Contains(item)); } [Test] @@ -178,12 +179,6 @@ public void TestsNotRunTest() Assert.That(ReportLines, Is.EqualTo(expected)); } - //[Test, Explicit("Displays failure behavior")] - //public void WarningsOnlyDisplayOnce() - //{ - // Assert.Warn("Just a warning"); - //} - [Test] public void TestParameterSettingsWrittenCorrectly() { diff --git a/src/NUnitCommon/nunit.common/AgentExitCodes.cs b/src/NUnitCommon/nunit.common/AgentExitCodes.cs index 7ae73011f..17b381be9 100644 --- a/src/NUnitCommon/nunit.common/AgentExitCodes.cs +++ b/src/NUnitCommon/nunit.common/AgentExitCodes.cs @@ -1,6 +1,6 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt -namespace NUnit +namespace NUnit.Common { public static class AgentExitCodes { diff --git a/src/NUnitCommon/nunit.common/TcpChannelUtils.ObservableServerChannelSinkProvider.cs b/src/NUnitCommon/nunit.common/Communitcation/Transports/Remoting/TcpChannelUtils.ObservableServerChannelSinkProvider.cs similarity index 98% rename from src/NUnitCommon/nunit.common/TcpChannelUtils.ObservableServerChannelSinkProvider.cs rename to src/NUnitCommon/nunit.common/Communitcation/Transports/Remoting/TcpChannelUtils.ObservableServerChannelSinkProvider.cs index e4f44a602..a0eb0eae6 100644 --- a/src/NUnitCommon/nunit.common/TcpChannelUtils.ObservableServerChannelSinkProvider.cs +++ b/src/NUnitCommon/nunit.common/Communitcation/Transports/Remoting/TcpChannelUtils.ObservableServerChannelSinkProvider.cs @@ -7,7 +7,7 @@ using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Messaging; -namespace NUnit.Engine +namespace NUnit.Engine.Communication.Transports.Remoting { partial class TcpChannelUtils { diff --git a/src/NUnitCommon/nunit.common/TcpChannelUtils.cs b/src/NUnitCommon/nunit.common/Communitcation/Transports/Remoting/TcpChannelUtils.cs similarity index 99% rename from src/NUnitCommon/nunit.common/TcpChannelUtils.cs rename to src/NUnitCommon/nunit.common/Communitcation/Transports/Remoting/TcpChannelUtils.cs index 5a49ec6c4..7d55802a9 100644 --- a/src/NUnitCommon/nunit.common/TcpChannelUtils.cs +++ b/src/NUnitCommon/nunit.common/Communitcation/Transports/Remoting/TcpChannelUtils.cs @@ -3,13 +3,12 @@ #if NETFRAMEWORK using System; using System.Collections.Generic; -using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Serialization.Formatters; using System.Threading; -namespace NUnit.Engine +namespace NUnit.Engine.Communication.Transports.Remoting { /// /// A collection of utility methods used to create, retrieve diff --git a/src/NUnitCommon/nunit.common/DotNet.cs b/src/NUnitCommon/nunit.common/DotNet.cs index 8373a446c..f5a0e50a0 100644 --- a/src/NUnitCommon/nunit.common/DotNet.cs +++ b/src/NUnitCommon/nunit.common/DotNet.cs @@ -5,7 +5,7 @@ using System.IO; using System.Runtime.InteropServices; -namespace NUnit.Engine +namespace NUnit.Common { public static class DotNet { diff --git a/src/NUnitCommon/nunit.common/FrameworkIdentifers.cs b/src/NUnitCommon/nunit.common/FrameworkIdentifers.cs index e8b520a9b..0dc6b4789 100644 --- a/src/NUnitCommon/nunit.common/FrameworkIdentifers.cs +++ b/src/NUnitCommon/nunit.common/FrameworkIdentifers.cs @@ -1,6 +1,6 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt -namespace NUnit +namespace NUnit.Common { public static class FrameworkIdentifiers { diff --git a/src/NUnitCommon/nunit.common/Modernization/StringExtensions.cs b/src/NUnitCommon/nunit.common/Modernization/StringExtensions.cs index dc6cd752f..739b7b00f 100644 --- a/src/NUnitCommon/nunit.common/Modernization/StringExtensions.cs +++ b/src/NUnitCommon/nunit.common/Modernization/StringExtensions.cs @@ -2,7 +2,7 @@ #if !NETSTANDARD2_1 && !NETCOREAPP2_0_OR_GREATER -namespace NUnit.Common +namespace NUnit { public static class StringExtensions { diff --git a/src/NUnitCommon/nunit.common/PathUtils.cs b/src/NUnitCommon/nunit.common/PathUtils.cs index c9daaef08..3b22c5084 100644 --- a/src/NUnitCommon/nunit.common/PathUtils.cs +++ b/src/NUnitCommon/nunit.common/PathUtils.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; -namespace NUnit +namespace NUnit.Common { /// /// Static methods for manipulating project paths, including both directories diff --git a/src/NUnitCommon/nunit.common/ResultSummary.cs b/src/NUnitCommon/nunit.common/ResultSummary.cs index d8c5fba54..7996c1757 100644 --- a/src/NUnitCommon/nunit.common/ResultSummary.cs +++ b/src/NUnitCommon/nunit.common/ResultSummary.cs @@ -3,7 +3,7 @@ using System; using System.Xml; -namespace NUnit +namespace NUnit.Common { /// /// Summary description for ResultSummary. diff --git a/src/NUnitCommon/nunit.common/RuntimeInformation.cs b/src/NUnitCommon/nunit.common/RuntimeInformation.cs deleted file mode 100644 index b71ae296d..000000000 --- a/src/NUnitCommon/nunit.common/RuntimeInformation.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt - -#if NETFRAMEWORK -using System; -using System.IO; -using Microsoft.Win32; - -namespace NUnit.Engine.Internal.Backports -{ - /// - /// Partially replaces System.Runtime.InteropServices.RuntimeInformation - /// under the .NET Framework. Only FrameworkDescription is implemented. - /// - public static class RuntimeInformation - { - static RuntimeInformation() - { - bool isMono = Type.GetType("Mono.Runtime", false) is not null; - - Version version = new Version(Environment.Version.Major, Environment.Version.Minor); - if (isMono) - { - FrameworkName = "Mono"; - - switch (version.Major) - { - case 1: - version = new Version(1, 0); - break; - case 2: - version = new Version(3, 5); - break; - } - } - else /* We must be on Windows, so registry is available */ - { - FrameworkName = ".NET Framework"; - - RegistryKey? key = null; - switch (version.Major) - { - case 2: - key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework"); - if (key is not null) - { - string? installRoot = key.GetValue("InstallRoot") as string; - if (installRoot is not null) - { - if (Directory.Exists(System.IO.Path.Combine(installRoot, "v3.5"))) - { - version = new Version(3, 5); - } - else if (Directory.Exists(System.IO.Path.Combine(installRoot, "v3.0"))) - { - version = new Version(3, 0); - } - } - } - break; - case 4: - key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"); - if (key is not null) - { - version = new Version(4, 5); - int release = (int)key.GetValue("Release", 0); - foreach (var entry in ReleaseTable) - if (release >= entry.Release) - version = entry.Version; - } - break; - } - - key?.Dispose(); - } - - FrameworkVersion = version; - } - - public static string FrameworkName { get; } - public static Version FrameworkVersion { get; } - public static string FrameworkDescription => $"{FrameworkName} {FrameworkVersion}"; - - private struct MinimumRelease - { - public readonly int Release; - public readonly Version Version; - - public MinimumRelease(int release, Version version) - { - Release = release; - Version = version; - } - } - - private static readonly MinimumRelease[] ReleaseTable = new MinimumRelease[] - { - new MinimumRelease(378389, new Version(4, 5)), - new MinimumRelease(378675, new Version(4, 5, 1)), - new MinimumRelease(379893, new Version(4, 5, 2)), - new MinimumRelease(393295, new Version(4, 6)), - new MinimumRelease(394254, new Version(4, 6, 1)), - new MinimumRelease(394802, new Version(4, 6, 2)), - new MinimumRelease(460798, new Version(4, 7)), - new MinimumRelease(461308, new Version(4, 7, 1)), - new MinimumRelease(461808, new Version(4, 7, 2)), - new MinimumRelease(528040, new Version(4, 8)) - }; - } -} -#endif diff --git a/src/NUnitCommon/nunit.common/TestPackageExtensions.cs b/src/NUnitCommon/nunit.common/TestPackageExtensions.cs index 895e1c36b..2649fd9a9 100644 --- a/src/NUnitCommon/nunit.common/TestPackageExtensions.cs +++ b/src/NUnitCommon/nunit.common/TestPackageExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using NUnit.Common; namespace NUnit.Engine { diff --git a/src/NUnitCommon/nunit.common/ClientTestResult.cs b/src/NUnitCommon/nunit.common/TextDisplay/ClientTestResult.cs similarity index 96% rename from src/NUnitCommon/nunit.common/ClientTestResult.cs rename to src/NUnitCommon/nunit.common/TextDisplay/ClientTestResult.cs index 7aca978d2..566501993 100644 --- a/src/NUnitCommon/nunit.common/ClientTestResult.cs +++ b/src/NUnitCommon/nunit.common/TextDisplay/ClientTestResult.cs @@ -1,12 +1,9 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt -using System; using System.Collections.Generic; -using System.Text; using System.Xml; -using NUnit.TextDisplay; -namespace NUnit +namespace NUnit.TextDisplay { /// /// ConsoleTestResult represents the result of one test being @@ -73,7 +70,7 @@ public List Assertions XmlNodeList? assertions = _resultNode.SelectNodes("assertions/assertion"); if (assertions is not null) foreach (XmlNode assertion in assertions) - Assertions.Add(new ClientTestResult.AssertionResult(assertion)); + Assertions.Add(new AssertionResult(assertion)); } return _assertions; diff --git a/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs index a0994dcb0..d2f9afab9 100644 --- a/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs +++ b/src/NUnitCommon/nunit.common/TextDisplay/ResultReporter.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.Reflection; using System.Xml; +using NUnit.Common; namespace NUnit.TextDisplay { @@ -17,8 +18,6 @@ public static void WriteHeader(ExtendedTextWriter writer) var header = $"{versionBlock.ProductName} {versionBlock.ProductVersion}"; - var configurationAttributes = entryAssembly.GetCustomAttribute(); - writer.WriteLine(ColorStyle.Header, header); writer.WriteLine(ColorStyle.SubHeader, versionBlock.LegalCopyright ?? "No Copyright statement found"); writer.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); diff --git a/src/NUnitCommon/nunit.extensibility.tests/ExtensionSelectorTests.cs b/src/NUnitCommon/nunit.extensibility.tests/ExtensionSelectorTests.cs index 328a9edd4..9b95d5b7a 100644 --- a/src/NUnitCommon/nunit.extensibility.tests/ExtensionSelectorTests.cs +++ b/src/NUnitCommon/nunit.extensibility.tests/ExtensionSelectorTests.cs @@ -4,7 +4,7 @@ using System; using System.Runtime.Versioning; using NSubstitute; -using NUnit.Extensibility; +using NUnit.Common; using NUnit.Framework; namespace NUnit.Extensibility diff --git a/src/NUnitCommon/nunit.extensibility/AddinsFileEntry.cs b/src/NUnitCommon/nunit.extensibility/AddinsFileEntry.cs index 40807a650..09b17b90b 100644 --- a/src/NUnitCommon/nunit.extensibility/AddinsFileEntry.cs +++ b/src/NUnitCommon/nunit.extensibility/AddinsFileEntry.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.IO; +using NUnit.Common; namespace NUnit.Extensibility { diff --git a/src/NUnitConsole/nunit4-console/ConsoleOptions.cs b/src/NUnitConsole/nunit4-console/ConsoleOptions.cs index e37fc9f3f..b7dddd7f1 100644 --- a/src/NUnitConsole/nunit4-console/ConsoleOptions.cs +++ b/src/NUnitConsole/nunit4-console/ConsoleOptions.cs @@ -6,7 +6,6 @@ using System.IO; using System.Text; using System.Text.RegularExpressions; -using NUnit.Common; using NUnit.ConsoleRunner.Options; namespace NUnit.ConsoleRunner diff --git a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs index 337ccc57d..0fdcad583 100644 --- a/src/NUnitConsole/nunit4-console/ConsoleRunner.cs +++ b/src/NUnitConsole/nunit4-console/ConsoleRunner.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; using System.IO; using System.Xml; +using NUnit.Common; using NUnit.ConsoleRunner.Utilities; using NUnit.ConsoleRunner.Options; using NUnit.Engine; using NUnit.Engine.Extensibility; -using NUnit.Extensibility; using NUnit.TextDisplay; using System.Runtime.InteropServices; using System.Text; diff --git a/src/NUnitConsole/nunit4-console/Options/Options.cs b/src/NUnitConsole/nunit4-console/Options/Options.cs index 7675fbcff..5bd8efc84 100644 --- a/src/NUnitConsole/nunit4-console/Options/Options.cs +++ b/src/NUnitConsole/nunit4-console/Options/Options.cs @@ -182,8 +182,6 @@ using MessageLocalizerConverter = System.Converter; #endif -using NUnit.Common; - namespace NUnit.ConsoleRunner.Options { internal static class StringCoda diff --git a/src/NUnitConsole/nunit4-console/TestEventHandler.cs b/src/NUnitConsole/nunit4-console/TestEventHandler.cs index 862d446b6..2bd298782 100644 --- a/src/NUnitConsole/nunit4-console/TestEventHandler.cs +++ b/src/NUnitConsole/nunit4-console/TestEventHandler.cs @@ -1,10 +1,10 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System.Xml; -using NUnit.Common; using NUnit.Engine; +using NUnit.TextDisplay; -namespace NUnit.TextDisplay +namespace NUnit.ConsoleRunner { /// /// TestEventHandler processes events from the running diff --git a/src/NUnitConsole/nunit4-netcore-console/Program.cs b/src/NUnitConsole/nunit4-netcore-console/Program.cs index 627d5480b..3612514d3 100644 --- a/src/NUnitConsole/nunit4-netcore-console/Program.cs +++ b/src/NUnitConsole/nunit4-netcore-console/Program.cs @@ -45,7 +45,7 @@ public static int Main(string[] args) } catch (OptionException ex) { - WriteHeader(); + ResultReporter.WriteHeader(OutWriter); WriteErrorMessage(string.Format(ex.Message, ex.OptionName)); return ConsoleRunner.INVALID_ARG; } @@ -58,7 +58,7 @@ public static int Main(string[] args) } catch (Exception error) { - WriteHeader(); + ResultReporter.WriteHeader(OutWriter); WriteErrorMessage(string.Format("Unsupported Encoding, {0}", error.Message)); return ConsoleRunner.INVALID_ARG; } @@ -67,7 +67,7 @@ public static int Main(string[] args) try { if (Options.ShowVersion || !Options.NoHeader) - WriteHeader(); + ResultReporter.WriteHeader(OutWriter); if (Options.ShowHelp || args.Length == 0) { @@ -149,28 +149,6 @@ public static int Main(string[] args) } } - private static void WriteHeader() - { - Assembly entryAssembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); - var versionBlock = FileVersionInfo.GetVersionInfo(entryAssembly.ManifestModule.FullyQualifiedName); - - var header = $"{versionBlock.ProductName} {versionBlock.ProductVersion}"; - - var configurationAttributes = entryAssembly.GetCustomAttributes().ToArray(); - - if (configurationAttributes.Length > 0) - { - string configuration = ((AssemblyConfigurationAttribute)configurationAttributes[0]).Configuration; - if (!string.IsNullOrEmpty(configuration)) - header += $" ({configuration})"; - } - - OutWriter.WriteLine(ColorStyle.Header, header); - OutWriter.WriteLine(ColorStyle.SubHeader, versionBlock.LegalCopyright ?? "No Copyright statement found"); - OutWriter.WriteLine(ColorStyle.SubHeader, DateTime.Now.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern)); - OutWriter.WriteLine(); - } - private static void WriteHelpText() { OutWriter.WriteLine(); diff --git a/src/NUnitCommon/nunit.common.tests/ProcessUtilsTests.cs b/src/NUnitEngine/nunit.engine.tests/Services/ProcessUtilsTests.cs similarity index 98% rename from src/NUnitCommon/nunit.common.tests/ProcessUtilsTests.cs rename to src/NUnitEngine/nunit.engine.tests/Services/ProcessUtilsTests.cs index fefb9c53c..a7a061f27 100644 --- a/src/NUnitCommon/nunit.common.tests/ProcessUtilsTests.cs +++ b/src/NUnitEngine/nunit.engine.tests/Services/ProcessUtilsTests.cs @@ -21,11 +21,10 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // *********************************************************************** -using NUnit.Engine.Internal; using NUnit.Framework; using System.Text; -namespace NUnit.Engine.Tests.Internal +namespace NUnit.Engine.Services { public static class ProcessUtilsTests { diff --git a/src/NUnitEngine/nunit.engine.tests/TestEngineResultTests.cs b/src/NUnitEngine/nunit.engine.tests/TestEngineResultTests.cs index f0a57a1fe..0b38accf7 100644 --- a/src/NUnitEngine/nunit.engine.tests/TestEngineResultTests.cs +++ b/src/NUnitEngine/nunit.engine.tests/TestEngineResultTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System.Xml; -using NUnit.Engine.Internal; using NUnit.Framework; namespace NUnit.Engine diff --git a/src/NUnitEngine/nunit.engine/Runtime.cs b/src/NUnitEngine/nunit.engine/Runtime.cs index bf60da154..4b0763ad3 100644 --- a/src/NUnitEngine/nunit.engine/Runtime.cs +++ b/src/NUnitEngine/nunit.engine/Runtime.cs @@ -1,6 +1,7 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt using System; +using NUnit.Common; namespace NUnit.Engine { diff --git a/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs b/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs index e67ab994d..3ff7ce695 100644 --- a/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs +++ b/src/NUnitEngine/nunit.engine/Services/AgentProcess.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Text; +using NUnit.Common; namespace NUnit.Engine.Services { diff --git a/src/NUnitCommon/nunit.common/ProcessUtils.cs b/src/NUnitEngine/nunit.engine/Services/ProcessUtils.cs similarity index 99% rename from src/NUnitCommon/nunit.common/ProcessUtils.cs rename to src/NUnitEngine/nunit.engine/Services/ProcessUtils.cs index 0bbfb8680..56e3baac4 100644 --- a/src/NUnitCommon/nunit.common/ProcessUtils.cs +++ b/src/NUnitEngine/nunit.engine/Services/ProcessUtils.cs @@ -23,7 +23,7 @@ using System.Text; -namespace NUnit.Engine +namespace NUnit.Engine.Services { public static class ProcessUtils { diff --git a/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs b/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs index e039a4e04..1fc800a20 100644 --- a/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs +++ b/src/NUnitEngine/nunit.engine/Services/RuntimeFrameworkService.cs @@ -8,6 +8,7 @@ using System.Reflection; using System.Runtime.Versioning; using Microsoft.Win32; +using NUnit.Common; using NUnit.Engine.Services.RuntimeLocators; using TestCentric.Metadata; diff --git a/src/NUnitEngine/nunit.engine/Services/RuntimeLocators/NetCoreRuntimeLocator.cs b/src/NUnitEngine/nunit.engine/Services/RuntimeLocators/NetCoreRuntimeLocator.cs index 99034fa65..1348a02d7 100644 --- a/src/NUnitEngine/nunit.engine/Services/RuntimeLocators/NetCoreRuntimeLocator.cs +++ b/src/NUnitEngine/nunit.engine/Services/RuntimeLocators/NetCoreRuntimeLocator.cs @@ -1,11 +1,11 @@ // Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt #if NETFRAMEWORK -using Microsoft.Win32; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using NUnit.Common; namespace NUnit.Engine.Services.RuntimeLocators { diff --git a/src/NUnitEngine/nunit.engine/Services/TestAgency.cs b/src/NUnitEngine/nunit.engine/Services/TestAgency.cs index 3be84ab29..0636a6266 100644 --- a/src/NUnitEngine/nunit.engine/Services/TestAgency.cs +++ b/src/NUnitEngine/nunit.engine/Services/TestAgency.cs @@ -4,6 +4,7 @@ using System; using System.Threading; using System.Diagnostics; +using NUnit.Common; using NUnit.Engine.Communication.Transports.Remoting; using NUnit.Engine.Communication.Transports.Tcp; using System.Diagnostics.CodeAnalysis; From 43bad97c7bc5c877b0084d08e3b56591a9af55fa Mon Sep 17 00:00:00 2001 From: Charlie Poole Date: Thu, 24 Apr 2025 17:28:46 -0700 Subject: [PATCH 10/10] Take 2: restore showing passed tests that fail in teardown as errors --- .../Drivers/NUnitFrameworkDriverTests.cs | 10 ++-- .../Runners/TestAgentRunnerTests.cs | 4 +- .../TextDisplay/ResultReporterTests.cs | 4 +- src/NUnitCommon/nunit.common/ResultSummary.cs | 9 ++- src/TestData/mock-assembly/MockAssembly.cs | 59 +++++++++---------- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs b/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs index c7c041fac..c62040591 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/Drivers/NUnitFrameworkDriverTests.cs @@ -105,12 +105,12 @@ public void RunTestsAction_AfterLoad_ReturnsRunnableSuite() Assert.That(result.Name, Is.EqualTo("test-suite")); Assert.That(result.GetAttribute("type"), Is.EqualTo("Assembly")); Assert.That(result.GetAttribute("runstate"), Is.EqualTo("Runnable")); - Assert.That(result.GetAttribute("testcasecount"), Is.EqualTo(MockAssembly.Tests.ToString())); + Assert.That(result.GetAttribute("testcasecount", 0), Is.EqualTo(MockAssembly.Tests)); Assert.That(result.GetAttribute("result"), Is.EqualTo("Failed")); - Assert.That(result.GetAttribute("passed"), Is.EqualTo(MockAssembly.Passed.ToString())); - Assert.That(result.GetAttribute("failed"), Is.EqualTo(MockAssembly.Failed.ToString())); - Assert.That(result.GetAttribute("skipped"), Is.EqualTo(MockAssembly.Skipped.ToString())); - Assert.That(result.GetAttribute("inconclusive"), Is.EqualTo(MockAssembly.Inconclusive.ToString())); + Assert.That(result.GetAttribute("passed", 0), Is.EqualTo(MockAssembly.Passed_Raw)); + Assert.That(result.GetAttribute("failed", 0), Is.EqualTo(MockAssembly.Failed_Raw)); + Assert.That(result.GetAttribute("skipped", 0), Is.EqualTo(MockAssembly.Skipped)); + Assert.That(result.GetAttribute("inconclusive", 0), Is.EqualTo(MockAssembly.Inconclusive)); Assert.That(result.SelectNodes("test-suite")?.Count, Is.GreaterThan(0), "Explore result should have child tests"); } diff --git a/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs b/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs index af212f49b..0869b310a 100644 --- a/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs +++ b/src/NUnitCommon/nunit.agent.core.tests/Runners/TestAgentRunnerTests.cs @@ -113,8 +113,8 @@ private static void CheckRunResult(TestEngineResult result) private static void CheckRunResult(XmlNode result) { CheckBasicResult(result); - Assert.That(result.GetAttribute("passed", 0), Is.EqualTo(MockAssembly.Passed)); - Assert.That(result.GetAttribute("failed", 0), Is.EqualTo(MockAssembly.Failed)); + Assert.That(result.GetAttribute("passed", 0), Is.EqualTo(MockAssembly.Passed_Raw)); + Assert.That(result.GetAttribute("failed", 0), Is.EqualTo(MockAssembly.Failed_Raw)); Assert.That(result.GetAttribute("skipped", 0), Is.EqualTo(MockAssembly.Skipped)); Assert.That(result.GetAttribute("inconclusive", 0), Is.EqualTo(MockAssembly.Inconclusive)); } diff --git a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs index b0dfb83b6..78e4632c9 100644 --- a/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs +++ b/src/NUnitCommon/nunit.common.tests/TextDisplay/ResultReporterTests.cs @@ -104,8 +104,8 @@ public void SummaryReportTest() "Test Run Summary", " Overall result: Failed", $" Test Count: {MockAssembly.Tests}, Pass: {MockAssembly.Passed}, Fail: {MockAssembly.Failed}, Warn: {MockAssembly.Warnings}, Inconclusive: {MockAssembly.Inconclusive}, Skip: {MockAssembly.Skipped}", - $" Failed Tests - Failures: {MockAssembly.Failed_Other}, Errors: {MockAssembly.Failed_Error}, Invalid: {MockAssembly.Failed_NotRunnable}", - $" Skipped Tests - Ignored: 4, Explicit: 3, Other: 0", + $" Failed Tests - Failures: {MockAssembly.Failures}, Errors: {MockAssembly.Errors}, Invalid: {MockAssembly.NotRunnable}", + $" Skipped Tests - Ignored: {MockAssembly.Ignored}, Explicit: {MockAssembly.Explicit}, Other: 0", " Start time: 2015-10-19 02:12:28Z", " End time: 2015-10-19 02:12:29Z", " Duration: 0.349 seconds", diff --git a/src/NUnitCommon/nunit.common/ResultSummary.cs b/src/NUnitCommon/nunit.common/ResultSummary.cs index 7996c1757..4076f090a 100644 --- a/src/NUnitCommon/nunit.common/ResultSummary.cs +++ b/src/NUnitCommon/nunit.common/ResultSummary.cs @@ -216,11 +216,10 @@ private void Summarize(XmlNode node, bool failedInFixtureTearDown) InvalidAssemblies++; UnexpectedError = true; } - // TODO: This seems wrong and causes failures. Leaving it commented while awaiting feedback. - //if ((type == "SetUpFixture" || type == "TestFixture") && status == "Failed" && label == "Error" && site == "TearDown") - //{ - // failedInFixtureTearDown = true; - //} + if ((type == "SetUpFixture" || type == "TestFixture") && status == "Failed" && label == "Error" && site == "TearDown") + { + failedInFixtureTearDown = true; + } Summarize(node.ChildNodes, failedInFixtureTearDown); break; diff --git a/src/TestData/mock-assembly/MockAssembly.cs b/src/TestData/mock-assembly/MockAssembly.cs index 4171b58aa..7b0a8ed6d 100644 --- a/src/TestData/mock-assembly/MockAssembly.cs +++ b/src/TestData/mock-assembly/MockAssembly.cs @@ -18,12 +18,6 @@ namespace Assemblies /// public class MockAssembly { - /// - /// Constant definitions used by tests that both reference the - /// mock-assembly and load it in order to verify counts. - /// - public const string FileName = "mock.nunit.assembly.exe"; - public const int Classes = 9; public const int NamespaceSuites = 6; // assembly, NUnit, Tests, Assemblies, Singletons, TestAssembly @@ -65,27 +59,30 @@ public class MockAssembly public const int ExplicitFixtures = 1; public const int SuitesRun = Suites - ExplicitFixtures; - public const int PassedButFailedInTearDown = FixtureWithDispose.Tests - + FixtureWithOneTimeTearDown.Tests - + TestSetUpFixture.SetUpFixture.TestsInNamespace; - public const int Passed = MockTestFixture.Passed + Singletons.OneTestCase.Tests + TestAssembly.MockTestFixture.Tests + FixtureWithTestCases.Tests + ParameterizedFixture.Tests + GenericFixtureConstants.Tests - + AccessesCurrentTestContextDuringDiscovery.Tests - + PassedButFailedInTearDown; + + AccessesCurrentTestContextDuringDiscovery.Tests; + + public const int PassedButFailedInTearDown = FixtureWithDispose.Tests + + FixtureWithOneTimeTearDown.Tests + + TestSetUpFixture.SetUpFixture.TestsInNamespace; + + public const int Passed_Raw = Passed + PassedButFailedInTearDown; - public const int Skipped_Ignored = MockTestFixture.Skipped_Ignored + IgnoredFixture.Tests; - public const int Skipped_Explicit = MockTestFixture.Skipped_Explicit + ExplicitFixture.Tests; - public const int Skipped = Skipped_Ignored + Skipped_Explicit; + public const int Ignored = MockTestFixture.Ignored + IgnoredFixture.Tests; + public const int Explicit = MockTestFixture.Explicit + ExplicitFixture.Tests; + public const int Skipped = Ignored + Explicit; - public const int Failed_Error = MockTestFixture.Failed_Error; - public const int Failed_Other = MockTestFixture.Failed_Other; - public const int Failed_NotRunnable = MockTestFixture.Failed_NotRunnable + BadFixture.Tests; - public const int Failed = Failed_Error + Failed_Other + Failed_NotRunnable; + public const int Failures = MockTestFixture.Failures; + public const int Errors_Raw = MockTestFixture.Errors; + public const int Errors = MockTestFixture.Errors + PassedButFailedInTearDown; + public const int NotRunnable = MockTestFixture.NotRunnable + BadFixture.Tests; + public const int Failed = Failures + Errors + NotRunnable; + public const int Failed_Raw = Failures + Errors_Raw + NotRunnable; public const int Warnings = MockTestFixture.Warnings; @@ -99,13 +96,13 @@ public static void DisplayCounts() Console.WriteLine($"Test Count: {Tests}"); Console.WriteLine($" Passed: {Passed}"); Console.WriteLine($" Failed: {Failed}"); - Console.WriteLine($" Failures: {Failed_Other}"); - Console.WriteLine($" Errors: {Failed_Error}"); - Console.WriteLine($" Invalid: {Failed_NotRunnable}"); + Console.WriteLine($" Failures: {Failures}"); + Console.WriteLine($" Errors: {Errors}"); + Console.WriteLine($" Invalid: {NotRunnable}"); Console.WriteLine($" Warnings: {Warnings}"); Console.WriteLine($" Skipped: {Skipped}"); - Console.WriteLine($" Explicit: {Skipped_Explicit}"); - Console.WriteLine($" Ignored: {Skipped_Ignored}"); + Console.WriteLine($" Explicit: {Explicit}"); + Console.WriteLine($" Ignored: {Ignored}"); Console.WriteLine($" Inconclusive: {Inconclusive}"); } } @@ -119,14 +116,14 @@ public class MockTestFixture public const int Passed = 1; - public const int Skipped_Ignored = 1; - public const int Skipped_Explicit = 1; - public const int Skipped = Skipped_Ignored + Skipped_Explicit; + public const int Ignored = 1; + public const int Explicit = 1; + public const int Skipped = Ignored + Explicit; - public const int Failed_Other = 1; - public const int Failed_Error = 1; - public const int Failed_NotRunnable = 2; - public const int Failed = Failed_Error + Failed_Other + Failed_NotRunnable; + public const int Failures = 1; + public const int Errors = 1; + public const int NotRunnable = 2; + public const int Failed = Errors + Failures + NotRunnable; public const int Warnings = 1;