IOS自动化的那些经验

2019-11-09 14:25:00 浏览数 (1)

“在自动化测试过程中,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有哪些功能吧!

  1. 截图
代码语言:javascript复制
xcrun simctl io booted screenshot /pictures/test.png
  1. 录屏命令
代码语言:javascript复制
xcrun simctl io booted recordVideo /videos/test.mp4#  在终端按Ctrl C来停止录屏.
  1. 查看已安装的设备
代码语言:javascript复制
xcrun simctl list#列出安装的可用的模拟器xcrun instruments -s查看已安装的模拟器ios-sim showdevicetypes
  1. 启动模拟器
代码语言:javascript复制
#用来启动模拟器,其中的UUID参数就是之前列表中的UUID。xcrun simctl boot $UUIDxcrun instruments -w "iPhone 8(11.2)"
  1. 关闭模拟器
代码语言:javascript复制
xcrun simctl shutdown $UUID
  1. 重置模拟器
代码语言:javascript复制
xcrun simctl erase $UUID
  1. 清理不可用的模拟器
代码语言:javascript复制
#当Mac空间不够用时,这条命令或许可以帮你重获不是磁盘空间。xcrun simctl delete unavailable
  1. 安装指定app
代码语言:javascript复制
xcrun simctl install booted <app路径>ios-sim launch /Users/nali/Desktop/ting.app --devicetypeid iPhone-X, 11.2#多设备时xcrun simctl install <device> <app路径>
  1. 运行指定的app
代码语言:javascript复制
xcrun simctl launch booted <bundle identifier>#多设备时xcrun simctl launch <device> <bundle identifier>
  1. 关闭已经打开的应用
代码语言:javascript复制
xcrun simctl terminate booted <bundle identifer>#多设备时xcrun simctl terminate <device> <bundle identifier>
  1. 卸载指定应用
代码语言:javascript复制
xcrun simctl uninstall booted <bundle identifer>#多设备时xcrun simctl uninstall <device> <bundle identifier>
  1. 在模拟器与Mac设备之间进行复制&粘贴pbcopy & pbpaste
代码语言:javascript复制
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设备
  1. 更多功能查看
代码语言:javascript复制
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()

经验在于积累,在日常工作中,点滴积累,也许就能大幅度提高工作效率!

0 人点赞