“在自动化测试过程中,Android可以用adb来辅助,IOS却不太好操作,有没有办法呢?
在自动化中,IOS我们可以用libimobiledevice来辅助做一些工作,用xcrun simctl可以来操纵模拟器,具体咋用呢?
什么是libimobiledevice
一个跨平台的软件协议库和工具来与iOS设备进行本地通信 LipimBielEdter是一个跨平台的软件库,用于支持iPhone等mac设备的协议。不像其他项目,它不依赖于使用任何现有的专有库,不需要越狱。它允许其他软件轻松访问设备的文件系统,检索有关设备及其内部设备的信息。官方网站:http://www.libimobiledevice.org github地址:https://github.com/libimobiledevice
安装(Install For MacOS)
代码语言:javascript复制$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" # 若mac没有homebrew则执行此条命令,安装
$ brew install libimobiledevice $ brew install ideviceinstaller # ipa安装命令
1、打印app列表和信息
代码语言:javascript复制ideviceinstaller -l
2、查看当前已连接的设备的UUID
代码语言:javascript复制idevice_id -l
3、获取设备信息
代码语言:javascript复制ideviceinfo
4、获取设备时间
代码语言:javascript复制idevicedate
5、重启设备
代码语言:javascript复制idevicediagnostics restart 重启idevicediagnostics shutdown 关机idevicediagnostics sleep 休眠
6、安装ipa包,卸载应用
代码语言:javascript复制ideviceinstaller -i xxx.ipa //命令安装一个ipa文件到手机上,如果是企业签名的,非越狱机器也可以直接安装了。
ideviceinstaller -U [bundleID] //命令卸载应用,需要知道此应用的bundleID
7、查看系统日志
代码语言:javascript复制idevicesyslog//屏幕上即可看见手机上所有的日志
idevicesyslog >> iphone.log &//该命令是将日志导入到iphone.log这个文件,并且是在后台执行。//然后用tail -f和grep查看log
tail -f iphone.logtail -f iphone.log | grep 'WeChat’ # 查看包含WeChat的行
8、截图idevicescreenshot
//如果在使用截图的时候出现报错信息,那么就去把相应版本的DeveloperDiskImage的两个文件复制到libimobiledevice文件下面。
路径:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/对应版本/
获取版本号命令:
代码语言:javascript复制ideviceinfo -k ProductVersion
安装DeveloperDiskImage命令:
代码语言:javascript复制ideviceimagemounter DeveloperDiskImage.dmg//然后就可以正常截图了
9、 遇到报错
解决方法:卸载重装
代码语言:javascript复制brew uninstall ideviceinstallerbrew uninstall libimobiledevicebrew install --HEAD libimobiledevicebrew install ideviceinstaller
遇到的问题 问题1 执行命令ideviceinfo
代码语言:javascript复制报错:ERROR: Could not connect to lockdownd, error code -21
问题2 安装过程报错:
代码语言:javascript复制Requested ‘libusbmuxd >= 1.1.0’ but version of libusbmuxd is 1.0.10
解决方案:
代码语言:javascript复制brew updatebrew uninstall --ignore-dependencies libimobiledevicebrew uninstall --ignore-dependencies usbmuxdbrew install --HEAD usbmuxdbrew install --HEAD libimobiledevice
问题3:执行 ideviceinstaller -i ‘安装包路径’。抛出错误如下:
代码语言:javascript复制29385 abort ideviceinstaller -i
解决方案:卸载ideviceinstaller,安装最新版本的ideviceinstaller
操作iOS模拟器命令(xcrun simctl)
在做自动化测试的时候,有时候用模拟器来代替真机,这样有几个好处,一个是不一定有那么多真机设备,可以节约资源,还有就是不存在电量耗尽的情况。
我们需要了解一下模拟器和真机的区别:模拟器是i386处理器 真机是arm系列。arm是嵌入式设备的cpu,理论上的确精度要差一些。所以在编写移动设备时应当充分的考虑这些因素。
硬件限制 iOS 模拟器没有硬件限制,比如内存。所以会有应用出现在模拟器上很快,真机很慢的情况,原因是真机的内存被用完了。
我们在做基本的功能自动化,可以用模拟器来代替。我们可以用命令来操作模拟器,下面来看看xcrun simctl有哪些功能吧!
- 截图
xcrun simctl io booted screenshot /pictures/test.png
- 录屏命令
xcrun simctl io booted recordVideo /videos/test.mp4# 在终端按Ctrl C来停止录屏.
- 查看已安装的设备
xcrun simctl list#列出安装的可用的模拟器xcrun instruments -s查看已安装的模拟器ios-sim showdevicetypes
- 启动模拟器
#用来启动模拟器,其中的UUID参数就是之前列表中的UUID。xcrun simctl boot $UUIDxcrun instruments -w "iPhone 8(11.2)"
- 关闭模拟器
xcrun simctl shutdown $UUID
- 重置模拟器
xcrun simctl erase $UUID
- 清理不可用的模拟器
#当Mac空间不够用时,这条命令或许可以帮你重获不是磁盘空间。xcrun simctl delete unavailable
- 安装指定app
xcrun simctl install booted <app路径>ios-sim launch /Users/nali/Desktop/ting.app --devicetypeid iPhone-X, 11.2#多设备时xcrun simctl install <device> <app路径>
- 运行指定的app
xcrun simctl launch booted <bundle identifier>#多设备时xcrun simctl launch <device> <bundle identifier>
- 关闭已经打开的应用
xcrun simctl terminate booted <bundle identifer>#多设备时xcrun simctl terminate <device> <bundle identifier>
- 卸载指定应用
xcrun simctl uninstall booted <bundle identifer>#多设备时xcrun simctl uninstall <device> <bundle identifier>
- 在模拟器与Mac设备之间进行复制&粘贴pbcopy & pbpaste
pbcopy 复制内容到Mac设备的剪贴板pbpaste 将 Mac设备的剪贴板的内容进行粘贴xcrun simctl pbcopy booted 将Mac设备中剪贴板上的内容复制到模拟器上的剪贴板上;方向:Mac=》模拟器xcrun simctl pbpaste booted 将模拟器中剪贴板上的内容复制到Mac设备上的剪贴板上:方向:模拟器=》Macxcrun simctl pbsync sourceDevice destDevice 将source设备中剪贴板上的内容同步到dest设备上的剪贴板上;方向:source《=》dest,其中可以用 host 表示Mac设备
- 更多功能查看
xcrun simctl -h
这些命令,自己可以写一个包来调用,例如:
代码语言:javascript复制import osimport reimport subprocessimport time
current_time = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))
class iosinformation(): def exec_command(self, cmd): result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (stdoutdata, stderrdata) = result.communicate() # print("Result is:%s") % stdoutdata if (re.search("No device found", str(stdoutdata)) or re.search("Could not connect", str(stdoutdata))): print ("Please connet it agian, or add permission like: brew install libimobiledevice --HEAD,sudo chmod -R 777 /var/db/lockdown/") else: return stdoutdata
def Get_UUID(self): cmd = 'idevice_id -l' uuid = self.exec_command(cmd) return uuid
def Get_Device_Name(self): cmd = 'ideviceinfo -k DeviceName' device_name = self.exec_command(cmd) return device_name
def Get_Device_information(self): cmd = 'ideviceinfo -k ProductVersion' device_information = self.exec_command(cmd) return device_information
def Get_Device_Product_type(self): cmd = 'ideviceinfo -k ProductType' product_type = self.exec_command(cmd) return product_type
def List_All_Pakages(self, uuid): cmd = 'ideviceinstaller -u {0}'.format(uuid)
all_pakages = self.exec_command(cmd)
return all_pakages
def List_All_Logs(self, uuid): all_logs = "idevicesyslog -u {0}".format(uuid) return all_logs
def Take_Screenshot(self): current_dir = os.path.split(os.path.realpath(__file__))[0] cmd1 = "idevicescreenshot {0} '/' screenshot-DATE.tiff".format(current_dir) cmd2 = "sips - s format png {0}.tiff - -out {1}.png".format(current_time, current_time) self.exec_command(cmd1)
# self.exec_command(cmd2)
def Install_Ipa(self, ipa): cmd = 'ideviceinstaller -i {0}'.format(ipa) result = self.exec_command(cmd) return result
def Uninstall_Ipa(self, appid): cmd1 = 'ideviceinstaller -l' cmd2 = 'ideviceinstaller -U {0}'.format(appid) result = self.exec_command(cmd1) appids=[] for id in result.split('n'): if re.search('-',id): str = id[0:id.find("-")].strip() appids.append(str)
else: pass
if appid in appids: result = self.exec_command(cmd2) else: print ("The appid dosen't exit in the devices")
# cmd2 = 'ideviceinstaller -u appid'.format(appid) # result = self.exec_command(cmd) # return result
def main(): ios = iosinformation()
uuid = ios.Get_UUID() print (" uuid is {0}".format(uuid)) device = ios.Get_Device_Name() print (" device is {0}".format(device)) device_info = ios.Get_Device_information() print (" device_info is {0}".format(device_info)) product_type = ios.Get_Device_Product_type() print (" product_type is {0}".format(product_type)) # all_pakagas = ios.List_All_Pakages(uuid) # print " all_pakagas is {0}".format(all_pakagas) ios.Take_Screenshot()
if __name__ == '__main__': main()
经验在于积累,在日常工作中,点滴积累,也许就能大幅度提高工作效率!