[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension - #8131

Merged
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f
May 13, 2026
Merged

[Test Improver] test: add unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension#8131
Amaury Levé (Evangelink) merged 5 commits into
mainfrom
test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f

Conversation

@Evangelink

@EvangelinkAmaury Levé (Evangelink) commented May 11, 2026

Copy link
Copy Markdown
Member

Adds unit tests for LoggingManager.BuildAsync covering:

  • No providers case (returns non-null factory, verified by also calling CreateLogger)
  • Non-extension provider inclusion
  • Extension provider enabled/disabled filtering (with IsEnabledAsync call verification)
  • IAsyncInitializableExtension initialization for both enabled and disabled extension provider paths
  • Non-extension initializable provider path
  • Factory receives correct log level and service provider (parametrized across multiple log levels)

Adds unit tests for ExtensionValidationHelper.ValidateUniqueExtension covering:

  • Null argument validation for both overloads
  • Empty collection (no-throw)
  • No-duplicate case (no-throw)
  • Single and multiple duplicates (throw), including error message content (uid and both distinct concrete type names)
  • Case-sensitivity behavior (UIDs differing only by case do not conflict)
  • Custom selector overload with wrapper types

Also fixes a build error in DesktopTestSourceHostTests.cs introduced by the Moq upgrade to 4.20.72, which added nullable reference type annotations requiring null literals passed to Mock<TestSourceHost> constructor args to be cast to (IRunSettings?)null.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…ationHelper.ValidateUniqueExtension
Adds 10 tests for LoggingManager.BuildAsync covering:
- No providers case
- Non-extension provider inclusion
- Extension provider enabled/disabled filtering
- IAsyncInitializableExtension initialization
- Multiple providers handling
- Factory receives correct log level and service provider
Adds 16 tests for ExtensionValidationHelper.ValidateUniqueExtension covering:
- Null argument validation for both overloads
- Empty collection (no-throw)
- No-duplicate case (no-throw)
- Single and multiple duplicates (throw)
- Error message content (uid and type names)
- Custom selector overload
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 14:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds targeted unit-test coverage in Microsoft.Testing.Platform.UnitTests for two internal helpers in Microsoft.Testing.Platform: log factory construction (LoggingManager.BuildAsync) and extension UID uniqueness enforcement (ExtensionValidationHelper.ValidateUniqueExtension).

Changes:

  • Add LoggingManager.BuildAsync tests covering provider inclusion/exclusion (extension enabled/disabled), async initialization, multiple providers, and argument validation for AddProvider.
  • Add ExtensionValidationHelper.ValidateUniqueExtension tests covering null guards for both overloads, duplicate detection (single/multiple), custom selector behavior, and key error-message content.
Show a summary per file
FileDescription
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingManagerTests.csNew tests validating LoggingManager.BuildAsync provider filtering/initialization and factory callback inputs.
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/ExtensionValidationHelperTests.csNew tests validating duplicate-UID detection and null-guard behavior for both ValidateUniqueExtension overloads.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: PR Nitpick Reviewer 🔍
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

This is a clean, well-structured PR adding unit tests for LoggingManager.BuildAsync and ExtensionValidationHelper.ValidateUniqueExtension. The test naming follows the MethodName_Condition_ExpectedResult convention consistently, coverage is thorough, and the CreateExtension factory helper is a nice touch. A few small improvements are worth considering:

  1. ImportantValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames asserts on existingTypeName and newTypeName, but since both mocks are Mock<IExtension>, Moq produces the same proxy type for both — the two assertions check the same string. The test doesn't actually validate distinct type names.

  2. ImportantBuildAsync_ExtensionProviderDisabled_IsExcluded declares mockLogger and sets up CreateLogger on the disabled provider, but this setup is never invoked. Compare with BuildAsync_ExtensionDisabled_IsNotInitialized which correctly omits the unused mock.

  3. MinormockEnabled/mockDisabled naming in BuildAsync_MixedEnabledAndDisabledExtensions_OnlyEnabledIncluded breaks the mockProvider* naming convention used throughout the rest of the file.

  4. Minor — Two null-guard tests in ExtensionValidationHelperTests.cs use Mock<IExtension> newExtension = new() instead of the CreateExtension(...) helper used everywhere else.

  5. Minor — The three helper internal interface declarations are placed after the test class closing brace; moving them before the class (or to a separate file) makes them easier to discover.

Recommendations

  • Fix the ErrorMessageContainsBothTypeNames test to use two concrete IExtension implementations with different types, or rename the test to reflect what it actually verifies.
  • Remove the superfluous mockLogger + CreateLogger setup from the disabled-provider test.

Generated by PR Nitpick Reviewer

🔍 Meticulously inspected by PR Nitpick Reviewer 🔍

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Test Expert Reviewer 🧪
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

  1. [Assertion — Important]ValidateUniqueExtension_OneDuplicate_ErrorMessageContainsBothTypeNames: Both existing.Object.GetType() and newExtension.Object.GetType() resolve to the same Moq-generated proxy type, so existingTypeName == newTypeName. The two Assert.Contains calls are asserting the same string, providing false confidence that both distinct type names appear in the error message.

  2. [Coverage — Important] Missing test for the enabled+initializable provider path: BuildAsync_ExtensionDisabled_IsNotInitialized covers the disabled case for IEnabledInitializableLoggerProvider, but there is no test verifying that an enabledIEnabledInitializableLoggerProvider gets initialized. This leaves a gap in the production code path IsEnabledAsync() == true → TryInitializeAsync().

  3. [Assertion — Moderate]BuildAsync_ExtensionDisabled_IsNotInitialized: Verifying InitializeAsync() is Times.Never is necessary but not sufficient. A verification that IsEnabledAsync() was actually called would close the loop and prevent bugs where the enabled check is bypassed entirely.

  4. [Assertion — Minor]BuildAsync_NoProviders_ReturnsEmptyLoggerFactory: The test name claims behavioral verification ("empty factory") but only asserts IsNotNull. Either rename or strengthen the assertion.

Recommendations

  • Use concrete stub types (not mocks) in ErrorMessageContainsBothTypeNames to get genuinely distinct type names
  • Add a BuildAsync_ExtensionEnabled_IsInitialized test using IEnabledInitializableLoggerProvider with IsEnabledAsync() returning true
  • Add Verify(p => p.IsEnabledAsync(), Times.Once) alongside the existing Times.Never assertion
  • Rename BuildAsync_NoProviders_ReturnsEmptyLoggerFactory to reflect what is actually tested

Generated by Test Expert Reviewer

🧪 Test quality reviewed by Test Expert Reviewer 🧪

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Workflow: Expert Code Reviewer
Date: 2026-05-11
Repository: microsoft/testfx

Key Findings

No correctness, threading, performance, API compatibility, resource management, or security issues found.

Verified correct:

  • Assert.Contains(string, string) overload resolutionAssert.Contains("my-uid", ex.Message) correctly resolves to the string-specific overload Contains(string substring, string value), not the collection overload. Checking ex.Message contains the substring is accurate.

  • IEnabledLoggerProvider / IInitializableLoggerProvider / IEnabledInitializableLoggerProvider interface design — The three test-local interfaces precisely model the combinations of ILoggerProvider, IExtension, and IAsyncInitializableExtension that LoggingManager.BuildAsync branches on. The enabled/disabled/initializable logic is exercised correctly.

  • LoggingManager.BuildAsync enabled-check logic — When IsEnabledAsync() returns false, the continue correctly prevents both TryInitializeAsync and loggerProviders.Add; the tests for BuildAsync_ExtensionDisabled_IsNotInitialized and BuildAsync_ExtensionProviderDisabled_IsExcluded verify both effects correctly.

  • Non-extension initializable providerIInitializableLoggerProvider : ILoggerProvider, IAsyncInitializableExtension (without IExtension) correctly bypasses the enabled check and proceeds to TryInitializeAsync, as the test BuildAsync_InitializableProvider_IsInitialized verifies.

  • ExtensionValidationHelper selector overload — The WithCustomSelector test correctly exercises the generic overload with a tuple collection and a selector lambda.

  • MSTest assertion APIs — All assertions use MSTest's Assert class in accordance with the project's BannedSymbols.txt (which bans AwesomeAssertions in this test project).

  • Internal accessLoggingManager and IMonitor are internal, but Microsoft.Testing.Platform.UnitTests has an InternalsVisibleTo entry in the main project, so compilation will succeed.

Recommendations

None — the tests are functionally accurate and cover the key behavioral paths.


Generated by Expert Code Reviewer 🧠

🧠 Reviewed by Expert Code Reviewer 🧠

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot address review comment

…onHelper tests
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 16:32
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 16:32

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Main had independently landed similar test files via #8124 and #8128 (add/add conflicts). The merged result takes main's version as the base and incorporates our improvements: interfaces placed before the test class, and IsEnabledAsync Times.Once verification in the disabled-provider test.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot please fix the followinb build errors:

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L107

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(107,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.
Check failure on line 164 in test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs

azure-pipelines
azure-pipelines
/ microsoft.testfx (Build Windows Debug)
test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs#L164

test\UnitTests\MSTestAdapter.PlatformServices.UnitTests\Services\DesktopTestSourceHostTests.cs(164,57): error CS8625: (NETCORE_ENGINEERING_TELEMETRY=Build) Cannot convert null literal to non-nullable reference type.

… calls for Moq 4.20.72 NRT compatibility
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 11, 2026 17:31
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 11, 2026 17:31

CopilotAI commented May 11, 2026

Copy link
Copy Markdown
Contributor

Copilot please fix the followinb build errors:

azure-pipelines
...

Fixed in the latest commit. Moq 4.20.72 added nullable reference type annotations, so passing a bare null literal to Mock<TestSourceHost>(location, null) now triggers CS8625. Changed both occurrences (lines 107 and 164) to (IRunSettings?)null to supply a typed null that satisfies the NRT constraint.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Note

The pull request was not created — a fallback review issue was created instead due to protected file changes: #8140

🤖 Test Improver here. Status update: the work in this PR has been superseded. The LoggingManager tests landed in main via #8124 and #8130, and the ExtensionValidationHelper tests landed via #8128. This PR is a duplicate and can be safely closed.

Generated by Daily Test Improver · ● 9.5M ·

@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

1 similar comment
@Evangelink

Copy link
Copy Markdown
MemberAuthor

Copilot resolve the merge conflicts in this pull request

…anager-and-extension-validation-tests-v7-117fbe2f3bea215f
# Conflicts:
#	test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 13, 2026 11:19
@Evangelink
Amaury Levé (Evangelink) removed the request for review from CopilotMay 13, 2026 11:19

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. Both this branch and main independently fixed the CS8625 nullable warning in DesktopTestSourceHostTests.cs. The conflict was resolved by taking main's approach (null!) over our branch's (IRunSettings?)null cast — both are functionally equivalent but null! matches the pattern already used in the same file for other TestSourceHost constructions.

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merge conflicts are already resolved — commit 1118d3e merged origin/main into this branch. The branch is now up to date with no remaining conflicts.

@Evangelink
Amaury Levé (Evangelink) merged commit 11079c9 into mainMay 13, 2026
11 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the test-assist/logging-manager-and-extension-validation-tests-v7-117fbe2f3bea215f branch May 13, 2026 12:57
Sign up for freeto 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.

3 participants

@Evangelink