dotnet/maui · error · Exception
No test assembly found.
Error message
No test assembly found.
What it means
Thrown by GetTestCategories when reflection-loading a DeviceTests DLL (Controls or Core) fails for every candidate path found via GetFiles. The loop at line 204 swallows each Assembly.LoadFrom failure into a Warning, so this throw fires only when zero assemblies loaded successfully — meaning the build that should have produced Microsoft.Maui.Controls.DeviceTests.dll or Microsoft.Maui.Core.DeviceTests.dll never ran, or its output landed outside the searched ../../** glob.
Source
Thrown at eng/devices/devices-shared.cake:220
System.Reflection.Assembly loadedAssembly = null;
foreach (var filePath in dllFilePath)
{
try
{
loadedAssembly = System.Reflection.Assembly.LoadFrom(filePath.FullPath);
Information($"Loaded assembly from {filePath}: {loadedAssembly.FullName}");
break; // Exit the loop if the assembly is loaded successfully
}
catch (Exception ex)
{
Warning($"Failed to load assembly from {filePath}: {ex.Message}");
}
}
if (loadedAssembly == null)
{
throw new Exception("No test assembly found.");
}
var testCategoryType = loadedAssembly.GetType("Microsoft.Maui.DeviceTests.TestCategory");
var values = new List<string>();
foreach (var field in testCategoryType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
{
if (field.FieldType == typeof(string))
{
values.Add($"Category={(string)field.GetValue(null)}");
}
}
return values.ToList();
}
void HandleTestResults(string resultsDir, bool testsFailed, bool needsNameFix, string suffix = null)
{View on GitHub (pinned to f377ff1c5e)
Solutions
- Run the build target first (dotnet cake build.cake --target=build) so the DeviceTests DLL exists under artifacts/bin before invoking GetTestCategories.
- Check the Warning lines immediately before the throw — they list each attempted path and the LoadFrom exception, which identifies whether the issue is a missing file or a load failure.
- Confirm projectPath ends in Controls.DeviceTests.csproj or Core.DeviceTests.csproj; other project names return early with an empty list and never reach this code, so a wrong path means the glob at line 196/200 returns nothing.
- If the DLL exists but LoadFrom throws BadImageFormatException, verify the build TFM/architecture matches the host process (e.g. a net*-ios DLL cannot be LoadFrom'd on a Windows host).
Example fix
// before: glob may miss the output when the build used a non-default configuration
dllFilePath = GetFiles($"{directoryPath}/../../**/Microsoft.Maui.Controls.DeviceTests.dll").ToList();
// after: fall back to the known arcade bin layout and log when empty
dllFilePath = GetFiles($"{directoryPath}/../../**/Microsoft.Maui.Controls.DeviceTests.dll").ToList();
if (dllFilePath == null || dllFilePath.Count == 0)
{
var arcade = MakeAbsolute(new DirectoryPath($"../../artifacts/bin/Controls.DeviceTests/{configuration}"));
dllFilePath = GetFiles($"{arcade.FullPath}/**/Microsoft.Maui.Controls.DeviceTests.dll").ToList();
}
if (dllFilePath.Count == 0)
throw new Exception($"No test assembly found under {directoryPath}/../../** ; build the project first."); Defensive patterns
Strategy: validation
Validate before calling
// Before calling GetTestCategories, confirm the DLL exists for the project
var expectedDll = projectPath.EndsWith("Controls.DeviceTests.csproj")
? "Microsoft.Maui.Controls.DeviceTests.dll"
: "Microsoft.Maui.Core.DeviceTests.dll";
var found = GetFiles($"{Context.GetCallerInfo().SourceFilePath.GetDirectory()}/../../**/{expectedDll}");
if (found == null || !found.Any())
throw new Exception($"Build the {expectedDll} project before requesting test categories."); Prevention
- Always run the build target before the test target so DeviceTests DLLs exist.
- Treat a clean of artifacts/bin as requiring a rebuild before invoking GetTestCategories.
- Log the searched glob path and the count of matches before the LoadFrom loop so an empty result is obvious.
When it happens
Trigger: Calling GetTestCategories with a Controls.DeviceTests.csproj or Core.DeviceTests.csproj path before the test project has been built; building into a configuration/TFM whose bin folder the ../../** glob does not reach; a stale or deleted artifacts/bin tree after a clean; the DLL existing but being unloadable (locked, wrong architecture, corrupt) so every LoadFrom throws.
Common situations: Running the 'test' target without first running 'build'; switching DotnetVersion/target framework so the DLL is emitted under a new folder not matched by the glob; a clean/git-clean wiping artifacts/bin; running locally on Windows where the DLL is locked by a prior test runner process; CI caching an old artifacts dir.
Related errors
- No test results found.
- UI Test application path not specified.
- Error: Couldn't find .cer or .msix file
- No test result files found. All test processes may have cras
- Some test categories failed to complete: {string.Join(", ",
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/c6302fb6fc0f986b.
Report an issue: GitHub.