flowdeck test
Run unit and UI tests.
# After 'flowdeck init', run tests with saved settings
flowdeck test
# Run all tests (without init)
flowdeck test -w MyApp.xcworkspace -s MyScheme -S "iPhone 16"
# Run tests on macOS
flowdeck test -D "My Mac"
# Run specific tests with --only
flowdeck test --only MyTests/LoginTests
flowdeck test --only MyTests/LoginTests/testLogin
flowdeck test --only "MyTests/Login Tests/test Login Success"
# Skip specific tests
flowdeck test --skip MyTests/SlowTests
flowdeck test --skip MyTests/IntegrationTests
# Multiple test targets
flowdeck test --test-targets "UnitTests,IntegrationTests"
# Run a specific test plan (name or path)
flowdeck test --plan "Smoke"
flowdeck test --plan "TestPlans/Smoke.xctestplan"
# Output modes
flowdeck test # Summary only (default)
flowdeck test -v # Verbose xcodebuild output
flowdeck test --progress # Show pass/fail as tests complete
flowdeck test --streaming # Clean output for file capture
flowdeck test --json # JSON for CI/automation
# Pass arguments to xcodebuild
flowdeck test --xcodebuild-options='-parallel-testing-enabled YES'
flowdeck test --xcodebuild-options='-enableCodeCoverage YES'
flowdeck test --xcodebuild-options='-resultBundlePath /tmp/results.xcresult'
flowdeck test --xcodebuild-env='CI=true'
# Show usage examples
flowdeck test --examples
Options
| Option | Short | Description |
|---|
--examples | | Show usage examples |
--project <path> | -p | Project directory |
--workspace <path> | -w | Path to workspace (.xcworkspace) or project (.xcodeproj) |
--scheme <name> | -s | Scheme name |
--configuration <name> | -C | Build configuration (Debug/Release) |
--simulator <name> | -S | Simulator name/UDID (REQUIRED for iOS/tvOS/watchOS) |
--device <name> | -D | Device name/UDID (use “My Mac” for macOS) |
--derived-data-path <path> | -d | Derived data path (default: ~/Library/Developer/FlowDeck/DerivedData) |
--config <path> | -c | Path to JSON config file with project settings |
--test-targets <targets> | | Specific test targets to run (comma-separated) |
--test-cases <cases> | | Specific test cases to run (comma-separated, format: TargetName/ClassName/testMethod) |
--only <tests> | | Run only specific tests (format: TargetName/ClassName or TargetName/ClassName/testMethod) |
--skip <tests> | | Skip specific tests (format: TargetName/ClassName or TargetName/ClassName/testMethod) |
--plan <name-or-path> | | Test plan name or .xctestplan path |
--json | -j | Output as JSON |
--verbose | -v | Show raw xcodebuild test output (beautified) |
--progress | | Show test results as they complete (pass/fail per test) |
--streaming | | Stream clean formatted test results (no escape codes, for file capture) |
--xcodebuild-options <args> | | Extra xcodebuild arguments (e.g., --xcodebuild-options='-parallel-testing-enabled YES') |
--xcodebuild-env <vars> | | Xcodebuild environment variables (e.g., ‘CI=true’) |
After running flowdeck init, workspace, scheme, and simulator are saved to project state.
CLI parameters are only required if you haven’t initialized, or to override saved values.
Use --device "My Mac" for macOS builds.
Test Filtering
The --only option supports multiple formats:
- Full path:
MyAppTests/LoginTests/testValidLogin - runs a specific test method
- Class name:
LoginTests - runs all tests in that class
- Method name:
testValidLogin - runs all tests with that method name (across classes)
You can specify multiple tests by using --only multiple times or separating with commas.
The --config parameter accepts a JSON file with portable project settings:
{
"workspace": "MyApp.xcworkspace",
"scheme": "MyApp",
"configuration": "Debug",
"platform": "iOS",
"version": "18.0",
"derivedDataPath": "/custom/path"
}
For macOS builds, set platform to "macOS" (no simulator needed).
JSON Output
When using --json, the command outputs newline-delimited JSON events during execution, followed by a final test result:
{"type":"status","stage":"COMPILING","message":"Building for testing..."}
{"type":"status","stage":"TESTING","message":"Running tests on iPhone 16..."}
{"type":"test_started","testName":"LoginTests/testValidLogin"}
{"type":"test_passed","testName":"LoginTests/testValidLogin","duration":0.023}
{"type":"test_failed","testName":"LoginTests/testInvalidLogin","duration":0.045,"reason":"XCTAssertEqual failed","file":"LoginTests.swift","line":42}
{"type":"result","success":false,"operation":"test"}
Event Types:
| Type | Description |
|---|
status | Progress updates with stage and message |
test_started | Test execution started with testName |
test_passed | Test passed with testName and duration |
test_failed | Test failed with testName, duration, reason, file, line |
test_skipped | Test skipped with testName and optional reason |
result | Final result with success and operation |
Final Result (Success):
{
"success": true,
"totalTests": 42,
"passedTests": 42,
"failedTests": 0,
"skippedTests": 0,
"duration": 12.5,
"passedTestNames": ["LoginTests/testValidLogin", "..."],
"skippedTestNames": [],
"failures": []
}
Final Result (Failure):
{
"success": false,
"totalTests": 42,
"passedTests": 40,
"failedTests": 2,
"skippedTests": 0,
"duration": 15.3,
"passedTestNames": ["..."],
"skippedTestNames": [],
"failures": [
{
"testName": "LoginTests/testInvalidLogin",
"reason": "XCTAssertEqual failed: (\"expected\") is not equal to (\"actual\")",
"fileName": "LoginTests.swift",
"lineNumber": 42,
"duration": 0.045
}
]
}
flowdeck test discover
Discover all available tests in a project by parsing test source files. This uses static source analysis (like Xcode’s Test Navigator) and does not require building the project.
# After 'flowdeck init', discover tests with saved settings
flowdeck test discover
# Discover tests (without init)
flowdeck test discover -w MyApp.xcworkspace -s MyScheme
# Output as JSON (for tooling)
flowdeck test discover --json
# Filter tests by name
flowdeck test discover --filter Login
flowdeck test discover -F Login
# Include tests that are skipped in the scheme or test plan
flowdeck test discover --include-skipped-tests
Options
| Option | Short | Description |
|---|
--project <path> | -p | Project directory |
--workspace <path> | -w | Path to workspace (.xcworkspace) or project (.xcodeproj) (also accepts --ws) |
--scheme <name> | -s | Scheme name (also accepts --sch) |
--config <path> | -c | Path to JSON config file with project settings (also accepts --cfg) |
--filter <query> | -F | Filter tests by name (case-insensitive) |
--json | -j | Output as JSON |
--include-skipped-tests | | Include tests that are skipped in the scheme or test plan (marked as skipped) |
--examples | -e | Show usage examples |
Test discovery uses static source parsing and doesn’t require building. It finds XCTestCase subclasses, test* methods, @Suite structs, and @Test functions directly from source files. By default, tests that are disabled in the scheme or test plan are excluded from results.
JSON Output
{
"tests": [
{
"target": "MyAppTests",
"class": "LoginTests",
"method": "testValidLogin",
"identifier": "MyAppTests/LoginTests/testValidLogin",
"file": "LoginTests.swift",
"filePath": "/path/to/LoginTests.swift",
"lineNumber": 15,
"isSkipped": false
}
]
}
flowdeck test plans
List test plans referenced by a scheme. This reads the scheme file and does not build the project.
# After 'flowdeck init', list plans with saved settings
flowdeck test plans
# List plans (without init)
flowdeck test plans -w MyApp.xcworkspace -s MyScheme
# Output as JSON (for tooling)
flowdeck test plans --json
Options
| Option | Short | Description |
|---|
--project <path> | -p | Project directory |
--workspace <path> | -w | Path to workspace (.xcworkspace) or project (.xcodeproj) (also accepts --ws) |
--scheme <name> | -s | Scheme name (also accepts --sch) |
--config <path> | -c | Path to JSON config file with project settings (also accepts --cfg) |
--json | -j | Output as JSON |
--examples | -e | Show usage examples |
JSON Output
{
"plans": [
{
"name": "Smoke",
"reference": "container:App/TestPlans/Smoke.xctestplan",
"path": "/path/to/App/TestPlans/Smoke.xctestplan",
"isDefault": true,
"isMissing": false
}
]
}