swift_package_test
Execute Swift package tests using swift test within the MCP server 'sl-test'. Specify package path, test product, filter, build configuration, parallel execution, code coverage, and parse-as-library flag for efficient testing.
Instructions
Runs tests for a Swift Package with swift test
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| configuration | No | Build configuration: 'debug' (default) or 'release' | |
| filter | No | Filter tests by name (regex pattern) | |
| packagePath | Yes | Path to the Swift package root (Required) | |
| parallel | No | Run tests in parallel (default: true) | |
| parseAsLibrary | No | Add -parse-as-library flag for @main support (default: false) | |
| showCodecov | No | Show code coverage (default: false) | |
| testProduct | No | Optional specific test product to run |
Implementation Reference
- src/tools/test-swift-package.ts:25-89 (handler)The main handler function that constructs the 'swift test' command arguments based on input parameters, executes it using executeCommand, and returns success/error responses with output.async (params: { packagePath: string; testProduct?: string; filter?: string; configuration?: 'debug' | 'release'; parallel?: boolean; showCodecov?: boolean; parseAsLibrary?: boolean; }): Promise<ToolResponse> => { const pkgValidation = validateRequiredParam('packagePath', params.packagePath); if (!pkgValidation.isValid) return pkgValidation.errorResponse!; const resolvedPath = path.resolve(params.packagePath); const args: string[] = ['test', '--package-path', resolvedPath]; if (params.configuration && params.configuration.toLowerCase() === 'release') { args.push('-c', 'release'); } else if (params.configuration && params.configuration.toLowerCase() !== 'debug') { return createTextResponse("Invalid configuration. Use 'debug' or 'release'.", true); } if (params.testProduct) { args.push('--test-product', params.testProduct); } if (params.filter) { args.push('--filter', params.filter); } if (params.parallel === false) { args.push('--no-parallel'); } if (params.showCodecov) { args.push('--show-code-coverage'); } if (params.parseAsLibrary) { args.push('-Xswiftc', '-parse-as-library'); } log('info', `Running swift ${args.join(' ')}`); try { const result = await executeCommand(['swift', ...args], 'Swift Package Test'); if (!result.success) { const errorMessage = result.error || result.output || 'Unknown error'; return createErrorResponse('Swift package tests failed', errorMessage, 'TestError'); } return { content: [ { type: 'text', text: '✅ Swift package tests completed.' }, { type: 'text', text: '💡 Next: Execute your app with swift_package_run if tests passed', }, { type: 'text', text: result.output }, ], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); log('error', `Swift package test failed: ${message}`); return createErrorResponse('Failed to execute swift test', message, 'SystemError'); } },
- Zod schema defining the input parameters for the swift_package_test tool, including packagePath (required), optional testProduct, filter, configuration, parallel, showCodecov, and parseAsLibrary.packagePath: z.string().describe('Path to the Swift package root (Required)'), testProduct: z.string().optional().describe('Optional specific test product to run'), filter: z.string().optional().describe('Filter tests by name (regex pattern)'), configuration: swiftConfigurationSchema, parallel: z.boolean().optional().describe('Run tests in parallel (default: true)'), showCodecov: z.boolean().optional().describe('Show code coverage (default: false)'), parseAsLibrary: parseAsLibrarySchema, },
- src/utils/register-tools.ts:166-169 (registration)Registration entry in the central tool registrations array that conditionally registers the swift_package_test tool via registerTestSwiftPackageTool if the environment variable is set.register: registerTestSwiftPackageTool, groups: [ToolGroup.SWIFT_PACKAGE_WORKFLOW], envVar: 'XCODEBUILDMCP_TOOL_SWIFT_PACKAGE_TEST', },
- src/tools/test-swift-package.ts:11-91 (registration)The tool-specific registration function that calls registerTool with the name 'swift_package_test', description, schema, and handler. This is imported and called from the central register-tools.ts.export function registerTestSwiftPackageTool(server: McpServer): void { registerTool( server, 'swift_package_test', 'Runs tests for a Swift Package with swift test', { packagePath: z.string().describe('Path to the Swift package root (Required)'), testProduct: z.string().optional().describe('Optional specific test product to run'), filter: z.string().optional().describe('Filter tests by name (regex pattern)'), configuration: swiftConfigurationSchema, parallel: z.boolean().optional().describe('Run tests in parallel (default: true)'), showCodecov: z.boolean().optional().describe('Show code coverage (default: false)'), parseAsLibrary: parseAsLibrarySchema, }, async (params: { packagePath: string; testProduct?: string; filter?: string; configuration?: 'debug' | 'release'; parallel?: boolean; showCodecov?: boolean; parseAsLibrary?: boolean; }): Promise<ToolResponse> => { const pkgValidation = validateRequiredParam('packagePath', params.packagePath); if (!pkgValidation.isValid) return pkgValidation.errorResponse!; const resolvedPath = path.resolve(params.packagePath); const args: string[] = ['test', '--package-path', resolvedPath]; if (params.configuration && params.configuration.toLowerCase() === 'release') { args.push('-c', 'release'); } else if (params.configuration && params.configuration.toLowerCase() !== 'debug') { return createTextResponse("Invalid configuration. Use 'debug' or 'release'.", true); } if (params.testProduct) { args.push('--test-product', params.testProduct); } if (params.filter) { args.push('--filter', params.filter); } if (params.parallel === false) { args.push('--no-parallel'); } if (params.showCodecov) { args.push('--show-code-coverage'); } if (params.parseAsLibrary) { args.push('-Xswiftc', '-parse-as-library'); } log('info', `Running swift ${args.join(' ')}`); try { const result = await executeCommand(['swift', ...args], 'Swift Package Test'); if (!result.success) { const errorMessage = result.error || result.output || 'Unknown error'; return createErrorResponse('Swift package tests failed', errorMessage, 'TestError'); } return { content: [ { type: 'text', text: '✅ Swift package tests completed.' }, { type: 'text', text: '💡 Next: Execute your app with swift_package_run if tests passed', }, { type: 'text', text: result.output }, ], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); log('error', `Swift package test failed: ${message}`); return createErrorResponse('Failed to execute swift test', message, 'SystemError'); } }, ); }