1# Copyright 2025 Google Inc. 2# 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6 7import json 8import os 9import plistlib 10import subprocess 11import sys 12 13 14# Usage: ios_xcode_run.py <path to xcode> <path to app> <bundle id> <args>... 15# Runs the given app via xcode with the given args. 16 17 18xcode_path = sys.argv[1] 19app_path = sys.argv[2] 20bundle_id = sys.argv[3] 21args = sys.argv[4:] 22 23xcodebuild = os.path.join( 24 xcode_path, 'Contents', 'Developer', 'usr', 'bin', 'xcodebuild') 25 26subprocess.check_call([xcodebuild, '-version']) 27 28# Write the .xctestrun file. 29workdir = os.getcwd() 30xctestrun_path = os.path.join(workdir, 'skia_tests.xctestrun') 31module_name = os.path.splitext(os.path.basename(app_path))[0] + '_module' 32contents = { 33 module_name: { 34 'TestBundlePath': app_path, 35 'TestHostPath': app_path, 36 'TestHostBundleIdentifier': bundle_id, 37 'TestingEnvironmentVariables': {}, 38 'EnvironmentVariables': {}, 39 'CommandLineArguments': args, 40 }, 41} 42with open(xctestrun_path, 'wb') as f: 43 plistlib.dump(contents, f) 44 45# Find the ID of the attached device. We just assume a single device is attached. 46udid = subprocess.check_output(['idevice_id', '--list']).decode().strip() 47destination = 'id=' + udid 48 49output_json_path = os.path.join(workdir, 'enumerate-tests.json') 50 51# Run the app via XCode. 52result = subprocess.call([ 53 xcodebuild, 'test-without-building', 54 '-xctestrun', xctestrun_path, 55 '-destination', destination, 56 '-enumerate-tests', 57 '-test-enumeration-format', 'json', 58 '-test-enumeration-output-path', output_json_path, 59]) 60 61# Dump the JSON result. 62if os.path.exists(output_json_path): 63 with open(output_json_path) as f: 64 tests = json.load(f) 65 print(tests) 66 67# Exit with the code of the app. 68exit(result)