Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix consoleout=0, so also Error and Progress are blocked in this case… #1162

Merged
merged 3 commits into from Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.cake
Expand Up @@ -15,7 +15,7 @@ var configuration = Argument("configuration", "Release");

var version = "4.6.0";

var modifier = "-beta.1";
var modifier = "-beta.2";

var dbgSuffix = configuration.ToLower() == "debug" ? "-dbg" : "";
var packageVersion = version + modifier + dbgSuffix;
Expand Down
74 changes: 42 additions & 32 deletions src/NUnitTestAdapter/NUnitEventListener.cs
Expand Up @@ -31,7 +31,6 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;

using NUnit.Engine;
using NUnit.VisualStudio.TestAdapter;
using NUnit.VisualStudio.TestAdapter.Dump;
using NUnit.VisualStudio.TestAdapter.Internal;
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
Expand All @@ -49,10 +48,10 @@ public class NUnitEventListener :
ITestEventListener, IDisposable // Public for testing
{
private static readonly ICollection<INUnitTestEventTestOutput> EmptyNodes = new List<INUnitTestEventTestOutput>();
private readonly ITestExecutionRecorder recorder;
private readonly ITestConverterCommon testConverter;
private readonly IAdapterSettings settings;
private readonly Dictionary<string, ICollection<INUnitTestEventTestOutput>> outputNodes = new();
private ITestExecutionRecorder Recorder { get; }
private ITestConverterCommon TestConverter { get; }
private IAdapterSettings Settings { get; }
private Dictionary<string, ICollection<INUnitTestEventTestOutput>> OutputNodes { get; } = new();

#if NET462
public override object InitializeLifetimeService()
Expand All @@ -65,15 +64,15 @@ public override object InitializeLifetimeService()
}
#endif

private readonly INUnit3TestExecutor executor;
private INUnit3TestExecutor Executor { get; }

public NUnitEventListener(ITestConverterCommon testConverter, INUnit3TestExecutor executor)
{
this.executor = executor;
Executor = executor;
dumpXml = executor.Dump;
settings = executor.Settings;
recorder = executor.FrameworkHandle;
this.testConverter = testConverter;
Settings = executor.Settings;
Recorder = executor.FrameworkHandle;
TestConverter = testConverter;
}

#region ITestEventListener
Expand Down Expand Up @@ -105,8 +104,8 @@ public void OnTestEvent(string report)
}
catch (Exception ex)
{
recorder.SendMessage(TestMessageLevel.Warning, $"Error processing {node.Name} event for {node.FullName}");
recorder.SendMessage(TestMessageLevel.Warning, ex.ToString());
Recorder.SendMessage(TestMessageLevel.Warning, $"Error processing {node.Name} event for {node.FullName}");
Recorder.SendMessage(TestMessageLevel.Warning, ex.ToString());
}
}

Expand Down Expand Up @@ -143,51 +142,56 @@ protected virtual void Dispose(bool disposing)

public void TestStarted(INUnitTestEventStartTest testNode)
{
var ourCase = testConverter.GetCachedTestCase(testNode.Id);
var ourCase = TestConverter.GetCachedTestCase(testNode.Id);

// Simply ignore any TestCase not found in the cache
if (ourCase != null)
recorder.RecordStart(ourCase);
Recorder.RecordStart(ourCase);
}

/// <summary>
/// Collects up all text output messages in the current test, and outputs them here.
/// Note: Error and Progress are handled in TestOutput.
/// </summary>
/// <param name="resultNode"></param>
public void TestFinished(INUnitTestEventTestCase resultNode)
{
var testId = resultNode.Id;
if (this.outputNodes.TryGetValue(testId, out var outputNodes))
if (OutputNodes.TryGetValue(testId, out var outputNodes))
{
this.outputNodes.Remove(testId);
OutputNodes.Remove(testId);
}

var result = testConverter.GetVsTestResults(resultNode, outputNodes ?? EmptyNodes);
if (settings.ConsoleOut >= 1)
var result = TestConverter.GetVsTestResults(resultNode, outputNodes ?? EmptyNodes);
if (Settings.ConsoleOut >= 1)
{
if (!result.ConsoleOutput.IsNullOrWhiteSpace() && result.ConsoleOutput != NL)
{
string msg = result.ConsoleOutput;
if (settings.UseTestNameInConsoleOutput)
if (Settings.UseTestNameInConsoleOutput)
msg = $"{resultNode.Name}: {msg}";
var messageLevel = settings.ConsoleOut == 1
var messageLevel = Settings.ConsoleOut == 1
? TestMessageLevel.Informational
: TestMessageLevel.Warning;
recorder.SendMessage(messageLevel, msg);
Recorder.SendMessage(messageLevel, msg);
}
if (!resultNode.ReasonMessage.IsNullOrWhiteSpace())
{
recorder.SendMessage(TestMessageLevel.Informational, $"{resultNode.Name}: {resultNode.ReasonMessage}");
Recorder.SendMessage(TestMessageLevel.Informational, $"{resultNode.Name}: {resultNode.ReasonMessage}");
}
}

if (result.TestCaseResult != null)
{
recorder.RecordEnd(result.TestCaseResult.TestCase, result.TestCaseResult.Outcome);
Recorder.RecordEnd(result.TestCaseResult.TestCase, result.TestCaseResult.Outcome);
foreach (var vsResult in result.TestResults)
{
recorder.RecordResult(vsResult);
Recorder.RecordResult(vsResult);
}

if (result.TestCaseResult.Outcome == TestOutcome.Failed && settings.StopOnError)
if (result.TestCaseResult.Outcome == TestOutcome.Failed && Settings.StopOnError)
{
executor.StopRun();
Executor.StopRun();
}
}
}
Expand All @@ -199,24 +203,30 @@ public void SuiteFinished(INUnitTestEventSuiteFinished resultNode)
var site = resultNode.Site();
if (site != NUnitTestEvent.SiteType.Setup && site != NUnitTestEvent.SiteType.TearDown)
return;
recorder.SendMessage(TestMessageLevel.Warning, $"{site} failed for test fixture {resultNode.FullName}");
Recorder.SendMessage(TestMessageLevel.Warning, $"{site} failed for test fixture {resultNode.FullName}");

