Chaos.Testing
0.1.0
dotnet add package Chaos.Testing --version 0.1.0
NuGet\Install-Package Chaos.Testing -Version 0.1.0
<PackageReference Include="Chaos.Testing" Version="0.1.0" />
<PackageVersion Include="Chaos.Testing" Version="0.1.0" />
<PackageReference Include="Chaos.Testing" />
paket add Chaos.Testing --version 0.1.0
#r "nuget: Chaos.Testing, 0.1.0"
#:package Chaos.Testing@0.1.0
#addin nuget:?package=Chaos.Testing&version=0.1.0
#tool nuget:?package=Chaos.Testing&version=0.1.0
Chaos.Testing
Chaos.Testing is a lightweight .NET library that provides testing helpers for NUnit tests. It integrates seamlessly with Microsoft.Extensions.Logging to write test logs to the NUnit test output
and optionally capture log messages for assertions.
Features
- NUnit Integration: Write logs directly to NUnit's
TestContext.Progressoutput - Log Capture: Optionally capture log messages for assertions in your tests
- TimeProvider Support: Full support for
TimeProviderabstraction, enabling deterministic timestamp testing - Generic and Non-Generic Loggers: Use
NUnitTestLogger<T>orNUnitTestLoggerdepending on your needs - Dependency Injection: Easy integration with
Microsoft.Extensions.DependencyInjectionandILoggingBuilder - Structured Logging: Capture complete log metadata including state, exceptions, event IDs, and timestamps
Installation
Install the package via NuGet:
dotnet add package Chaos.Testing
Or via the Package Manager Console:
Install-Package Chaos.Testing
Usage
Basic Logger Usage
using Chaos.Testing.Logging;
using Microsoft.Extensions.Logging;
using NUnit.Framework;
public class MyTests
{
[Test]
public void MyTest()
{
// Create a logger that writes to NUnit test output
var logger = new NUnitTestLogger();
logger.LogInformation("This message appears in test output");
logger.LogWarning("Warning message");
logger.LogError("Error message");
}
}
Capturing Log Messages for Assertions
[Test]
public void MyTest_WithLogCapture()
{
// Enable log capture by passing true to the constructor
var logger = new NUnitTestLogger(captureMessages: true);
// Log some messages
logger.LogInformation("User logged in");
logger.LogWarning("Cache miss");
// Assert on captured log messages
Assert.That(logger.LogMessages, Has.Count.EqualTo(2));
Assert.That(logger.LogMessages[0].LogLevel, Is.EqualTo(LogLevel.Information));
Assert.That(logger.LogMessages[0].Message, Is.EqualTo("User logged in"));
Assert.That(logger.LogMessages[1].LogLevel, Is.EqualTo(LogLevel.Warning));
}
Using with TimeProvider for Deterministic Testing
using Microsoft.Extensions.Time.Testing;
[Test]
public void MyTest_WithFakeTime()
{
var fakeTime = new FakeTimeProvider(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc));
var logger = new NUnitTestLogger(captureMessages: true, timeProvider: fakeTime);
logger.LogInformation("First message");
// Advance time
fakeTime.Advance(TimeSpan.FromHours(1));
logger.LogInformation("Second message");
// Assert on timestamps
Assert.That(logger.LogMessages[0].Timestamp, Is.EqualTo(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
Assert.That(logger.LogMessages[1].Timestamp, Is.EqualTo(new DateTime(2025, 1, 1, 1, 0, 0, DateTimeKind.Utc)));
}
Generic Logger with Type Categories
[Test]
public void MyTest_WithGenericLogger()
{
var logger = new NUnitTestLogger<MyTests>(captureMessages: true);
// Logger category is automatically set to the type name
logger.LogInformation("Message from MyTests");
Assert.That(logger, Is.InstanceOf<ILogger<MyTests>>());
}
Dependency Injection Integration
using Microsoft.Extensions.DependencyInjection;
using Chaos.Testing.Logging;
[Test]
public void MyTest_WithDependencyInjection()
{
var services = new ServiceCollection();
// Add NUnit test logging to your service collection
services.AddNUnitTestLogging();
// OR add it directly to an ILoggingBuilder
services.AddLogging(builder => builder.AddNUnit());
var serviceProvider = services.BuildServiceProvider();
var logger = serviceProvider.GetRequiredService<ILogger<MyTests>>();
logger.LogInformation("Logging from dependency injection");
}
Capturing Structured State
[Test]
public void MyTest_WithStructuredState()
{
var logger = new NUnitTestLogger(captureMessages: true);
var state = new { UserId = 123, Action = "Login" };
logger.Log(
LogLevel.Information,
new EventId(1, "UserAction"),
state,
null,
(s, ex) => $"User {s.UserId} performed {s.Action}"
);
var captured = logger.LogMessages[0];
Assert.That(captured.State, Is.SameAs(state));
Assert.That(captured.Message, Is.EqualTo("User 123 performed Login"));
Assert.That(captured.EventId.Name, Is.EqualTo("UserAction"));
}
API Reference
NUnitTestLogger
The main logger implementation.
Constructor Parameters:
captureMessages(Boolean, optional): Iftrue, log messages are captured in theLogMessagescollection. Default:falsetimeProvider(TimeProvider?, optional): The time provider used for timestamping captured messages. Default:TimeProvider.System
Properties:
LogMessages(IReadOnlyList<LogMessage>): Collection of captured log messages (only populated whencaptureMessagesistrue)
NUnitTestLogger<T>
Generic version of the logger with typed category.
LogMessage
Record representing a captured log message.
Properties:
Timestamp(DateTime): UTC timestamp when the message was loggedLogLevel(LogLevel): Severity level of the log messageEventId(EventId): Event identifier associated with the log messageState(Object?): State object passed to the loggerException(Exception?): Exception associated with the log message, if anyMessage(String): Formatted log message text
Extension Methods
ILoggingBuilder.AddNUnit()
Adds the NUnit logger provider to the logging builder.
IServiceCollection.AddNUnitTestLogging()
Adds logging services configured with the NUnit logger provider.
Requirements
- .NET 8.0 or .NET 9.0
- NUnit testing framework
- Microsoft.Extensions.Logging and Microsoft.Extensions.Logging.Abstractions
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests on GitHub.
License
MIT License - see LICENSE for more information.
Copyright © 2025 Christian Flessa
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Logging (>= 9.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.9)
- Microsoft.Extensions.TimeProvider.Testing (>= 9.9.0)
- NUnit (>= 4.4.0)
-
net9.0
- Microsoft.Extensions.Logging (>= 9.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.9)
- Microsoft.Extensions.TimeProvider.Testing (>= 9.9.0)
- NUnit (>= 4.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 1,600 | 10/12/2025 |
| 0.1.0-preview.1 | 150 | 10/12/2025 |
# v0.1.0 (2025-10-12)
- No changes since last release