What changed
- Keep explicit
tuist test --scheme ... behavior unchanged.
- For default
tuist test runs, continue using the autogenerated workspace scheme unless that workspace scheme contains host-less unit test bundles.
- When host-less unit tests are present, run the generated project test schemes that cover the workspace scheme’s test targets instead of running the mixed workspace aggregate.
- Filter
--test-targets and --skip-test-targets per split scheme so a request for FeatureTests does not accidentally run AppTests.
- Preserve the existing selective-testing behavior that skips generated schemes with no remaining test-action targets.
Why
This fixes the behavior reported in Tuist test runs host-less module unit tests in the app launch context - xctest crashes at bootstrap.
The community repro has one app-hosted test bundle and one host-less framework test bundle in the autogenerated Sample-Workspace scheme. With Xcode 26.5, the aggregate scheme builds both bundles, runs the app-hosted test, then crashes while bootstrapping the host-less FeatureTests bundle:
Early unexpected exit, operation never finished bootstrapping - no restart will be attempted. (Underlying Error: The test runner crashed while preparing to run tests: xctest at <external symbol>)
I first tried making the workspace scheme use a host-less module as macro expansion / launch context, but the sample still crashed in the aggregate run. The passing path is the one Xcode already handles correctly: run the generated project schemes separately (App, then Feature) instead of mixing app-hosted and host-less bundles in the workspace aggregate.
Validation
swiftformat 0.58.7 on the touched Swift files.
swiftlint 0.59.1 lint --no-cache on the touched source files: exited 0. It still reports existing warnings for large functions / legacy disables in these files.
git diff --check
- Xcode 26.5 (
17F42) unit coverage:
xcodebuild test -workspace Tuist.xcworkspace -scheme TuistUnitTests -only-testing:TuistKitTests/TestServiceTests/test_run_tests_when_part_is_cached -only-testing:TuistKitTests/TestServiceTests/test_run_filters_test_targets_not_in_scheme -only-testing:TuistKitTests/TestServiceTests/test_run_skips_xcodebuild_when_all_requested_test_targets_are_pruned_from_scheme -only-testing:TuistKitTests/TestServiceTests/test_run_without_scheme_uses_project_schemes_when_workspace_scheme_contains_hostless_unit_tests -only-testing:TuistKitTests/TestServiceTests/test_run_tests_all_project_schemes -only-testing:TuistKitTests/TestServiceTests/test_run_build_infersSimulatorDestinationForSuiteShardPlanning CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY=
xcodebuild test -workspace Tuist.xcworkspace -scheme TuistUnitTests -only-testing:TuistKitTests/TestServiceTests CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY=
- Xcode 26.5 (
17F42) e2e sample verification on iPhone 17 Pro iOS 26.5 simulator (4A6DAF88-CBE5-4391-8DB5-0FA655B68F59):
- Regenerated
/private/tmp/tuist-hostless-test-repro/tuist-hostless-test-repro with Tuist 4.198.1.
xcodebuild test -scheme Sample-Workspace: failed, passedTests=1, failedTests=1, failure target FeatureTests, matching the xctest bootstrap crash.
xcodebuild test -scheme App: passed, passedTests=1, failedTests=0.
xcodebuild test -scheme Feature: passed, passedTests=1, failedTests=0.