{"record":{"id":"4d45f8fd08496507","repo":"stride3d/stride","slug":"multiple-uitest-classes-in-testdllpath-pass-test-name-to","errorCode":null,"errorMessage":"Multiple [UITest] classes in '{testDllPath}'; pass --test-name to select. Available: {string.Join(\", \", candidates.Select(t => t.FullName))}","messagePattern":"Multiple \\[UITest\\] classes in '(.+?)'; pass --test-name to select\\. Available: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.GameStudio.AutoTesting/UITestHost.cs","lineNumber":170,"sourceCode":"        var candidates = asm.GetTypes()\n            .Where(t => t.GetCustomAttribute<UITestAttribute>() is not null)\n            .ToList();\n        if (candidates.Count == 0)\n            throw new InvalidOperationException($\"No [UITest] class found in '{testDllPath}'.\");\n\n        Type chosen;\n        if (testClassName is not null)\n        {\n            chosen = candidates.FirstOrDefault(t => t.Name == testClassName || t.FullName == testClassName)\n                ?? throw new InvalidOperationException($\"No [UITest] class named '{testClassName}' in '{testDllPath}'. Available: {string.Join(\", \", candidates.Select(t => t.FullName))}\");\n        }\n        else if (candidates.Count == 1)\n        {\n            chosen = candidates[0];\n        }\n        else\n        {\n            throw new InvalidOperationException($\"Multiple [UITest] classes in '{testDllPath}'; pass --test-name to select. Available: {string.Join(\", \", candidates.Select(t => t.FullName))}\");\n        }\n\n        if (!typeof(IUITest).IsAssignableFrom(chosen))\n            throw new InvalidOperationException($\"[UITest] class {chosen.FullName} must implement IUITest.\");\n\n        return (IUITest)Activator.CreateInstance(chosen)!;\n    }\n\n    private void RunTest(IUITest test, Context ctx)\n    {\n        Task.Run(async () =>\n        {\n            var status = \"ok\";\n            object? exceptionInfo = null;\n            try\n            {\n                await test.Run(ctx);\n            }","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.GameStudio.AutoTesting/UITestHost.cs#L152-L188","documentation":"When no --test-name is supplied, LoadTest auto-selects the single [UITest] class in the DLL. If the DLL contains multiple annotated classes, it throws InvalidOperationException telling the user to pass --test-name and listing the available classes. Ambiguity must be resolved explicitly.","triggerScenarios":"Running the host with a test DLL containing two or more [UITest] classes and omitting --test-name.","commonSituations":"Accumulating several UI test classes in one test project over time while the launch command still predates the second test; CI jobs that only ever ran one test.","solutions":["Add --test-name <ClassName> to the launch command specifying which test to run.","Split tests into separate DLLs if you want each to be auto-selected.","Remove or mark obsolete the tests you no longer intend to run.","Update the CI/launch script to select the test explicitly."],"exampleFix":"// before\nStride.GameStudio.AutoTesting.exe --test-dll MyTests.dll\n// after\nStride.GameStudio.AutoTesting.exe --test-dll MyTests.dll --test-name SmokeTest","handlingStrategy":"validation","validationCode":"var count = asm.GetTypes().Count(t => t.GetCustomAttribute<UITestAttribute>() is not null);\nif (count > 1 && testName is null)\n    throw new InvalidOperationException(\"Multiple [UITest] classes: --test-name is required\");","typeGuard":null,"tryCatchPattern":"try { test = LoadTest(dll, testName); }\ncatch (InvalidOperationException) { testName = PromptForTestName(); test = LoadTest(dll, testName); }","preventionTips":["Always pass --test-name once a project has 2+ tests","Keep one test class per DLL for auto-selection","Prune obsolete test classes"],"tags":["testing","cli-argument","uitest"],"backgroundTag":"missing-cli-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}