stride3d/stride · error · InvalidOperationException
[UITest] class must implement IUITest.
Error message
[UITest] class {chosen.FullName} must implement IUITest. What it means
After choosing the [UITest] class, LoadTest verifies it implements IUITest. If the annotated class does not implement the interface, it throws InvalidOperationException with the class's full name. The attribute alone is not sufficient; the type must be instantiable as an IUITest to be run.
Solutions
- Make the annotated class implement IUITest and rebuild.
- Remove [UITest] from classes that are not actual runnable tests.
- Point --test-name at the correct test class instead of the mis-annotated one.
- Add a compile-time check (e.g. where T : IUITest pattern or unit test asserting all [UITest] types implement IUITest).
Example fix
// before
[UITest]
public class SmokeTest { public void Run(Context ctx) { ... } }
// after
[UITest]
public class SmokeTest : IUITest { public void Run(Context ctx) { ... } } Defensive patterns
Strategy: validation
Validate before calling
var bad = asm.GetTypes()
.Where(t => t.GetCustomAttribute<UITestAttribute>() is not null && !typeof(IUITest).IsAssignableFrom(t))
.ToList();
if (bad.Count > 0) throw new InvalidOperationException($"[UITest] types not implementing IUITest: {string.Join(", ", bad.Select(t => t.FullName))}"); Try / catch
try { test = LoadTest(dll, testName); }
catch (InvalidOperationException ex) { Console.Error.WriteLine(ex.Message); return 1; } Prevention
- Always derive test classes from IUITest
- Never put [UITest] on non-test classes
- Add a unit test asserting attribute/interface consistency
When it happens
Trigger: Annotating a class with [UITest] that does not implement IUITest (interface dropped during refactor, or attribute applied to a helper/model class by mistake).
Common situations: Renaming or refactoring removed the IUITest base; a developer copies [UITest] onto the wrong class; a partial implementation class only satisfies the interface in another assembly.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- No [UITest] class found in
- No [UITest] class named
- Multiple [UITest] classes in
- The assetUpgraderType must implement IAssetUpgrader…
- compilationContext should inherit from ICompilationContext
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/3dfaf47ea6153758.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.GameStudio.AutoTesting/UITestHost.cs:174
throw new InvalidOperationException($"No [UITest] class found in '{testDllPath}'.");
Type chosen;
if (testClassName is not null)
{
chosen = candidates.FirstOrDefault(t => t.Name == testClassName || t.FullName == testClassName)
?? throw new InvalidOperationException($"No [UITest] class named '{testClassName}' in '{testDllPath}'. Available: {string.Join(", ", candidates.Select(t => t.FullName))}");
}
else if (candidates.Count == 1)
{
chosen = candidates[0];
}
else
{
throw new InvalidOperationException($"Multiple [UITest] classes in '{testDllPath}'; pass --test-name to select. Available: {string.Join(", ", candidates.Select(t => t.FullName))}");
}
if (!typeof(IUITest).IsAssignableFrom(chosen))
throw new InvalidOperationException($"[UITest] class {chosen.FullName} must implement IUITest.");
return (IUITest)Activator.CreateInstance(chosen)!;
}
private void RunTest(IUITest test, Context ctx)
{
Task.Run(async () =>
{
var status = "ok";
object? exceptionInfo = null;
try
{
await test.Run(ctx);
}
catch (Exception ex)
{
status = "error";
exceptionInfo = SerializeException(ex);View on GitHub (pinned to 96fad776d2)