目录:
一、go-ios安装部署启动
1、Windows系统驱动下载
2、Windows系统驱动部署
3、配置环境变量
二、构建wda.ipa
方案一:通过xcode构建
方案二:通过命令构建wda.ipa
可能遇到的问题及解决方案
三、IOS18启动自动化测试
四、连接到AirtestIDE
五、封装IOS17+的启动方法总结
go-ios的基本使用
之前写过IOS17打包WebDriverAgent构建ipa包安装到ios16.7及ios17以上设备结合tidevice3进行自动化测试,但那种方式发现在不同的设备上会有失败的概率,小版本号也会有一定影响,而且操作比较繁琐,失败率较高。
于是乎在tidevice作者的推荐下,尝试使用go-ios这个开源项目进行启动wda程序,发现稳定性很好,ios17以上,包括ios18(目前最新),均可以正常启动wda,同时Airtest也可以通过ubsmax连接IOS17及IOS18设备进行控件树识别,进行自动化测试。
代码层面,目前Airtest启动wda是采用的tidevice,所以需要自己改动源码或者重新封装go-ios的方式进行启动,Airtest官方目前也在调研go-ios,后续应该会出相应解决ios17、ios18启动wda的方案,本文也会提供封装源码。
一、go-ios安装部署启动
项目地址:https://github.com/danielpaulus/go-ios
releases包下载:https://github.com/danielpaulus/go-ios/releases
这个项目也可以使用如下命令进行安装:
npm install -g go-ios
releases包可以根据自己的系统进行下载:
1、Windows系统驱动下载
我使用的是windows,非Windows系统可以跳过这段,通过README教程查看,需要下载相关驱动。
npm install -g go-ios
can be used to get going. Runios --help
after the installation for details. For iOS 17+ devices you need to runsudo ios tunnel start
for go ios to work. This will start a tunnel daemon. To make this work on Windows, download the latest wintun.dll from herehttps://git.zx2c4.com/wintun
and copy it toC:/Windows/system32
翻译:
npm install -g go-ios
下载后可以进行运行。安装后运行ios --help
了解详细信息。对于 iOS 17+ 设备,您需要运行sudo ios tunnel start
才能使 go ios 正常工作。这将启动一个 tunnel 守护程序。要在 Windows 上执行此操作,请从此处下载最新的wintun.dll https://git.zx2c4.com/wintun
并将其复制到C:/Windows/system32
驱动网址1:https://www.wintun.net/
驱动网址2:https://git.zx2c4.com/wintun
2、Windows系统驱动部署
1、把下载好的驱动文件进行解压缩,进入bin\amd64
(现在的windows系统电脑一般是amd64),把wintun.dll
文件复制到C:/Windows/system32
根目录下。
Ubuntu\Linux查看系统内核
使用 uname -m
查看架构类型。使用 lscpu
获取详细的 CPU 信息。查看 /proc/cpuinfo
文件中的详细信息。
2、注意:是把dll文件放过去,不是整个文件夹放过去
3、配置环境变量
1、如果是通过npm -g安装的就不需要进行这一步,如果是通过release包进行下载的,想要在全局使用go-ios,则需要配置环境变量。
2、比如我下载后存放的路径是D:\P_Program\go-ios-win\ios.exe
3、打开我的电脑 -> 属性 -> 系统 -> 系统信息 -> 高级系统设置 -> 环境变量
4、点开环境变量 -> 系统变量 -> 找到变量为path的,双击进入 -> 新建 -> 输入D:\P_Program\go-ios-win\ios.exe
-> 确认
5、win+r 输入cmd,打开控制台,输入ios验证是否配置成功,出现如下内容,代表环境变量配置成功。
C:\Users>ios
Usage:
ios activate [options]
ios listen [options]
.....
二、构建wda.ipa
这个在之前的文章有写,这里简单阐述一下步骤,一个是通过xcode构建直接安装到设备,一个是通过命令构建wda.ipa,再把该ipa安装到设备。
设备部署构建环境:
Mac电脑:macOS Sonoma 14.5 Xcode16:需要下载支持ios18的内容 Appium-WebDriverAgent:v8.9.2
方案一:通过xcode构建
1、进入appium-webdriveragent下载源码:https://github.com/appium/WebDriverAgent/releases
2、使用xcode16打开源码目录下的WebDriverAgent.xcodeproj文件,打开后,在左侧选择WebDriverAgentRunner,然后在 Signing & Capabilities
选项卡中,确保 Automatically manage signing
选项已勾选。
3、xcode16不再像之前的版本一样需要选ios小版本,这里只需要勾选ios大版本即可,账号使用企业开发者账户签名,个人的只有七天有效期。
选择正确的团队(Team),这将确保 Xcode 使用正确的签名证书和配置文件。
4、Bundle identifier需要更改一下,不重复就可以了,我是直接在后面加点后缀。
5、连接目标ios设备,product --> Destination --> 选择对应设备,如果显示设备没有准备好,插拔连接线,还是这样直接重启就可以恢复连接。
6、选择对应方案,Product --> Scheme -- > WebDriverAgentRunner
7、启动构建测试:Product --> Build For --> Testing
8、测试构建:Product --> Test
以上步骤成功标志是:
Xcode控制台正常输出日志
显示Build Succeeded
设备上安装上了WebDriverAgentRunner-Runner
设备上显示Automation Running动态水印样式
方案二:通过命令构建wda.ipa
# 1、xcode打开代码下的WebDriverAgent.xcodeproj项目,配置好团队唯一id等信息
$ xcodebuild build-for-testing -scheme WebDriverAgentRunner -sdk iphoneos -configuration Release -derivedDataPath /tmp/derivedDataPath
# 2、cd的目录和上条命令/tmp/derivedDataPath目录是一致的
$ cd /tmp/derivedDataPath
# 3、这个目录是连续的可以和上条命令一起 cd /tmp/derivedDataPath/Build/Products/Release-iphoneos
$ cd Build/Products/Release-iphoneos
# 4、在这个目录下创建一个Payload文件夹,并且把.app文件复制到Payload文件夹下
$ mkdir Payload && mv *.app Payload
# 5、用zip命令打包出来一个ipa
$ zip -r WDA.ipa Payload
# 6、把WDA.ipa安装到指定设备上
$ ios install WDA.ipa --udid=<udid>
打开访达,shift+command+g 在出现的窗口中输入/tmp,斜杆必须写,这样可以进去对应目录吧WDA.ipa拖出来。
安装示列:
ios install --path=ios18-WDA.ipa --udid=00008110-00112DA90E07801E
可能遇到的问题及解决方案
使用方案一在进行构建时,可能会出现构建失败,或者在安装ipa的时候会出现中断报错,这是因为我们在新的设备上没有信任该开发者账号。(ios17之前貌似不用)
安装报错示列:
{"err":"your app is not properly signed for this device, check your codesigning and provisioningprofile. original error: 'ApplicationVerificationFailed' errorDescription:'Failed to verify code signature of /var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.XyWuva/extracted/Payload/WebDriverAgentRunner-Runner.app : 0xe8008015 (A valid provisioning profile for this executable was not found.)'","level":"fatal","msg":"failed writing","time":"2024-09-14T18:46:41+08:00"}
解决方案:打开设置 -> 通用 -> VPN与设备管理 -> 信任开发者
三、IOS18启动自动化测试
1、ios17以上需要通过go-ios启动隧道
以管理员启动终端运行如下命令,且不要关闭该界面。
ios tunnel start
启动之后不要关闭,连接到ios17以上设备会自动帮你启动隧道。
2、设置 -> 开发者 -> 启动UI自动化勾上,(如果没有打开开发者:【设置】-【隐私与安全性】,拉到底部,就可在“安全性”一栏看到开发者模式了。)
3、指定设备启动WebDriverAgentRunner
ios runwda --udid=00008110-00112DA90E07801E --bundleid=com.facebook.WebDriverAgentRunnerxzz.xctrunner --testrunnerbundleid=com.facebook.WebDriverAgentRunnerxzz.xctrunner --xctestconfig=WebDriverAgentRunner.xctest
四、连接到AirtestIDE
1、打开AirtestIDE
2、通过远程IOS连接
ios:///http+usbmux://00008110-00112DA90E07801E
3、点击连接即可,下面是IOS17.6.1和IOS18使用go-ios启动wda后连接AirtestIDE的展示
IOS18
4、均可以正常连上,后续也使用代码进行测试了,可以正常运行自动化,测试连接设备代码如下(脚本不便展示):
from airtest.core.api import *
# ios18设备的udid
devices = '00008110-00112DA90E07801E'
auto_setup(__file__, devices=[f"ios:///http+usbmux://{devices}", ])
from poco.drivers.ios import iosPoco
dev = connect_device(f"iOS:///http+usbmux://{devices}")
poco_ios = iosPoco(device=dev)
五、封装IOS17+的启动方法
Airtest中的方法start_app()是封装的tidevice,但tidevice是不支持ios17和ios18,并且作者开了新的tidevice3,并且推荐go-ios,所以可以直接修改源码更换,也可以重新封装,这里我为了不影响ios17之前的设备运行,我采用重新封装的方法。封装代码如下:
# -*- coding: utf-8 -*-
"""
@Time : 2024/9/13 17:57
@Email : Lvan826199@163.com
@公众号 : 梦无矶测开实录
@File : connect_ios17_or_higher.py
"""
__author__ = "梦无矶小仔"
import os
import subprocess
import time
from airtest.core.api import connect_device, device, sleep, auto_setup, click, text
from poco.drivers.ios import iosPoco
class IOS17HigherAutomation:
def __init__(self, wda_package_name, uuid, wda_ipa_path, log_dir='./ios'):
self.wda_package_name = wda_package_name
self.uuid = uuid
self.wda_ipa_path = wda_ipa_path
self.log_dir = log_dir
self.device = None
self.poco = None
self.width = None
self.height = None
def install_wda(self):
os.system(self.wda_ipa_path)
time.sleep(6)
def run_wda(self):
run_wda_command = [
'ios', 'runwda',
f'--bundleid={self.wda_package_name}',
f'--testrunnerbundleid={self.wda_package_name}',
'--xctestconfig=WebDriverAgentRunner.xctest'
]
subprocess.Popen(run_wda_command)
time.sleep(6)
def connect_device(self):
self.device = connect_device(f"ios:///http+usbmux://{self.uuid}")
self.poco = iosPoco(device=self.device)
dev = device()
self.width, self.height = dev.get_current_resolution()
auto_setup(logdir=self.log_dir, compress=3, devices=[f"ios:///http+usbmux://{self.uuid}"])
sleep(6)
def start_recording(self, fps=4, orientation=1):
self.device.start_recording(fps=fps, orientation=orientation)
def stop_recording(self):
self.device.stop_recording()
def start_app(self, app_package_name):
# # you need to kill the app firstly, and then start the app
# otherwith it would fail to open the app after you open the app more than 188 times
self._kill_app(app_package_name)
self._launch_app(app_package_name)
def _kill_app(self, app_package_name):
kill_app_command = ['ios', 'kill', app_package_name]
subprocess.run(kill_app_command, check=True)
def _launch_app(self, app_package_name):
launch_app_command = ['ios', 'launch', app_package_name]
subprocess.run(launch_app_command, check=True)
def search_in_app_store(self, search_text):
self.poco(nameMatches=".*search").click()
self.poco(nameMatches="AppStore.searchField").click()
text(search_text)
click([self.width * 0.5, self.height * 0.5])
def uninstall_wda(self):
os.system(f'tidevice uninstall {self.wda_package_name}')
def main():
WDA_PACKAGE_NAME = 'xxx'
UUID = 'xxx'
WDA_IPA_PATH = r'ios install C:\xxx\xxxx\xxxx\xxxxx\xxxxx\wda.ipa'
ios_automation = IOS17HigherAutomation(WDA_PACKAGE_NAME, UUID, WDA_IPA_PATH)
ios_automation.install_wda()
ios_automation.run_wda()
ios_automation.connect_device()
ios_automation.start_recording()
ios_automation.start_app("com.apple.AppStore")
ios_automation.search_in_app_store("原神")
ios_automation.stop_recording()
ios_automation.uninstall_wda()
if __name__ == "__main__":
main()
大家可以根据这个,封装符合自己业务的代码。
总结
1、安装go-ios
2、使用xcode安装WebDriverAgentRunner
3、使用ios tunnel start
和ios runwda --udid=00008110-00112DA90E07801E --bundleid=com.xxxx.xctrunner --testrunnerbundleid=com.xxxx.xctrunner --xctestconfig=WebDriverAgentRunner.xctest
命令启动WebDriverAgentRunner
4、远程连接AirtestIDE
go-ios的基本使用
激活连接的 iOS 设备。
ios activate [options]
监听设备的连接和断开事件
ios listen [options]
列出所有连接的 iOS 设备。使用 --details
参数可以获取详细信息。
ios list [options] [--details]
获取设备的基本信息。 display
获取显示信息,lockdown
获取锁定状态信息。
ios info [display | lockdown] [options]
列出设备上的开发者镜像。
ios image list [options]
挂载开发者镜像。需要提供镜像的路径。
ios image mount [--path=<imagepath>] [options]
卸载当前挂载的开发者镜像。
ios image unmount [options]
自动挂载开发者镜像,基于提供的镜像存储目录。
ios image auto [--basedir=<where_dev_images_are_stored>] [options]
获取设备的系统日志。
ios syslog [options]
截屏,获取设备的屏幕截图。可以指定输出文件和端口。
ios screenshot [options] [--output=<outfile>] [--stream] [--port=<port>]
通知,获取设备的通知信息。
ios instruments notifications [options]
列出崩溃日志,可以使用模式匹配。
ios crash ls [<pattern>] [options]
复制崩溃日志
ios crash cp <srcpattern> <target> [options]
删除崩溃日志
ios crash rm <cwd> <pattern> [options]
获取设备名称
ios devicename [options]
获取或设置设备日期
ios date [options]
设置时间格式,可以设置为 24 小时制、12 小时制、切换或获取当前格式。
ios timeformat (24h | 12h | toggle | get) [--force] [options]
列出设备状态配置文件
ios devicestate list [options]
启用设备状态配置文件
ios devicestate enable <profileTypeId> <profileId> [options]
擦除设备上的所有数据。使用 --force
参数强制执行。
ios erase [--force] [options]
设置语言和区域
ios lang [--setlocale=<locale>] [--setlang=<newlang>] [options]
获取指定的 MobileGestalt 键值信息。可以选择输出为 plist 格式。
ios mobilegestalt <key>... [--plist] [options]
列出诊断信息
ios diagnostics list [options]
列出配置文件
ios profile list [options]
准备设备,准备设备进行开发或测试。可以跳过某些步骤,指定证书文件和组织名称。
ios prepare [--skip-all] [--skip=<option>]... [--certfile=<cert_file_path>] [--orgname=<org_name>] [--locale] [--lang] [options]
创建证书
ios prepare create-cert
打印准备设备时跳过的步骤。
ios prepare printskip
从设备上移除指定的配置文件。
ios profile remove <profileName> [options]
向设备添加配置文件。可以指定 p12 文件和密码。
ios profile add <profileFile> [--p12file=<orgid>] [--password=<p12password>] [options]
设置设备的 HTTP 代理。需要提供代理主机、端口、用户、密码以及 p12 文件和密码。
ios httpproxy <host> <port> [<user>] [<pass>] --p12file=<orgid> --password=<p12password> [options]
移除设备上的 HTTP 代理设置。
ios httpproxy remove [options]
与设备进行配对。需要提供 p12 文件和密码。
ios pair [--p12file=<orgid>] [--password=<p12password>] [options]
列出设备上的进程。使用 --apps
参数可以仅列出应用进程。
ios ps [--apps] [options]
获取设备 IP 地址
ios ip [options]
在主机和设备之间进行端口转发。
ios forward [options] <hostPort> <targetPort>
启动代理服务。可以选择模式和接口。
ios dproxy [--binary] [--mode=<all(default)|usbmuxd|utun>] [--iface=<iface>] [options]
读取配对信息
ios readpair [options]
捕获设备上的网络数据包。可以指定进程 ID 或进程名称。
ios pcap [options] [--pid=<processID>] [--process=<processName>]
安装应用,需要提供应用的路径。
ios install --path=<ipaOrAppFolder> [options]
卸载应用,需要提供应用的包名。
ios uninstall <bundleID> [options]
列出应用,使用 --system
参数列出系统应用,--all
参数列出所有应用,--list
参数列出简短信息,--filesharing
参数列出支持文件共享的应用。
ios apps [--system] [--all] [--list] [--filesharing] [options]
启动应用,可以选择等待应用启动完成 ( --wait
) 或杀死已有的应用实例 (--kill-existing
)。
ios launch <bundleID> [--wait] [--kill-existing] [options]
终止应用,可以通过包名、进程 ID 或进程名称来指定应用。
ios kill (<bundleID> | --pid=<processID> | --process=<processName>) [options]
运行 XCTest 测试。可以指定测试包 ID、测试运行器包 ID、XCTest 配置文件、日志输出文件、要运行的测试、要跳过的测试和环境变量。
ios runtest [--bundle-id=<bundleid>] [--test-runner-bundle-id=<testrunnerbundleid>] [--xctest-config=<xctestconfig>] [--log-output=<file>] [--xctest] [--test-to-run=<tests>]... [--test-to-skip=<tests>]... [--env=<e>]... [options]
运行 WebDriverAgent,可以指定包 ID、测试运行器包 ID、XCTest 配置文件、日志输出文件、启动参数和环境变量。
ios runwda [--bundleid=<bundleid>] [--testrunnerbundleid=<testbundleid>] [--xctestconfig=<xctestconfig>] [--log-output=<file>] [--arg=<a>]... [--env=<e>]... [options]
设置辅助功能字体大小
ios ax [--font=<fontSize>] [options]
调试应用,可以选择在入口点停止。
ios debug [options] [--stop-at-entry] <app_path>
文件同步操作,可以删除 ( rm
)、列出目录树 (tree
) 或创建目录 (mkdir
)。
ios fsync (rm [--r] | tree | mkdir) --path=<targetPath>
文件同步传输,从设备拉取文件 ( pull
) 或推送文件到设备 (push
)。
ios fsync (pull | push) --srcPath=<srcPath> --dstPath=<dstPath>
重启设备
ios reboot [options]
显示帮助信息
ios -h | --help
显示版本信息
ios --version | version [options]
设置设备位置,需要提供纬度和经度。
ios setlocation [options] [--lat=<lat>] [--lon=<lon>]
设置设备位置(GPX 文件),需要提供 GPX 文件路径。
ios setlocationgpx [options] [--gpxfilepath=<gpxfilepath>]
重置设备位置
ios resetlocation [options]
控制辅助触控,可以启用、禁用、切换或获取当前状态。
ios assistivetouch (enable | disable | toggle | get) [--force] [options]
控制 VoiceOver,可以启用、禁用、切换或获取当前状态。
ios voiceover (enable | disable | toggle | get) [--force] [options]
控制缩放触控,可以启用、禁用、切换或获取当前状态。
ios zoomtouch (enable | disable | toggle | get) [--force] [options]
获取磁盘空间信息
ios diskspace [options]
检查电池状态
ios batterycheck [options]
启动隧道,可以提供配对记录路径和用户空间选项。
ios tunnel start [options] [--pair-record-path=<pairrecordpath>] [--userspace]
列出隧道
ios tunnel ls [options]
停止隧道代理
ios tunnel stopagent
开启或获取开发者模式
ios devmode (enable | get) [--enable-post-restart] [options]
列出设备的 RSD(Remote Service Discovery)信息。
ios rsd ls [options]