【IOS自动化】IOS18如何使用Airtest进行自动化测试及go-ios的基本使用

科技   2024-09-25 16:00   广东  

目录:

一、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. Run ios --help after the installation for details. For iOS 17+ devices you need to run sudo 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 here https://git.zx2c4.com/wintun and copy it to C:/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 startios 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]
(猜你还想看
【私有云场景案例分享③】批量回归测试自动化流程
【装包测试】Android应用权限授权小技巧
【私有云场景案例分享②】批量装包与冒烟测试的自动化实现

AirtestProject
AirtestProject是网易开源的UI自动化测试方案。关注我们,获取测试领域的最新技术,洞察测试行业的最新动态。
 最新文章