Skip to content

feat: add TUnit.Logging.Microsoft package and shared web app logging#4817

Merged
thomhurst merged 7 commits intomainfrom
feat/tunit-logging-microsoft
Feb 15, 2026
Merged

feat: add TUnit.Logging.Microsoft package and shared web app logging#4817
thomhurst merged 7 commits intomainfrom
feat/tunit-logging-microsoft

Conversation

@thomhurst
Copy link
Owner

Summary

  • New TUnit.Logging.Microsoft package — provides Microsoft.Extensions.Logging integration without ASP.NET Core dependencies, enabling ILogger output capture in TUnit test output for any IHost or generic DI scenario
  • Shared WebApplicationFactory logging — adds TUnitTestIdHandler (client-side header propagation) and CorrelatedTUnitLoggerProvider + TUnitTestContextMiddleware (server-side per-request test context resolution) so a single shared web app can route logs to the correct test
  • Improved log routing — logs now write directly to TestContext.Output.WriteLine()/WriteError() instead of Console.WriteLine, and error-level logs are properly separated

New package: TUnit.Logging.Microsoft

  • TUnitLogger / TUnitLoggerProvider — writes directly to test context output
  • ILoggingBuilder.AddTUnit(context) and IServiceCollection.AddTUnitLogging(context) extension methods
  • No ASP.NET Core dependency — works with any IHost-based app

Shared web app support in TUnit.AspNetCore

  • TUnitTestIdHandlerDelegatingHandler that propagates TestContext.Id via X-TUnit-TestId header
  • TUnitTestContextMiddleware — extracts test ID from request headers and resolves TestContext via GetById()
  • CorrelatedTUnitLogger — resolves test context per log call (HttpContext items → AsyncLocal fallback → no-op)
  • IServiceCollection.AddCorrelatedTUnitLogging() — one-call registration with IStartupFilter
  • WebApplicationFactory<T>.CreateClientWithTestContext() — convenience extension

Breaking changes

  • TUnitAspNetLogger, TUnitLoggerProvider, TUnitLoggerScope removed from TUnit.AspNetCore.Logging namespace (replaced by TUnit.Logging.Microsoft types)
  • Extension methods (AddTUnit, AddTUnitLogging) remain API-compatible in TUnit.AspNetCore.Extensions

Test plan

  • dotnet build TUnit.Logging.Microsoft — all 3 TFMs (net8.0/net9.0/net10.0) compile cleanly
  • dotnet build TUnit.AspNetCore — all 3 TFMs compile cleanly
  • dotnet test TUnit.AspNetCore.Analyzers.Tests — net8.0/net9.0 pass (net10.0 failures are pre-existing System.Runtime version mismatches)
  • Manual smoke test: AddTUnitLogging(testContext) captures ILogger output in test results
  • Manual smoke test: AddCorrelatedTUnitLogging() + CreateClientWithTestContext() routes shared app logs to correct test

🤖 Generated with Claude Code

Create a new TUnit.Logging.Microsoft package that provides Microsoft.Extensions.Logging
integration without requiring ASP.NET Core dependencies. This allows users who just need
IHost or generic DI to capture app-level ILogger output in TUnit test output.

For shared WebApplicationFactory scenarios, add correlated logging support to
TUnit.AspNetCore via TUnitTestIdHandler (client-side header propagation) and
TUnitTestContextMiddleware + CorrelatedTUnitLoggerProvider (server-side context
resolution per log call).

Key improvements over the previous TUnitAspNetLogger:
- Writes directly to TestContext.Output instead of Console.WriteLine
- Error-level logs routed to WriteError() for proper separation
- No longer sets TestContext.Current as a side effect in Log()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link
Contributor

claude bot commented Feb 15, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

This PR introduces a well-structured logging abstraction:

  • The new TUnit.Logging.Microsoft package successfully decouples logging from ASP.NET Core dependencies
  • The correlated logging architecture (header propagation → middleware extraction → context resolution) is sound and enables the shared WebApplicationFactory scenario
  • All CLAUDE.md mandatory rules are satisfied (no VSTest dependencies, proper async patterns, AOT compatibility)
  • Code follows modern C# conventions and patterns

The approach of separating generic IHost-compatible logging into its own package while building ASP.NET-specific correlation on top is a good architectural decision.

- Add TUnit.Logging.Microsoft to project-structure.md
- Rewrite TUnit Logging Integration section in aspnet.md with:
  - Per-test logging with isolated factory
  - Standalone logging without ASP.NET Core
  - Shared web app logging with header propagation
- Add new types and extensions to API reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set TestContext.Current before writing via Console.WriteLine/Console.Error.WriteLine
so the console interceptor and all registered log sinks (TestOutputSink,
ConsoleOutputSink, RealTimeOutputSink) naturally pick up and route the output.

This matches the original TUnitAspNetLogger pattern and ensures IDE real-time
output works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Automatically register correlated logging in CreateHostBuilder() and
per-test logging in GetIsolatedFactory() so users get logging out of
the box without manual setup. Add TUnitLoggingRegistry for duplicate
prevention when both loggers are active.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update ASP.NET Core and logging docs to reflect that
TestWebApplicationFactory now auto-registers both per-test and
correlated logging. Users no longer need manual setup — just use
CreateClientWithTestContext() for shared factory scenarios.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CI was failing because TUnit.AspNetCore now depends on
TUnit.Logging.Microsoft, but the new package wasn't being packed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: LoggingProvider for DI style tests

1 participant