[Test Improver] Add unit tests for LoggingManager.BuildAsync#8124
Conversation
Cover all key behaviors of LoggingManager: - AddProvider with null throws ArgumentNullException - BuildAsync with no providers returns a non-null factory - Factory delegate receives the correct LogLevel and IServiceProvider - Non-IExtension provider is always included - IExtension provider enabled -> included; disabled -> excluded - IAsyncInitializableExtension + enabled -> InitializeAsync called - IAsyncInitializableExtension + disabled -> InitializeAsync not called - Non-extension IAsyncInitializableExtension -> InitializeAsync called Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds unit test coverage for Microsoft.Testing.Platform.Logging.LoggingManager.BuildAsync, which is responsible for assembling the platform ILoggerFactory and conditionally including/initializing providers.
Changes:
- Adds coverage for
AddProvidernull-guard behavior. - Adds coverage for
BuildAsyncbehavior with no providers and correct propagation ofLogLevel/IServiceProviderinto provider factories. - Adds coverage for extension-provider enable/disable filtering and async initialization (
IAsyncInitializableExtension) behavior.
Show a summary per file
| File | Description |
|---|---|
| test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.cs | New unit tests covering provider inclusion/filtering and initialization behaviors in LoggingManager.BuildAsync. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 0
Evangelink
left a comment
There was a problem hiding this comment.
Summary
Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx
Key Findings
Good overall structure and naming conventions — the test names are descriptive and follow the MethodName_Condition_ExpectedBehavior pattern consistently. A few minor polish items:
- Unused
CreateLoggermock setups (lines 109 & 136) — Two tests that focus solely onInitializeAsyncalso configureCreateLoggeron their mock but never invokefactory.CreateLogger(), making those setups dead code. - Unclear lambda parameter
xin constructor (line 19) — The single instance ofxis inconsistent with the more descriptive parameter names used elsewhere in the file. - Nullable capture variable without intermediate assertion (line 56) — A missing
Assert.IsNotNull(capturedServiceProvider)before theAreSamecheck would produce a clearer failure message if the factory is not invoked.
Positive Highlights
- The three helper interface declarations (
IExtensionLoggerProvider,IInitializableLoggerProvider,IInitializableExtensionLoggerProvider) are a clean approach to composing test-only types for different provider combinations. - Clear separation between "inclusion" tests (that call
factory.CreateLogger) and "initialization" tests (that only checkInitializeAsyncwas called).
Generated by PR Nitpick Reviewer
🔍 Meticulously inspected by PR Nitpick Reviewer 🔍
Evangelink
left a comment
There was a problem hiding this comment.
Summary
Workflow: Expert Code Reviewer 🧠
Date: 2026-05-11
Repository: microsoft/testfx
Key Findings
No actionable issues found across all review categories:
- Correctness ✅ — All eight test cases accurately reflect the production logic in
LoggingManager.BuildAsync. TheIExtensionfilter path (enabled/disabled), theTryInitializeAsyncdispatch path (via theIAsyncInitializableExtensionextension method), and the non-extension inclusion path are all correctly exercised. - Threading ✅ — Test-only code; no thread-safety concerns.
- Performance ✅ — No hot-path concerns in test helpers.
- API Compat ✅ — No public API changes. The three helper interfaces (
IExtensionLoggerProvider,IInitializableLoggerProvider,IInitializableExtensionLoggerProvider) areinternaland scoped to the test file. - Resources ✅ —
IMonitor.Lockmock correctly returns a disposable; no leaked handles. - Security ✅ — No wire-format or IPC-contract changes.
Positive Observations
- The test-local interface trio precisely models the four combination cases the production code branches on (
IExtension×IAsyncInitializableExtension), without leaking test-only abstractions into production code. - The
IMonitormock is correctly initialized in the constructor so all async factory tests reuse the same setup. - Moq
Verifycalls are tight (Times.Once/Times.Never) and target the right method on the right mock.
Generated by Expert Code Reviewer 🧠
🧠 Reviewed by Expert Code Reviewer 🧠
Evangelink
left a comment
There was a problem hiding this comment.
Summary
Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx
Overview
PR #8124 adds a new LoggingManagerTests.cs covering 8 behaviours of LoggingManager.BuildAsync. The tests are well-structured, isolated (all state is per-instance), use the correct assertion library (MSTest Assert APIs), and exercise all the main code paths described in the PR description. No flakiness or isolation bugs were found.
Key Findings
-
[Coverage]
BuildAsync_NoProviders_ReturnsNonNullFactoryis a smoke-only test (line 33) — onlyAssert.IsNotNullis asserted; callingfactory.CreateLogger(...)on the empty factory would give stronger confidence. -
[DataDriven]
BuildAsync_PassesCorrectLogLevelAndServiceProviderToFactorytests a singleLogLevel(line 55) — using[DataRow]with a few representativeLogLevelvalues would make the "passthrough" invariant explicit and guard against accidental remapping in future refactors. -
[Coverage]
BuildAsync_InitializableExtensionProvider_WhenEnabled_CallsInitializeAsyncverifies initialization but not inclusion (line 114) — a regression whereInitializeAsync()is called but the provider is not added to the factory would go undetected, since the existing inclusion test uses a non-initializable mock. -
[Coverage] Same gap in
BuildAsync_NonExtensionInitializableProvider_CallsInitializeAsync(line 141) — no test jointly verifies thatIAsyncInitializableExtension(non-IExtension) providers are both initialized and included.
What Looks Good
- All mocks are instance fields; no static mutable state — the class is safe under parallel execution.
- The three composite test interfaces (
IExtensionLoggerProvider,IInitializableLoggerProvider,IInitializableExtensionLoggerProvider) are a clean way to create typed Moq mocks covering the relevant interface combinations. - The "disabled provider is excluded" test correctly calls
factory.CreateLoggerbefore assertingTimes.Never. - Assertion methods match the assertion intent throughout (
Assert.AreEqual,Assert.AreSame,Assert.ThrowsExactly, Moq.Verify).
Recommendations
- For tests #3 and #4 above: store the returned factory and add
factory.CreateLogger("test")+mockProvider.Verify(p => p.CreateLogger("test"), Times.Once)to jointly validate initialization and inclusion. - For test #2: parameterize with
[DataRow(LogLevel.Trace)],[DataRow(LogLevel.Warning)],[DataRow(LogLevel.Critical)].
Generated by Test Expert Reviewer
🧪 Test quality reviewed by Test Expert Reviewer 🧪
|
@copilot address review comments |
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Done in |
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Cover all key behaviors of LoggingManager:
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>