Problem Statement
When a shared testing library references TUnit.Core (e.g., to provide an IAsyncInitializer implementations shared across multiple test assemblies), it is always treated by TUnit as a test assembly solely because it references TUnit types. This happens even if the assembly is purely infrastructure, containing no tests of its own. There is no way to instruct TUnit to ignore such assemblies during discovery, leading to unnecessary scanning, possible confusion, and performance overhead in solutions with many shared libraries.
Proposed Solution
Introduce an assembly-level attribute in TUnit.Core (such as [assembly: ExcludeFromTestDiscovery] or [assembly: DoNotScan]) that can be placed in shared libraries to indicate that TUnit should skip scanning them for test methods/classes.
Upon detecting this attribute in an assembly's metadata, both reflection-based and source-generated discovery engines should skip it.
This would require updates to the assembly filtering code in:
- TUnit.Engine/Discovery/ReflectionTestDataCollector.cs (ShouldScanAssembly)
- TUnit.Core.SourceGenerator/CodeGenerators/InfrastructureGenerator.cs (ShouldLoadAssembly)
Alternatives Considered
- Splitting shared libraries into multiple projects (core logic + using a test assembly) to avoid unnecessary TUnit.Core references. This adds maintenance overhead for large solutions, and hides important shared testing infrastructure in other test files.
- Leaving as is: causes unwanted discovery, performance impact, and confusion when shared libs show up as test assemblies. Errors when running
dotnet test as, in this case, the SharedTestingFramework assembly is a Library, not an Exe causing a failure.
- Relying on naming conventions (e.g. prefixes), which is fragile, not future-proof, and doesn't fit all orgs.
None are as direct or maintainable as a simple explicit opt-out.
Feature Category
Test Discovery / Attributes
How important is this feature to you?
Important - significantly impacts my workflow
Additional Context
Example use-case:
- Shared library implements
IAsyncInitializer, or contains TUnit.Core base types, but has no test classes or test methods ([Test]).
- Currently always scanned; desired: explicit opt-out attribute.
Relevant files for change:
Failure:
> dotnet test
Unhandled exception: One or more errors occurred. (Unable to proceed with project '{removed-path}\tests\SharedTestingFramework\SharedTestingFramework.csproj'.
Ensure you have a runnable project type.
A runnable project should target a runnable TFM (for instance, net10.0) and have OutputType 'Exe'.
The current OutputType is 'Library'.)
Contribution
Problem Statement
When a shared testing library references TUnit.Core (e.g., to provide an IAsyncInitializer implementations shared across multiple test assemblies), it is always treated by TUnit as a test assembly solely because it references TUnit types. This happens even if the assembly is purely infrastructure, containing no tests of its own. There is no way to instruct TUnit to ignore such assemblies during discovery, leading to unnecessary scanning, possible confusion, and performance overhead in solutions with many shared libraries.
Proposed Solution
Introduce an assembly-level attribute in TUnit.Core (such as [assembly: ExcludeFromTestDiscovery] or [assembly: DoNotScan]) that can be placed in shared libraries to indicate that TUnit should skip scanning them for test methods/classes.
Upon detecting this attribute in an assembly's metadata, both reflection-based and source-generated discovery engines should skip it.
This would require updates to the assembly filtering code in:
Alternatives Considered
dotnet testas, in this case, theSharedTestingFrameworkassembly is a Library, not an Exe causing a failure.None are as direct or maintainable as a simple explicit opt-out.
Feature Category
Test Discovery / Attributes
How important is this feature to you?
Important - significantly impacts my workflow
Additional Context
Example use-case:
IAsyncInitializer, or contains TUnit.Core base types, but has no test classes or test methods ([Test]).Relevant files for change:
Failure:
Contribution