Xcode MCP: RunAllTests runs the previously active test plan's target selection after XcodeSwitchTestPlan

Status Closed — not planned
Maintainer reply None cached
Activity 1 comment · opened Sep 26, 2026 · closed Oct 12, 2026

Summary

mcp__xcode__RunAllTests can execute the previously active test plan's target selection instead of the currently active one, even though mcp__xcode__XcodeListTestPlans correctly reports the new plan as active. mcp__xcode__RunSomeTests (explicit {targetName, testIdentifier} list) does not have this problem and reliably runs against the active plan/destination.

Setup

  • An Xcode project/scheme with two .xctestplan files, each enabling a different unit-test target and disabling the other, e.g.:
  • PlanA.xctestplan: target UnitTestsA enabled, target UnitTestsB disabled
  • PlanB.xctestplan: target UnitTestsB enabled, target UnitTestsA disabled
  • Both plans registered on the scheme's TestPlans list (.xcscheme).

Repro steps

  1. XcodeSwitchTestPlan(testPlanName: "PlanA") — active plan is PlanA.
  2. RunAllTests — runs UnitTestsA only, as expected.
  3. XcodeSwitchTestPlan(testPlanName: "PlanB") — tool reports activeTestPlanName: "PlanB".
  4. XcodeListTestPlans — confirms PlanB is active (isActive: true), PlanA is not.
  5. RunAllTests — top-level result still says activeTestPlanName: "PlanB", but the actual test run executes UnitTestsA's tests (all "Passed") and reports every UnitTestsB test as "No result" — the inverse of what the active plan specifies.
  6. The console log for that run (fullConsoleLogsPath) shows only one app install/launch, for the host app running UnitTestsA's bundle — UnitTestsB's bundle is never launched, only mentioned in the trailing code-coverage summary ("Generating entry for target UnitTestsB.xctest" with "Skipped N file(s) with no executable lines").

Expected

RunAllTests should run whatever GetTestList/XcodeListTestPlans reports as the active plan's enabled tests — i.e. UnitTestsB in step 5.

Actual

RunAllTests silently ran the stale, previously-active plan's target selection. No error was surfaced; the result shape looks identical to a normal successful run (real Pass/Fail states for the tests that did run), so this is easy to miss — the only tell is that the "wrong" target's tests passed and the "right" target's tests all show "No result".

Workaround found

Calling RunSomeTests with an explicit list of {targetName: "UnitTestsB", testIdentifier: "..."} pairs (enumerated from GetTestList while PlanB is active) runs the correct tests every time, with real results — this suggests the destination/build-for-testing itself is fine and the bug is specifically in how RunAllTests resolves "the active plan's selection" right after a plan switch (looks like a stale cache of the previous plan's derived -only-testing/-skip-testing argument list).

Impact

Anyone scripting "switch plan → run all tests" (e.g. to separate simulator-safe tests from device-only tests across two plans on the same scheme) gets silently wrong results — tests that should be skipped report as passed (from the old plan), and tests that should run report as not run, with no indication anything went wrong. Re-running RunAllTests a second time after the switch, or using RunSomeTests with explicit identifiers, both work around it.

Environment

  • Claude Code desktop app, built-in Xcode MCP tools (mcp__xcode__*)
  • Xcode with a multi-test-plan scheme (this repro used 3 plans total, only 2 involved in the switch)
  • Reproduced against both a Simulator destination and a physical device destination

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