-
-
Notifications
You must be signed in to change notification settings - Fork 105
feat: add IAsyncDiscoveryInitializer for asynchronous initialization during test discovery #4000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…during test discovery
Pull Request Review: IAsyncDiscoveryInitializer FeatureThank you for this PR! I've reviewed the implementation and have the following feedback: ✅ Strengths
🔍 Critical Issue: Dual-Mode ImplementationAccording to CLAUDE.md Rule 1 (Mandatory), ALL changes must work identically in both execution modes:
Impact: This feature will only work in reflection mode. Users relying on source-generated tests will not have access to Required Action:
📋 Additional Observations1. Performance ConsiderationThe loop in 2. Code Style
3. Test DesignThe test in
Minor suggestion: Consider adding a test that verifies the object is NOT initialized during discovery if it only implements 🎯 RecommendationsBefore merging:
📊 Overall AssessmentQuality: High ✅ The reflection-mode implementation is excellent, but the missing source-generated mode support makes this feature incomplete per TUnit's architecture requirements. Once dual-mode support is added, this will be a valuable addition to TUnit! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a new IAsyncDiscoveryInitializer interface that enables asynchronous initialization of data sources during test discovery, allowing fixtures like Docker containers or database connections to be initialized before test case enumeration.
Key Changes:
- New
IAsyncDiscoveryInitializerinterface extendingIAsyncInitializerfor discovery-time initialization - Engine support in
TestBuilder.csto initialize discovery initializers before evaluating method data sources - Integration test demonstrating the feature with a simulated container scenario
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| TUnit.Core/Interfaces/IAsyncDiscoveryInitializer.cs | New marker interface extending IAsyncInitializer with comprehensive documentation explaining discovery-time vs execution-time initialization |
| TUnit.Engine/Building/TestBuilder.cs | Adds InitializeDiscoveryObjectsAsync method called during test building to initialize IAsyncDiscoveryInitializer objects before method data sources are evaluated |
| TUnit.TestProject/Bugs/3997/Tests.cs | Integration test with SimulatedContainer demonstrating that discovery initializers are called before InstanceMethodDataSource accesses container data |
| TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.*.verified.txt | Updated public API snapshots for all .NET target frameworks (.NET 4.7, 8.0, 9.0, 10.0) reflecting the new interface addition |
| foreach (var data in classData) | ||
| { | ||
| if (data is IAsyncDiscoveryInitializer && data is not IDataSourceAttribute) | ||
| { | ||
| // Uses ObjectInitializer which handles deduplication. | ||
| // This also prevents double-init during execution since ObjectInitializer | ||
| // tracks initialized objects. | ||
| await ObjectInitializer.InitializeAsync(data); | ||
| } | ||
| } |
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.
Pull Request ReviewThank you for implementing IAsyncDiscoveryInitializer! This is a well-documented feature that solves a real problem. However, I have identified a critical issue that must be addressed before merging. CRITICAL ISSUE: Dual-Mode Implementation ViolationProblem: This PR only implements the feature in reflection mode (TUnit.Engine) but is missing the source-generated mode implementation (TUnit.Core.SourceGenerator). According to CLAUDE.md Rule 1:
Evidence:
Impact:Users relying on source-generated mode will not get IAsyncDiscoveryInitializer initialization during discovery, causing:
Required Action:
Positive AspectsExcellent Documentation
Good Test Coverage
Clean Implementation
Additional Recommendations1. Performance (Minor)The InitializeDiscoveryObjectsAsync method iterates through all class data and type-checks each object. This is in a hot path. While impact is likely minimal, consider profiling with large test suites. 2. Test CoverageConsider adding:
3. Security & Safety
VerdictStatus: Requires Changes (Critical: Missing dual-mode implementation) The reflection mode implementation is excellent, but without source-gen mode parity, this feature is incomplete per TUnit architecture requirements. Once source-gen support is added and tested, this will be a valuable addition. Great work on documentation and test coverage! The implementation quality is high - it just needs to be complete across both execution modes. Reviewed by: Claude Code (Sonnet 4.5) |
No description provided.