Skip to content

Conversation

@glennawatson
Copy link
Contributor

@glennawatson glennawatson commented Jan 17, 2026

What kind of change does this PR introduce?
Refactoring - Test infrastructure improvement and bug fixes

What is the current behavior?
Tests used scope-based patterns with manual Before/After hooks (WpfAppBuilderScope, MauiTestFixture, DispatcherSchedulerScope) requiring boilerplate setup/teardown code in each test class. Some tests had intermittent failures due to:

  • DynamicData ToObservableChangeSet().Bind() race conditions in scheduler tests
  • Missing ImmediateScheduler.Instance in some RoutingState constructors causing async hangs
  • Incorrect observable subscription handling in navigation tests

What is the new behavior?
Tests use declarative executor pattern with [TestExecutor<T>] attributes, centralizing setup logic and eliminating boilerplate:

Test Infrastructure Changes:

  • Created MauiTestExecutor for MAUI test isolation with dispatcher setup
  • Created SuspensionHostTestExecutor for managing static state in suspension tests
  • Deleted obsolete scope classes: WpfAppBuilderScope, MauiTestFixture (2 files), DispatcherSchedulerScope
  • Migrated 34 test files to executor pattern (21 WPF, 12 MAUI, 1 suspension test)

Bug Fixes:

  • Fixed SchedulerIsUsedForAllCommands intermittent failure by removing ToObservableChangeSet() race conditions
  • Fixed all RoutingState constructors to use ImmediateScheduler.Instance preventing test hangs
  • Fixed NavigationPushPopTest bug that compared subscription object instead of view model
  • Fixed RoutingStateThrows to properly handle ReactiveCommand exceptions via ThrownExceptions
  • Removed all DynamicData usage from RoutingStateTests.cs to eliminate scheduling issues

Results:

  • 43 files changed: 239 insertions(+), 1,002 deletions(-)
  • All 6,155 tests passing reliably across all frameworks (net8.0, net9.0, net10.0)
  • Zero intermittent failures

What might this PR break?
No breaking changes - purely internal test infrastructure improvements. All tests remain functionally equivalent with the same coverage.

Please check if the PR fulfills these requirements

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features) - N/A, internal test changes only

Other information:
This refactoring improves test maintainability by:

  • Eliminating 1,002 lines of boilerplate setup/teardown code
  • Centralizing platform-specific configuration in reusable executors
  • Preventing state leakage between tests through proper lifecycle management
  • Making tests more declarative and easier to understand

Co-authored-by: Christian Fischerauer [email protected]

- Removed WpfAppBuilderScope, MauiTestFixture, and DispatcherSchedulerScope
- Migrated 34 test files to use declarative executor pattern
- Created MauiTestExecutor for MAUI test isolation
- Created SuspensionHostTestExecutor for static state management
- Fixed RoutingState constructor to use ImmediateScheduler.Instance in all tests
- Fixed NavigationPushPopTest bug comparing subscription instead of view model
- Fixed RoutingStateThrows test to properly handle ReactiveCommand exceptions
- All 6,135 tests passing (intermittent net10.0 test runner infrastructure issue)
…cData

- Simplified SchedulerIsUsedForAllCommands to check NavigationStack directly instead of using ToObservableChangeSet bindings
- Removed all DynamicData usage from RoutingStateTests.cs to eliminate scheduling race conditions
- Replaced ToObservableChangeSet().Bind() with simple List<> subscriptions in CurrentViewModel tests
- Removed unused DynamicData bindings from RoutingStateThrows test
- All 6,155 tests now passing reliably across all frameworks
Copy link
Contributor

Copilot AI left a 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 refactors the test infrastructure by migrating from manual scope-based test patterns (using [Before(Test)]/[After(Test)] hooks) to a declarative executor pattern using [TestExecutor<T>] attributes. This modernization eliminates 1,002 lines of boilerplate setup/teardown code while centralizing platform-specific configuration in reusable executors.

Changes:

  • Created MauiTestExecutor and SuspensionHostTestExecutor for centralized test isolation with proper state management
  • Deleted 4 obsolete scope/fixture classes: WpfAppBuilderScope, DispatcherSchedulerScope, and 2 MauiTestFixture files
  • Migrated 34 test files to executor pattern (21 WPF, 12 MAUI, 1 suspension test) with removal of 1,000+ lines of boilerplate
  • Fixed critical bugs in RoutingStateTests.cs: removed DynamicData race conditions, fixed navigation test assertions, proper ReactiveCommand exception handling, and added explicit schedulers to all RoutingState constructors
  • Updated project files with proper references and using directives for MAUI test projects

Reviewed changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
MauiTestExecutor.cs New executor providing MAUI dispatcher isolation and cleanup
SuspensionHostTestExecutor.cs New executor managing static state in SuspensionHostExtensions
WpfAppBuilderScope.cs Deleted - functionality moved to WpfTestExecutor
DispatcherSchedulerScope.cs Deleted - functionality integrated into WpfTestExecutor
MauiTestFixture.cs (2 files) Deleted - replaced with MauiTestExecutor
RoutingStateTests.cs Fixed race conditions, navigation bugs, and added explicit schedulers
RoutedViewHostTests.cs Removed [Skip] attributes, added inline WpfWithViewAndRoutingExecutor
XamlViewCommandTests.cs and 19 other WPF test files Migrated to WpfTestExecutor pattern, removed boilerplate
11 MAUI test files Migrated to MauiTestExecutor pattern, removed boilerplate
SuspensionHostExtensionsTests.cs Migrated to SuspensionHostTestExecutor pattern
WinFormsViewModelViewHostTests.cs Added TearDown to reset static state
ReactiveUI.Maui.Tests.csproj Added TUnit using directives
ReactiveUI.Builder.Maui.Tests.csproj Added project reference to ReactiveUI.Maui.Tests and using directives

- Fixed RoutedViewHostTests.cs (WPF) missing scheduler parameter
- Fixed WinFormsRoutedViewHostTests.cs (3 instances) missing scheduler parameter
- Fixed AdvancedAOTTests.cs missing scheduler parameter
- Ensures all test RoutingState instances execute synchronously preventing async hangs
- All 6,155 tests passing
@glennawatson glennawatson enabled auto-merge (squash) January 17, 2026 17:56
@glennawatson glennawatson disabled auto-merge January 17, 2026 18:13
@glennawatson glennawatson merged commit 68903f2 into main Jan 17, 2026
4 checks passed
@glennawatson glennawatson deleted the glennawatson/migrate-to-executor-tests branch January 17, 2026 18:13
@codecov
Copy link

codecov bot commented Jan 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.70%. Comparing base (e20db9e) to head (5fc021a).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4271      +/-   ##
==========================================
+ Coverage   78.23%   78.70%   +0.47%     
==========================================
  Files         248      248              
  Lines        9552     9552              
  Branches     1459     1459              
==========================================
+ Hits         7473     7518      +45     
+ Misses       1839     1792      -47     
- Partials      240      242       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to 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.

2 participants