Skip to content

MSTest throws NotSupportedException when Assembly.Location returns empty string (Android CoreCLR) #7769

@simonrozsival

Description

@simonrozsival

Description

MSTest throws NotSupportedException when Assembly.Location returns an empty string. This happens on .NET for Android when using the CoreCLR runtime, where assemblies are
memory-mapped and don't have a file-backed location.

We discovered this issue when switching the default runtime from MonoVM to CoreCLR in Debug builds in dotnet/android#11169

Steps To Reproduce

  1. Create an Android instrumented test project using MSTest with EnableMSTestRunner=true
  2. Use the Microsoft Testing Platform API to run tests:
    var builder = await TestApplication.CreateBuilderAsync(args);
    builder.AddMSTest(() => [GetType().Assembly]);
    using ITestApplication app = await builder.BuildAsync();
    await app.RunAsync();
  3. Run the app on an Android device/emulator using the CoreCLR runtime (not MonoVM)

Expected behavior

Tests are discovered and executed normally, regardless of what Assembly.Location returns.

Actual behavior

MSTest throws:

 System.NotSupportedException: Running tests in any of the provided sources is not supported for the selected platform

Root Cause

The failure chain is:

  1. SynchronizedSingleSessionVSTestBridgedTestFramework.ExecuteRequestAsync calls: _getTestAssemblies().Select(x => x.Location).ToArray()
  2. MSTestDiscovererHelpers.AreValidSources() validates that each source path ends with .dll or .exe (via TestSourceHost.ValidSourceExtensions)
  3. On CoreCLR Android, Assembly.Location returns "" for assemblies loaded from memory-mapped data (via the custom assembly load hook clr_external_assembly_probe)
  4. The empty string fails the .dll/.exe extension check → NotSupportedException

This works with MonoVM because Mono resolves Assembly.Location to a file path even for memory-mapped assemblies. CoreCLR does not.

Suggested Fix

AreValidSources (or the code that calls it) should handle the case where Assembly.Location returns an empty string. When assemblies are provided directly via builder.AddMSTest(() => [assembly]), the framework already has the Assembly reference and should not need a valid file path to discover and run tests.

Workaround

In dotnet/android app, we can set <EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk> in the project file. This embeds assemblies inside the APK so they are extracted to disk at runtime, making Assembly.Location
return a valid path. This disables fast-deploy, so incremental deployment is significantly slower (unusable for day-to-day dev experience).

Environment

  • MSTest 4.1.0
  • .NET for Android (net11.0-android)
  • CoreCLR runtime on Android (arm64-v8a)
  • Android API 36

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions