前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在iphone真机上自动化测试

如何在iphone真机上自动化测试

作者头像
赵云龙龙
发布2020-05-22 15:43:05
1.9K0
发布2020-05-22 15:43:05
举报
文章被收录于专栏:python爱好部落python爱好部落

我们做自动化测试的时候,有的时候需要用模拟器来跑。 主要好处是:节约设备,不需要占用实际的设备资源;而且不会锁屏,需要充电等各种烦恼。 有的时候却用真机跑有好处,他们的区别是什么? 1.模拟器太慢

模拟器的运行速度取决于PC的配置,如果PC使用了机械硬盘那么使用模拟器光是启动的时间就够泡一壶茶了。

2.模拟器在某些方面往往达不到真机的真实水平。

碎片化严重。国内的手机厂商们热衷于对安卓系统进行深度定制,这也让开发者们操碎了心。小米、魅族、锤子这样的深度定制系统,应用开发好以后同样需要使用真实设备来适配。

3.模拟器不能模拟所有的API

Email、电话、短信等基于真实硬件的API由于模拟器本身的限制是不能被模拟出来的,因此应用但凡需要调用这些API的,都应该选择真机调试。

4.真机调试更能清晰真实的反映出开发过程中出现的问题;而模拟器性能比较差,在模拟器上不一定能发现。

5.真机测试更能支持横竖屏都方便,有一些情况模拟机不行。

6.搞3D图形图像时候,真机支持,虚拟机不一定支持OpenGL ES。

7.真机调试速度快,模拟器速度慢。

如果你对什么都没有要求,可以用模拟器来跑。如果你对上面列举的有要求,在资源允许的情况下,能用真机就用真机。

最近需要在真机上模拟用户的行为。然后考虑用Appium这个自动化测试框架来操作。

用Android 还好,一下就解决问题了。 代码类似如下:

代码语言:javascript
复制
current_path = os.path.dirname(os.path.abspath(__file__))

audio_file_path = os.path.join(current_path, "audio")
sentence_file = current_path + "\\sentence.txt"
result_path = current_path + "\\result"
log_path = current_path + "\\result\\log.txt"

import subprocess


def cmd(cmd):
    return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)


def get_device():
    for device in cmd('adb devices').stdout.readlines():
        if 'devices' not in str(device):
            device = device.decode('utf-8')
            return device.split('\t')[0]


def get_version():
    if cmd('adb shell getprop | findstr version.release').stdout != "":
        result = cmd('adb shell getprop | findstr ro.build.version.release').stdout.readline()
        result = str(result).split(":")[1]
        return result[result.index("[") + 1:result.index("]")]


def get_brand():
    if cmd('adb shell getprop | findstr ro.product.brand').stdout != "":
        result = cmd('adb shell getprop | findstr ro.product.brand').stdout.readline()

        result = str(result).split(":")[1]
        return result[result.index("[") + 1:result.index("]")]


desired_caps = {}

desired_caps["platformName"] = "android"
desired_caps["platformVersion"] = get_version()
desired_caps["deviceName"] = get_device()
desired_caps["appPackage"] = "com.library.speechscoringsdk"
desired_caps["appActivity"] = "com.library.speechscoringsdk.RootActivity"
desired_caps["autoGrantPermissions"] = True
desired_caps["automationName"] = "UiAutomator1"
desired_caps["noReset"] = True

driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)

result = []


#
def wait_element_appear(driver, element):
    try:
        # 设置等待
        wait = WebDriverWait(driver, element_time, DURATION)
        # 使用匿名函数
        wait.until(lambda diver: driver.find_element_by_id(element))
        return True
    except:
        return False


def is_element_appear(driver, element):
    try:
        driver.find_element_by_id(element)
        return True
    except:
        return False

Android真机跟模拟器没啥区别,只要你插上去的机器,都能获取device name 和版本号。

但是IOS的真机,就遇到了一些麻烦。弄了好久都没搞定。 启动,类似这样:

看来是没有装最新的WDA https://github.com/appium/appium/issues/13996

然后找了官方文档来读, http://appium.io/docs/en/drivers/ios-xcuitest-real-devices/ 就是要装一个一个WDA. WDA: WebDriverAgent is a WebDriver server implementation for iOS that can be used to remote control iOS devices. 最后在某个对测试有研究的老外开发的帮助下,折腾了好久,终于搞定了。 在某度上搜了好久,都不起作用,主要是都是以前的文档,某度上都会告诉你用一个免费的apple id就能搞定,实际则不然。可能苹果公司后面有限制了。

自动build WDA的方法 其实这种方法比较简单,就是你不需要自己手动去build WDA, 它自动帮你弄好。推荐用这种方法,主要是你codesign要搞正确,不行用buildleid, 这里举Appium-desktop为例子。 首先你得在你的mac上装最新的Appium-desktop, 不然不兼容。

然后配置文件可以这么写:

代码语言:javascript
复制
  "automationName": "XCUITest",
  "platformName": "ios",
  "platformVersion": "12.4",
  "deviceName": "Phone XS Max",
  "bundleId": "com.EngageSpeechScoringSample",
  "udid": "0000-00110D141492002E",
  "xcodeOrgId": "8HX",
  "xcodeSigningId": "iPhone Developer",
  "updatedWDABundleId": "com.EngageSpeechScoringSample"

这些参数 "platformVersion", "deviceName, "udid" 可以在你插入的手机里面获得: You can find it in xcode. Window→Device and Similators

像是这样:

这个 "bundleId"就是你要测的App的标识符,如果不知道,请开发帮忙。 这个 "xcodeOrgId" 就是苹果开发者证书的id, 也可以找开发帮忙。

当所有的desired_caps 填好以后. 就可以启动Appium-desktop. 我开始老启动不起来,主要是updatedWDABundleId这里出了点问题,后来在老外的帮助下,加了这个字段,就搞定了。

第一次启动的时候,要花上几分钟,你可以看到log里面一直报错。那是在build WDA, 无法跟WDA通信。

最后,在你的测试机上会build成功一个WDA,你可以开始愉快的玩耍了。

手动Build WDA

手动的配置,就是你要手工去build一个WDA在你的测试机器上,

代码语言:javascript
复制
  "automationName": "XCUITest",
  "platformName": "ios",
  "platformVersion": "12.4",
  "deviceName": "Phone XS Max",
  "bundleId": "com.EngageSpeechScoringSample",
  "udid": "8020-00110D141492002E",
  "xcodeOrgId": "8HHX",
  "xcodeSigningId": "iPhone Developer",

首先,你得在xcode登录苹果开发者账号,哪怕用个人team, 网上教程都是用免费的,现在免费的好像不灵了。 查看一下账号 Xcode. Xcode-->Preferance

然后去clone开源代码, 当然你也可以看网上教程,去appium内部module下去编译。个人觉得开源代码更新更靠谱一些。 https://github.com/facebookarchive/WebDriverAgent

然后CD到项目路径下,运行

代码语言:javascript
复制
./Scripts/bootstrap.sh

然后就是改WebdriverAngentLib and WebdriverAgentRunner 中的team, bundle ID, 把facebook的都改成你自己的。 我在开发电脑上一次性就搞好了。

然后Test, 最终在你的测试机上就会编译成功一个WDA. 也可以查命令:

代码语言:javascript
复制
Open /usr/local/lib/node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj

cd cd /usr/local/lib/node_modules/appium/node_modules/appium-webdriveragent/

xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'id=00008030-000145601EF0802E' test

成功以后,就可以开始你的测试了。

当然,IOS里面没有adb命令,你可以用自己封装的一些命令来操作,也可以达到效果。

代码语言:javascript
复制
brew install --HEAD libimobiledevice
brew install --HEAD ideviceinstaller
idevice_id -l  #显示当前所连接的设备[udid],包括 usb、WiFi 连接
ideviceinstalller -i  xx.ipa
# 查看应用的bundleId
andersons-iMac:~ anderson$ ideviceinstaller -l

如果报错:

代码语言:javascript
复制
Could not connect to lockdownd. Exiting.

重新编译就可以解决:

代码语言:javascript
复制
1   brew uninstall -f libimobiledevice ideviceinstaller usbmuxd
 如果失败执行:
    brew uninstall --ignore-dependencies libimobiledevice ideviceinstaller usbmuxd

2   brew install -v --HEAD --fetch --build-from-source usbmuxd libimobiledevice ideviceinstaller

更多命令,需要自己平时总结。我这里写一个例子:

代码语言:javascript
复制
from playsound import playsound

TIME_OUT = 30
TIMES = 30
element_max_wait_time = 10
DURATION = 0.5
SLEEPTIME = 13

current_path = os.path.dirname(os.path.abspath(__file__))

audio_file_path = os.path.join(current_path, "audio")
sentence_file = current_path + "/sentence.txt"
result_path = current_path + "/result"
log_path = current_path + "/result/log.txt"

import subprocess

def cmd(cmd):
    return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

def get_device_udid():
    if cmd('idevice_id -l').stdout != "":
        result = cmd('idevice_id -l').stdout.readline()
        return result.decode("utf-8").strip()

def get_version():
    if cmd('ideviceinfo -k ProductVersion').stdout != "":
        result = cmd('ideviceinfo -k ProductVersion').stdout.readline()
        return result.decode("utf-8").strip()

def get_device_show_name():
    if cmd('idevicename').stdout != "":
        result = cmd('idevicename').stdout.readline()
        return result.decode("utf-8").strip()

def get_device_name():
    if cmd('ideviceinfo -k ProductType').stdout != "":
        result = cmd('ideviceinfo -k ProductType').stdout.readline()
        return result.decode("utf-8").strip()

desired_caps = {}
desired_caps["automationName"] = "XCUITest"
desired_caps["platformName"] = "ios"
desired_caps["platformVersion"] = get_version()
desired_caps["udid"] = get_device_udid()
desired_caps["deviceName"] = get_device_name()
desired_caps["bundleId"] = "com.SpeechScoringSample"
desired_caps["xcodeOrgId"] = "HHX"
desired_caps["xcodeSigningId"] = "iPhone Developer"
desired_caps["updatedWDABundleId"] = "com.SpeechScoringSample"

driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)

result = []


def play_audio(mp3):
    playsound(mp3)


def is_element_appear(driver, element):
    try:
        driver.find_element_by_accessibility_id(element)
        return True
    except:
        return False

def wait_element_appear(driver, element):
    try:
        wait = WebDriverWait(driver,element_max_wait_time,DURATION)
        wait.until(lambda driver: driver.find_element_by_accessibility_id(element))
        return True
    except:
        return False

其他的就是业务上的累积了,我就不在这里写了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python粉丝团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档