Skip to content

Enable NativeAOT support for iOS test runner#1554

Merged
kotlarmilos merged 1 commit intodotnet:mainfrom
kotlarmilos:enable-nativeaot-mobile-library-tests
Mar 12, 2026
Merged

Enable NativeAOT support for iOS test runner#1554
kotlarmilos merged 1 commit intodotnet:mainfrom
kotlarmilos:enable-nativeaot-mobile-library-tests

Conversation

@kotlarmilos
Copy link
Member

@kotlarmilos kotlarmilos commented Mar 11, 2026

Description

Make ThreadlessXunitTestRunner platform-agnostic and add NativeAOT case to iOSApplicationEntryPoint. The runner uses reflection-based test discovery (ThreadlessXunitDiscoverer) which is NativeAOT-compatible, unlike XUnitTestRunner which depends on XunitFrontController for dynamic assembly loading. WriteResultsToFile is refactored to support file-based xml output on non-browser platforms while preserving existing wasm behavior.

Fixes dotnet/runtime#91871

Make ThreadlessXunitTestRunner platform-generic so it can be used on
iOS/tvOS/Mac Catalyst in addition to WASM. The runner uses reflection-based
test discovery (ThreadlessXunitDiscoverer) which is NativeAOT-compatible,
unlike XUnitTestRunner which depends on XunitFrontController for dynamic
assembly loading.

Changes:
- ThreadlessXunitTestRunner: make ResultsFileName settable, refactor
  WriteResultsToFile to support file-based XML output on non-browser
  platforms while preserving existing WASM behavior
- iOSApplicationEntryPoint: detect NativeAOT via
  RuntimeFeature.IsDynamicCodeSupported and automatically use
  ThreadlessXunitTestRunner when dynamic code is not available

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Member

@matouskozak matouskozak left a comment

Choose a reason for hiding this comment

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

LGTM!

I wonder, should we add a NativeAOT test app to the set of apps we're testing so that we can validate it here? I think we also miss coverage over the regular runtime test apps as we only test libraries in xharness.

@kotlarmilos
Copy link
Member Author

Yes, adding a NAOT test makes sense. The regular runtime test shouldn't differ from the library tests we already have in the CI. Created a tracking issue to add a NAOT test once we standup the runtime jobs and retrieve an app bundle.

@kotlarmilos kotlarmilos merged commit 8fc29af into dotnet:main Mar 12, 2026
17 checks passed
@akoeplinger
Copy link
Member

akoeplinger commented Mar 12, 2026

The downside of the ThreadlessXunitTestRunner is that it will only run one test at a time, but you do have threads with NativeAOT. I think you could extract just the pieces that do reflection-based test discovery into a new runner.

kotlarmilos added a commit to kotlarmilos/xharness that referenced this pull request Mar 13, 2026
Introduce NativeAotXunitTestRunner that extends ThreadlessXunitTestRunner
with parallel test execution support and file-based result output.
ThreadlessXunitTestRunner uses reflection-based discovery (NativeAOT-safe)
but forces single-threaded execution. The new runner overrides the
configuration to allow parallel test collections since NativeAOT has
threads available.

- Add NativeAotXunitTestRunner extending ThreadlessXunitTestRunner with
  configurable MaxParallelThreads and ParallelizeTestCollections
- Extract virtual CreateConfiguration() and RunnerDisplayName from
  ThreadlessXunitTestRunner for extensibility
- Revert PR dotnet#1554 changes to ThreadlessXunitTestRunner, keeping it
  WASM-only as originally intended
- Update iOS and Android entry points to use NativeAotXunitTestRunner
  when RuntimeFeature.IsDynamicCodeSupported is false

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 17, 2026
* Add NativeAOT xunit test runner with threaded execution

Introduce NativeAotXunitTestRunner that extends ThreadlessXunitTestRunner
with parallel test execution support and file-based result output.
ThreadlessXunitTestRunner uses reflection-based discovery (NativeAOT-safe)
but forces single-threaded execution. The new runner overrides the
configuration to allow parallel test collections since NativeAOT has
threads available.

- Add NativeAotXunitTestRunner extending ThreadlessXunitTestRunner with
  configurable MaxParallelThreads and ParallelizeTestCollections
- Extract virtual CreateConfiguration() and RunnerDisplayName from
  ThreadlessXunitTestRunner for extensibility
- Revert PR #1554 changes to ThreadlessXunitTestRunner, keeping it
  WASM-only as originally intended
- Update iOS and Android entry points to use NativeAotXunitTestRunner
  when RuntimeFeature.IsDynamicCodeSupported is false

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

* Refactor: extract CustomXunitTestRunner abstract base, rename to ReflectionBasedXunitTestRunner

Address review feedback:
- Rename NativeAotXunitTestRunner to ReflectionBasedXunitTestRunner
- Extract shared reflection-based discovery logic into abstract
  CustomXunitTestRunner base class
- Make ThreadlessXunitTestRunner and ReflectionBasedXunitTestRunner
  concrete implementations of CustomXunitTestRunner

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apple iOS/tvOS/WatchOS/Mac Catalyst area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[infra] Implement XHarness test discovery/running without the XunitFrontController

3 participants