Appium (无需编译 WDA) 纯 Python 在 windows/mac 系统执行 iOS 自动化测试,同时获取性能数据

小抄 · 2021年03月04日 · 最后由 hank.huang 回复于 2023年08月04日 · 13301 次阅读
本帖已被设为精华帖!

(无需编译 WDA) 纯 Python 在 windows/mac 系统执行 iOS 自动化测试

感谢 @xiaoj 大佬的支持

可以边执行自动化测试边获取 iOS 性能数据

关于性能数据获取:

无需入侵被测 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 系统修改:

2021/3/9 更新了 1.0.8 版本,可选择是否进行端口转发,如果 start_xcuitest 的参数 pair_ports 为 ["设备端口:本地端口"],则可以不修改这个文件
已修改的,需要改回来

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()

执行结果实例:

共收到 18 条回复 时间 点赞

建议 gitee 同步下仓库,github 近期时不时的访问不了,不知道我网络问题还是怎么

回复

最近 gitee 也不能同步 github 项目了,等同步了我回复你吧

陈恒捷 将本帖设为了精华贴 03月05日 09:39

这个库的代码写的不错嘛 https://github.com/YueChen-C/py-ios-device pair 相关的代码,我就不客气的借鉴啦 @xiaoj

又一个好东西!

codeskyblue 回复

是准备把这个集成到 tidevice 吗?

cmlanche 回复

pair 部分的代码,我之前因为依赖太难安装的问题,就没写进去,看他这个库里面用 pyopenssl 实现了,这个依赖安装就简单的多。所以就把这部分的代码放到 tidevice 了。

请教修改driver.js的目的是什么,不修改也行吧

Jacc 回复

这个是为了进入本地端口转发的判断里,之后库本身可以转发端口后就可以不修改这个文件了

小抄 #12 · 2021年03月08日 Author

2021/3/8 更新了 1.0.7 版本,可选择是否进行端口转发,如果 forward 为 True,则可以不修改appium/node_modules/appium-xcuitest-driver/build/lib/driver.js文件,
已修改的,需要改回来

@ 小抄 我本地试了一下,运行发现一直提示报错信息:

appium 调试日志的报错信息:

[debug] [XCUITest] Failed to create WDA session (An unknown server-side error occurred while processing the command. Original error: Could not proxy command to the remote server. Original error: connect ECONNREFUSED 127.0.0.1:8200). Retrying...

我本地 ide 里面报错信息:

Traceback (most recent call last):
  File "D:/pythonworkpace/tideviceTest/PreviewCameraTest.py", line 58, in <module>
    driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=desired_caps)
  File "D:\Program Files\Python\lib\site-packages\appium\webdriver\webdriver.py", line 155, in __init__
    proxy
  File "D:\Program Files\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "D:\Program Files\Python\lib\site-packages\appium\webdriver\webdriver.py", line 225, in start_session
    response = self.execute(RemoteCommand.NEW_SESSION, parameters)
  File "D:\Program Files\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "D:\Program Files\Python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Unable to start WebDriverAgent session because of xcodebuild failure: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to the remote server. Original error: connect ECONNREFUSED 127.0.0.1:8200 Make sure you follow the tutorial at https://github.com/appium/appium-xcuitest-driver/blob/master/docs/real-device-config.md. Try to remove the WebDriverAgentRunner application from the device if it is installed and reboot the device.


我试过电脑和手机都重启了,发现不管用呀,求指导一下

少女 回复

问题解决好了😆

过期了

依赖 appium 就依赖 wda 了额

“设备上需要有编译好的 wda, wda 的 bundle id 可以使用”
这不是还是要编译 WDA 吗、、

我想问一下怎么自动授信应用,在手机上,

你这标题党了吧?请告诉我不编译 WDA 怎么运行你这个?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册