(无需编译 WDA) 纯 Python 在 windows/mac 系统执行 iOS 自动化测试
感谢 @xiaoj 大佬的支持
关于性能数据获取: 
无需入侵被测 app 源码,单纯的获取性能数据 (包含但不限于 FPS,CPU,GPU 等等),对性能的影响可以忽略不计,获取性能数据的 api 可查看 py-ios-device api
也可连接着手机,边功能测试边获
源码使用:
硬货来啦!!使用纯 python 实现 Instruments 协议,跨平台 (win,mac,linux) 获取 iOS 性能数据
tidevice 开源:不依赖 Xcode 也能启动 WDA
python 仓库:  https://github.com/YueChen-C/py-ios-device 如果觉得有帮助点下  呗~
前置条件:
1.需要安装 appium server, windows 系统需要安装 itunes
2.pip3 install py-ios-device
3.设备上需要有编译好的 wda, wda 的 bundle id 可以使用 py_ios_device.get_applications() 获取
4.windows 系统修改: 
appium/node_modules/appium-xcuitest-driver/build/lib/device-log/ios-crash-log.js 中 process.env.HOME 修改为 process.env.TMP 即:
super(opts.udid ? _path.default.resolve(process.env.HOME, 'Library', 'Logs', 'CrashReporter', 'MobileDevice') : _path.default.resolve(process.env.HOME, 'Library', 'Logs', 'DiagnosticReports'));
修改为
super(opts.udid ? _path.default.resolve(process.env.TMP, 'Library', 'Logs', 'CrashReporter', 'MobileDevice') : _path.default.resolve(process.env.TMP, 'Library', 'Logs', 'DiagnosticReports'));
5.Mac / windows 系统修改: 
appium/node_modules/appium-xcuitest-driver/build/lib/driver.js 中的
const usePortForwarding = this.isRealDevice() && !this.wda.webDriverAgentUrl  && (0, _utils.isLocalHost)(this.wda.wdaBaseUrl);
修改为 
const usePortForwarding = this.isRealDevice() && (0, _utils.isLocalHost)(this.wda.wdaBaseUrl);
注意以上文件修改的都是 build 目录下的文件
6.启动 appium appium -p 4723 --relaxed-security
接下来就可以执行代码试试啦:
import json
import re
import time
from appium import webdriver
from ios_device.py_ios_device import PyiOSDevice
# 这个留空
web_driver_agent_url = ""
# 这里设置 wda 的端口,保证每个设备都有自己的端口
wda_port = 8200
# 这里是 wda 的 bundle id, 一般为 xxx.xxx.xxx.xctrunner
wda_bundle_id = ""
# 设备 id
device_id = ""
# 被测应用 bundle id
app = ""
device_channel = PyiOSDevice(device_id=device_id)
def xcuitest_callback(res):
    global web_driver_agent_url
    if "ServerURLHere->" in str(res):
        web_driver_agent_url = re.findall("ServerURLHere->(.+?)<-ServerURLHere", str(res))[0]
# 开启xcuitest 
# 2021/3/9 更新了 1.0.8 版本,可选择是否进行端口转发
xcuitest = device_channel.start_xcuitest(bundle_id=wda_bundle_id,
                                         callback=xcuitest_callback,
                                         app_env={"USE_PORT": wda_port},
                                         pair_ports=["8200:8200"])
def fps_callback(res):
    print("fps 数据{}".format(json.dumps(res)))
# 开启 fps 数据获取通道
device_channel.start_get_fps(fps_callback)
def gpu_callback(res):
    print("gpu 数据{}".format(json.dumps(res)))
# 开启 gpu 数据获取通道
device_channel.start_get_gpu(gpu_callback)
while web_driver_agent_url == "":
    time.sleep(1)
print(web_driver_agent_url)
desired_caps = {
    'app': app,
    'udid': device_id,
    'platformName': "iOS",
    'deviceName': 'iPhone',
    'xcodeOrgId': '9CVMN4UZK4',
    'xcodeSigningId': 'iPhone Developer',
    'automationName': 'XCUITest',
    "wdaLocalPort": wda_port,
    'webDriverAgentUrl': "http://127.0.0.1:8200",
    'noReset': True,
    'clearSystemFiles': True,
    "wdaLaunchTimeout": 360000,
    'newCommandTimeout': 1000,
    'showXcodeLog': True
}
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
driver.launch_app()
time.sleep(1)
driver.launch_app()
driver.stop_client()
# 关闭通道
device_channel.stop_get_fps()
device_channel.stop_get_gpu()
device_channel.stop_xcuitest(xcuitest)
device_channel.stop()
执行结果实例:
