Skip to content

Commit

Permalink
Merge pull request #272 from thePantz/feature/xunit-fixture-logging
Browse files Browse the repository at this point in the history
xUnit fixture logging
  • Loading branch information
AutomationPanda authored Apr 16, 2024
2 parents ebd298a + e4ff43a commit ce41918
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@
<ItemGroup>
<ProjectReference Include="..\Boa.Constrictor.Xunit\Boa.Constrictor.Xunit.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="xunit.runner.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Boa.Constrictor.Xunit.UnitTests;

using global::Xunit.Abstractions;
using global::Xunit.Sdk;

/// <summary>
/// A test double that enables reading the output of a message sink
/// </summary>
public class ConcreteMessageSink : IMessageSink
{
public bool OnMessage(IMessageSinkMessage message)
{
var diagnosticMessage = (DiagnosticMessage)message;
LastMessage = diagnosticMessage.Message;
return true;
}

public string LastMessage { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
namespace Boa.Constrictor.Xunit.UnitTests;

using Boa.Constrictor.Screenplay;
using FluentAssertions;
using global::Xunit;

public class MessageSinkLoggerTest
{
#region Variables

const string TimePattern = @"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}";

ConcreteMessageSink MessageSink;

MessageSinkLogger Logger;

#endregion

#region Setup

public MessageSinkLoggerTest()
{
MessageSink = new ConcreteMessageSink();
Logger = new MessageSinkLogger(MessageSink);
}

#endregion

#region Tests

[Fact]
public void Close()
{
Logger.Info("hello");
Logger.Info("moto");
Logger.Invoking(y => y.Close()).Should().NotThrow();
}

[Fact]
public void LogArtifact()
{
const string type = "Screenshot";
const string path = "path/to/screen.png";

Logger.LogArtifact(type, path);

MessageSink.LastMessage.Should().MatchRegex(TimePattern).And.EndWith($"[INFO] {type}: {path}");
}

[Theory]
[InlineData("Trace")]
[InlineData("Debug")]
[InlineData("Info")]
[InlineData("Warning")]
[InlineData("Error")]
[InlineData("Fatal")]
public void LogByLevel(string level)
{
const string message = "Message text!";

Logger.GetType().GetMethod(level).Invoke(Logger, new object[] { message });

MessageSink.LastMessage.Should().MatchRegex(TimePattern).And.EndWith($"[{level.ToUpper()}] {message}");
}

[Theory]
[InlineData("Info")]
[InlineData("Warning")]
[InlineData("Error")]
[InlineData("Fatal")]
public void LowestSeverityLogged(string level)
{
const string message = "Message text!";
Logger.LowestSeverity = LogSeverity.Info;

Logger.GetType().GetMethod(level).Invoke(Logger, new object[] { message });

MessageSink.LastMessage.Trim().Should().MatchRegex(TimePattern).And.EndWith($"[{level.ToUpper()}] {message}");
}

[Theory]
[InlineData("Trace")]
[InlineData("Debug")]
[InlineData("Info")]
[InlineData("Warning")]
[InlineData("Error")]
public void LowestSeverityBlocked(string level)
{
const string message = "Message text!";
Logger.LowestSeverity = LogSeverity.Fatal;

Logger.GetType().GetMethod(level).Invoke(Logger, new object[] { message });

MessageSink.LastMessage.Should().BeNull();
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@

namespace Boa.Constrictor.Xunit.UnitTests
{
public class XunitLoggerTest
public class TestOutputLoggerTest
{
#region Variables

const string TimePattern = @"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}";

public TestOutputHelper OutputHelper;

public XunitLogger Logger;
public TestOutputLogger Logger;

#endregion

#region SetUp

public XunitLoggerTest()
public TestOutputLoggerTest()
{
// Using a concrete TestOutputHelper allows us to access the output
OutputHelper = new TestOutputHelper();
Logger = new XunitLogger(OutputHelper);
Logger = new TestOutputLogger(OutputHelper);

InitializeOutputHelper();
}
Expand Down Expand Up @@ -80,7 +80,7 @@ public void LogArtifact()
const string path = "path/to/screen.png";

Logger.LogArtifact(type, path);

OutputHelper.Output.Trim().Should().MatchRegex(TimePattern).And.EndWith($"[INFO] {type}: {path}");
}

Expand Down Expand Up @@ -133,4 +133,4 @@ public void LowestSeverityBlocked(string level)

#endregion
}
}
}
4 changes: 4 additions & 0 deletions Boa.Constrictor.Xunit.UnitTests/xunit.runner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"diagnosticMessages": true
}
5 changes: 3 additions & 2 deletions Boa.Constrictor.Xunit/Boa.Constrictor.Xunit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<Version>4.0.0</Version>
<Version>4.1.0</Version>
<Authors>Keith Tremorin, Pandy Knight, and the PrecisionLender SETs</Authors>
<Company>Q2</Company>
<Title>Boa.Constrictor.Xunit</Title>
Expand All @@ -28,6 +28,7 @@

<ItemGroup>
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.2" />
</ItemGroup>

<ItemGroup Condition="'$(Configuration)' == 'Release'">
Expand All @@ -38,4 +39,4 @@
<ProjectReference Include="..\Boa.Constrictor.Screenplay\Boa.Constrictor.Screenplay.csproj" />
</ItemGroup>

</Project>
</Project>
13 changes: 11 additions & 2 deletions Boa.Constrictor.Xunit/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ This file documents all notable changes to the Boa.Constrictor.Xunit project and
Its format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

## [Unreleased]

(none)

## [4.1.0] - 2024-04-15
### Added

- Added `MessageSinkLogger` for logging in xUnit extensibility classes
- See [the docs](https://q2ebanking.github.io/boa-constrictor/user-guides/testing-with-xunit-net/#shared-context) for more info

### Changed

- Renamed `XunitLogger` to `TestOutputLogger`


## [4.0.0] - 2023-05-29

Expand All @@ -32,4 +41,4 @@ Its format is based on Keep a Changelog, and this project adheres to Semantic Ve
- Added project `Boa.Constrictor.Xunit.UnitTests`
- Added XunitLogger to support the use of `ITestOutputHelper`
- Added `XunitLoggerTests`
- Updated `nuget-push.yml` to publish the `Boa.Constrictor.Xunit` package
- Updated `nuget-push.yml` to publish the `Boa.Constrictor.Xunit` package
62 changes: 62 additions & 0 deletions Boa.Constrictor.Xunit/Logging/Loggers/MessageSinkLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Boa.Constrictor.Xunit
{
using Boa.Constrictor.Screenplay;
using global::Xunit.Abstractions;
using global::Xunit.Sdk;

/// <summary>
/// Prints messages to xUnit's IMessageSink.
/// </summary>
public class MessageSinkLogger : AbstractLogger
{
#region Constructors

/// <summary>
/// Constructor.
/// </summary>
/// <param name="messageSink">the logger object used by xUnit's extensibility classes.</param>
/// <param name="lowestSeverity">The lowest severity message to log.</param>
public MessageSinkLogger(IMessageSink messageSink, LogSeverity lowestSeverity = LogSeverity.Trace)
:base(lowestSeverity)
{
MessageSink = messageSink;
}

#endregion

#region Properties

/// <summary>
/// A logger object used by xUnit's extensibility classes.
/// </summary>
public IMessageSink MessageSink { get; set; }

#endregion

#region Log Method Implementations

/// <summary>
/// Closes the logging stream
/// (No-op for IMessageSink)
/// </summary>
public override void Close()
{
}

/// <summary>
/// Logs a basic message to the console after checking the lowest severity.
/// </summary>
/// <param name="message">The message text.</param>
/// <param name="severity">The severity level (defaults to info).</param>
protected override void LogRaw(string message, LogSeverity severity = LogSeverity.Info)
{
if (severity >= LowestSeverity)
{
var diagnosticMessage = new DiagnosticMessage(MessageFormat.StandardTimestamp(message, severity));
MessageSink.OnMessage(diagnosticMessage);
}
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
namespace Boa.Constrictor.Xunit
{
/// <summary>
/// Prints messages to xUnit's ITestOutputHelper
/// Prints messages to xUnit's ITestOutputHelper
/// </summary>
public class XunitLogger : AbstractLogger
public class TestOutputLogger : AbstractLogger
{
#region Constructors

Expand All @@ -15,7 +15,7 @@ public class XunitLogger : AbstractLogger
/// </summary>
/// <param name="testOutputHelper">The xUnit logger object</param>
/// <param name="lowestSeverity">The lowest severity message to log.</param>
public XunitLogger(ITestOutputHelper testOutputHelper, LogSeverity lowestSeverity = LogSeverity.Trace) : base(lowestSeverity)
public TestOutputLogger(ITestOutputHelper testOutputHelper, LogSeverity lowestSeverity = LogSeverity.Trace) : base(lowestSeverity)
{
TestOutputHelper = testOutputHelper;
}
Expand Down Expand Up @@ -56,4 +56,4 @@ protected override void LogRaw(string message, LogSeverity severity = LogSeverit

#endregion
}
}
}
Loading

0 comments on commit ce41918

Please sign in to comment.