Implement dynamic exclusion filters for Coverlet.MTP assemblies - #1946
Merged
Merged
Conversation
Replace static exclude list with dynamic discovery of loaded assemblies at runtime. Introduce IProcessAssemblyHelper for testability and maintainability. Update CoverageConfiguration to use dynamic filters as defaults when no config file is present, keeping CLI/config file override logic. Reduce CoverletMTPConstants to a single baseline filter. Add tests for new dynamic behavior. This removes the need for manual updates when new test frameworks are used.
Refactor exclusion logic to dynamically discover and exclude loaded test framework assemblies at runtime using a new IProcessAssemblyHelper abstraction. Always include a permanent baseline filter for Coverlet assemblies. Update CoverageConfiguration to merge filters by CLI, config file, then dynamic defaults. Add comprehensive unit tests for dynamic exclusion, fallback, and deduplication. Update existing tests to match new behavior. Improves robustness and reduces hardcoded filter maintenance.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces dynamic default exclude filters for coverlet.MTP by discovering loaded assemblies at runtime instead of relying on a long static list. It adds a core helper abstraction, wires it into MTP configuration, and expands tests/documentation around precedence and fallback behavior.
Changes:
- Adds
IProcessAssemblyHelper/ProcessAssemblyHelperto enumerate loaded assembly names and convert them to coverlet exclude filters. - Updates
CoverageConfigurationandCollectorExtensionto use dynamic exclude defaults when no CLI/config-file exclusions are provided. - Adds tests and documentation for dynamic filtering, precedence, deduplication, and fallback behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/coverlet.core/Abstractions/IProcessAssemblyHelper.cs |
Adds an internal abstraction for retrieving loaded assembly names. |
src/coverlet.core/Helpers/ProcessAssemblyHelper.cs |
Implements loaded-assembly discovery and filter-pattern conversion. |
src/coverlet.MTP/Configuration/CoverageConfiguration.cs |
Replaces static default exclude list with baseline + dynamic defaults. |
src/coverlet.MTP/Collector/CollectorExtension.cs |
Passes the test assembly name into MTP coverage configuration. |
test/coverlet.core.tests/Helpers/ProcessAssemblyHelperTests.cs |
Adds tests for assembly discovery and filter formatting. |
test/coverlet.MTP.tests/Configuration/CoverageConfigurationDynamicExcludeTests.cs |
Adds tests for dynamic defaults, precedence, fallback, and deduplication. |
test/coverlet.MTP.tests/Configuration/CoverageConfigurationTests.cs |
Updates existing exclude-filter assertions for the new baseline behavior. |
Documentation/Plans/DynamicExcludeFilters.md |
Documents the design and intended behavior of dynamic exclude filters. |
Extend dynamic exclude-filter logic to merge assemblies from both the test module's deps.json and the controller process, improving infrastructure exclusion for coverage. Add GetDepsJsonAssemblyNames to IProcessAssemblyHelper and implement it. Update filter pattern logic to wildcard after the second segment for multi-part names and prune redundant filters. Refactor CoverageConfiguration to use testModulePath. Expand and update tests to cover new logic and edge cases. Apply minor code and style improvements.
Revise documentation to clarify default exclude filters, introduce dynamic runtime exclusions based on assembly naming, and specify that both static and dynamic exclusions are not applied when a configuration file is present. Update breaking change notice accordingly.
Updated CoverageConfigurationDynamicExcludeTests to expect additional default exclude filters: "[Microsoft.VisualStudio.TestPlatform.*]*" and "[testhost*]*", in addition to "[coverlet.*]*". This aligns test expectations with the new dynamic exclusion logic.
This was referenced Sep 27, 2026
This was referenced Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a dynamic mechanism for generating default assembly exclude filters in
coverlet.MTP, replacing the previous static list with runtime discovery of loaded assemblies (#1934). This makes it easier to support new test frameworks without code changes and improves maintainability. The change is architected to ensure that dynamic filtering is only applied when no configuration file is present, preserving existing precedence rules. The implementation is modular and testable, with new abstractions and unit tests to support the new logic.Dynamic Exclude Filter Generation:
IProcessAssemblyHelperinterface andProcessAssemblyHelperimplementation tocoverlet.corefor discovering assemblies loaded in the current process at runtime. This enables the generation of exclude filters based on actual test infrastructure dependencies present during test execution."xunit.core"→"[xunit.core]*").Configuration and Precedence Changes:
CoverageConfigurationincoverlet.MTPto:IProcessAssemblyHelperand the test assembly name."[coverlet.*]*") and generate additional filters dynamically at runtime.CollectorExtensionto pass the test assembly name toCoverageConfiguration, enabling the exclusion of the test assembly itself from the dynamic filters.Constants and Maintenance:
CoverletMTPConstants.csto a single baseline entry, with all other framework assemblies discovered dynamically.Documentation and Testing:
DynamicExcludeFilters.md) describing the motivation, architecture, implementation steps, and benefits of the new dynamic exclude filter mechanism.These changes collectively automate the process of excluding test infrastructure assemblies from coverage reports, reducing manual maintenance and improving support for new or custom test frameworks.