Skip to content

Latest commit

 

History

History
242 lines (113 loc) · 7.55 KB

readme.source.md

File metadata and controls

242 lines (113 loc) · 7.55 KB

XunitLogger

Build status NuGet Status NuGet Status

Extends xUnit to simplify logging.

Redirects Trace.Write, Debug.Write, and Console.Write and Console.Error.Write to ITestOutputHelper. Also provides static access to the current ITestOutputHelper for use within testing utility methods.

Uses AsyncLocal to track state.

toc

NuGet package

https://nuget.org/packages/XunitLogger/

ClassBeingTested

snippet: ClassBeingTested.cs

XunitLoggingBase

XunitLoggingBase is an abstract base class for tests. It exposes logging methods for use from unit tests, and handle the flushing of longs in its Dispose method. XunitLoggingBase is actually a thin wrapper over XunitLogging. XunitLoggings Write* methods can also be use inside a test inheriting from XunitLoggingBase.

snippet: TestBaseSample.cs

XunitLogging

XunitLogging provides static access to the logging state for tests. It exposes logging methods for use from unit tests, however registration of ITestOutputHelper and flushing of logs must be handled explicitly.

snippet: XunitLoggerSample.cs

XunitLogging redirects Trace.Write, Console.Write, and Debug.Write in its static constructor.

snippet: writeRedirects

These API calls are then routed to the correct xUnit ITestOutputHelper via a static AsyncLocal.

Filters

XunitLogger.Filters can be used to filter out unwanted lines:

snippet: FilterSample.cs

Filters are static and shared for all tests.

Context

For every tests there is a contextual API to perform several operations.

  • Context.TestOutput: Access to ITestOutputHelper.
  • Context.Write and Context.WriteLine: Write to the current log.
  • Context.LogMessages: Access to all log message for the current test.
  • Counters: Provide access in predicable and incrementing values for the following types: Guid, Int, Long, UInt, and ULong.
  • Context.Test: Access to the current ITest.

There is also access via a static API.

snippet: ContextSample.cs

Current Test

There is currently no API in xUnit to retrieve information on the current test. See issues #1359, #416, and #398.

To work around this, this project exposes the current instance of ITest via reflection.

Usage:

snippet: CurrentTestSample.cs

Implementation:

snippet: LoggingContext_CurrentTest.cs

Test Failure

When a test fails it is expressed as an exception. The exception can be viewed by enabling exception capture, and then accessing Context.TestException. The TestException will be null if the test has passed.

One common case is to perform some logic, based on the existence of the exception, in the Dispose of a test.

snippet: TestExceptionSample

Counters

Provide access to predicable and incrementing values for the following types: Guid, Int, Long, UInt, and ULong.

Non Test Context usage

Counters can also be used outside of the current test context:

snippet: NonTestContextUsage

Implementation

snippet: LoggingContext_Counters.cs

snippet: Counters.cs

snippet: GuidCounter.cs

snippet: LongCounter.cs

Base Class

When creating a custom base class for other tests, it is necessary to pass through the source file path to XunitLoggingBase via the constructor.

snippet: XunitLoggingCustomBase

Parameters

Provided the parameters passed to the current test when using a [Theory].

Usage:

snippet: ParametersSample.cs

Implementation:

snippet: Parameters

UniqueTestName

Provided a string that uniquely identifies a test case.

Usage:

snippet: UniqueTestNameSample.cs

Implementation:

snippet: UniqueTestName

Logging Libs

Approaches to routing common logging libraries to Diagnostics.Trace:

Xunit.ApprovalTests

The default behavior of ApprovalTests uses the StackTrace to derive the current test and hence compute the name of the approval file. This has several drawbacks/issues:

  • Fragility: Deriving the test name from a stack trace is dependent on several things to be configured correctly. Optimization must be disabled to avoid in-lining and debug symbols enabled and parsable.
  • Performance impact: Computing a stack trace is a relatively expensive operation. Disabling optimization also impacts performance

Xunit.ApprovalTests avoids these problems by using the current xUnit context to derive the approval file name.

NuGet package

https://nuget.org/packages/Xunit.ApprovalTests/

Usage

Usage is done via inheriting from a base class XunitApprovalBase

snippet: XunitApprovalBaseUsage

xUnit Theory

xUnit Theories are supported.

snippet: Theory

Will result in the following .approved. files:

  • Sample.Theory_value=Foo.approved.txt
  • Sample.Theory_value=9.approved.txt
  • Sample.Theory_value=True.approved.txt

AsEnvironmentSpecificTest

ApprovalTests NamerFactory.AsEnvironmentSpecificTest is supported.

snippet: AsEnvironmentSpecificTest

Will result in the following .approved. file:

  • Sample.AsEnvironmentSpecificTest_Foo.approved.txt

UseApprovalSubdirectory

ApprovalTests [UseApprovalSubdirectory] is supported.

snippet: UseApprovalSubdirectory

Will result in the following .approved. file:

  • SubDir\Sample.InSubDir.approved.txt

ForScenario

ApprovalTests ApprovalResults.ForScenario is supported.

snippet: ForScenario

Will result in the following .approved. file:

  • Sample.ForScenarioTest_ForScenario.Name.approved.txt

Base Class

When creating a custom base class for other tests, it is necessary to pass through the source file path to XunitApprovalBase via the constructor.

snippet: XunitApprovalCustomBase

Release Notes

See closed milestones.

Icon

Wolverine designed by Mike Rowe from The Noun Project.