if (resultNode.HasFailure)
{
string msg = resultNode.FailureMessage;
var stackNode = resultNode.StackTrace;
if (!string.IsNullOrEmpty(stackNode) && settings.IncludeStackTraceForSuites)
if (!string.IsNullOrEmpty(stackNode) && Settings.IncludeStackTraceForSuites)
msg += $"\nStackTrace: {stackNode}";
recorder.SendMessage(TestMessageLevel.Warning, msg);
Recorder.SendMessage(TestMessageLevel.Warning, msg);
}
}

private static readonly string NL = Environment.NewLine;
private static readonly int NL_LENGTH = NL.Length;
private readonly IDumpXml dumpXml;

/// <summary>
/// Error stream and Progress stream are both sent here.
/// </summary>
/// <param name="outputNodeEvent"></param>
public void TestOutput(INUnitTestEventTestOutput outputNodeEvent)
{
if (Settings.ConsoleOut == 0)
return;
string text = outputNodeEvent.Content;

// Remove final newline since logger will add one
Expand All @@ -231,10 +241,10 @@ public void TestOutput(INUnitTestEventTestOutput outputNodeEvent)
string testId = outputNodeEvent.TestId;
if (!string.IsNullOrEmpty(testId))
{
if (!this.outputNodes.TryGetValue(testId, out var outputNodes))
if (!OutputNodes.TryGetValue(testId, out var outputNodes))
{
outputNodes = new List<INUnitTestEventTestOutput>();
this.outputNodes.Add(testId, outputNodes);
OutputNodes.Add(testId, outputNodes);
}

outputNodes.Add(outputNodeEvent);
Expand All @@ -244,7 +254,7 @@ public void TestOutput(INUnitTestEventTestOutput outputNodeEvent)
? TestMessageLevel.Warning
: TestMessageLevel.Informational;

recorder.SendMessage(testMessageLevel, text);
Recorder.SendMessage(testMessageLevel, text);
}
}
}
25 changes: 25 additions & 0 deletions src/NUnitTestAdapterTests/NUnitEventListenerOutputTests.cs
Expand Up @@ -49,13 +49,25 @@ public void Setup()
recorder = Substitute.For<IFrameworkHandle>();
converter = Substitute.For<ITestConverterCommon>();
settings = Substitute.For<IAdapterSettings>();
settings.ConsoleOut.Returns(1);
executor = Substitute.For<INUnit3TestExecutor>();
executor.Settings.Returns(settings);
executor.FrameworkHandle.Returns(recorder);
}

[Test]
public void ThatNormalTestOutputIsOutput()
{
var sut = new NUnitEventListener(converter, executor);
sut.OnTestEvent(TestOutputOut);
sut.OnTestEvent(TestFinish);

recorder.Received().SendMessage(Arg.Any<TestMessageLevel>(), Arg.Is<string>(x => x.StartsWith("Whatever")));
converter.Received().GetVsTestResults(Arg.Any<NUnitTestEventTestCase>(), Arg.Is<ICollection<INUnitTestEventTestOutput>>(x => x.Count == 1));
}

[Test]
public void ThatProgressTestOutputIsOutput()
{
var sut = new NUnitEventListener(converter, executor);
sut.OnTestEvent(TestOutputProgress);
Expand All @@ -76,6 +88,19 @@ public void ThatNormalTestOutputIsError()
converter.Received().GetVsTestResults(Arg.Any<NUnitTestEventTestCase>(), Arg.Is<ICollection<INUnitTestEventTestOutput>>(x => x.Count == 1));
}

[Test]
public void ThatConsoleOutCanStopAllTestOutput()
{
settings.ConsoleOut.Returns(0);
var sut = new NUnitEventListener(converter, executor);
sut.OnTestEvent(TestOutputOut);
sut.OnTestEvent(TestOutputProgress);
sut.OnTestEvent(TestOutputError);
sut.OnTestEvent(TestFinish);

recorder.DidNotReceive().SendMessage(Arg.Any<TestMessageLevel>(), Arg.Any<string>());
}

[Test]
public void ThatTestOutputWithOnlyWhiteSpaceIsNotOutput()
{
Expand Down