facebook-wda 是一个基于Python的测试库,通过HTTP协议与WebDriverAgent通信,本文介绍如何使用 facebook-wda 进行iOS APP自动化测试。

环境准备

使用 facebook-wda 之前需要满足如下条件:

  1. 手机安装 WebDriverAgent应用

    • 可以使用xcodebuild启动WDA(需要MAC电脑)
    • 也可以使用 tidevice 启动,它可以在Linux 、Windows和MAC上使用
  2. 电脑安装facebook-wda:

pip3 install -U facebook-wda

在windows上搭建iOS自动化测试环境可参考: Windows上实现iOS APP自动化测试:tidevice + WebDriverAgent + facebook-wda / appium

本文使用tidevice启动WDA:

$ tidevice list
List of apple devices attached
00008101-000255021E08001E iPhone12
$
$ tidevice -u [设备 udid] wdaproxy -B [wda 的 bundle Id] --port 8100

可以使用weditor查看UI元素,注意使用它之前要启动WDA。

pip3 install -U weditor # 安装

命令窗口输入weditor,会自动打开一个浏览器,选择iOS。

环境准备好后就可以使用 facebook-wda 进行iOS APP自动化测试了。

初始化

全局配置

import wdawda.DEBUG = False # default False
wda.HTTP_TIMEOUT = 180.0 # default 180 seconds
wda.DEVICE_WAIT_TIMEOUT = 180.0

DEBUG设置为 True 时会显示HTTP请求和响应信息

>>> import wda
>>> wda.DEBUG = True
>>> wda.HTTP_TIMEOUT = 180.0
>>> wda.DEVICE_WAIT_TIMEOUT = 180.0
>>> c = wda.Client('http://localhost:8100')
>>> c.app_current()
Shell$ curl -X GET -d '' 'http://localhost:8100/wda/activeAppInfo'
Return (206ms): {"value" : {"processArguments" : {"env" : {},"args" : []},"name" : "","pid" : 228,"bundleId" : "com.apple.Preferences"},"sessionId" : null
}
{'processArguments': {'env': {}, 'args': []}, 'name': '', 'pid': 228, 'bundleId': 'com.apple.Preferences'}
>>>
>>> wda.DEBUG = False
>>> c.app_current()
{'processArguments': {'env': {}, 'args': []}, 'name': '', 'pid': 228, 'bundleId': 'com.apple.Preferences'}
>>>

创建一个客户端

import wda
c = wda.Client('http://localhost:8100')
c = wda.Client() # 读取环境变量DEVICE_URL,如果没有使用默认地址:http://localhost:8100

也可以使用USBClient连接设备:

c = wda.USBClient() # 仅连接一个设备可以不传参数
c = wda.USBClient("00008101-000255021E08001E", port=8100) # 指定设备 udid 和WDA 端口号
c = wda.Client("http+usbmux://{udid}:8100".format(udid="00008101-000255021E08001E")) # 通过DEVICE_URL访问
c = wda.USBClient("00008101-000255021E08001E", port=8100, wda_bundle_id="com.facebook.WebDriverAgent.test2.xctrunner") # 1.2.0 引入 wda_bundle_id 参数

注:初始化连接设备时不需要事先使用tidevice命令启动WDA,wda.Client()会自动启动WDA应用。

设备操作

等待WDA服务正常

c.wait_ready(timeout=120, noprint=True) # 默认120s,安静的等待,无进度输出

锁屏

>>> c.locked()
False
>>> c.lock()
{'value': None, 'sessionId': '4D60BDFB-5D18-4EFB-8C40-97E4826B9AAB', 'status': 0}
>>> c.unlock()
{'value': None, 'sessionId': '4D60BDFB-5D18-4EFB-8C40-97E4826B9AAB', 'status': 0}

回到手机主页面

c.home()
c.press("home")

增大降低音量

c.press("volumeUp")
c.press_duration("volumeUp", 1) # 长按1s
c.press("volumeDown")
c.press_duration("volumeDown", 1)

打开、停止App

打开APP

s = c.session('com.apple.Health') # 打开app
s = c.session('com.apple.Health', alert_action="accept")
s.close() # 关闭c.session().app_activate("com.apple.Health") # 打开app

停止APP:

c.session().app_terminate("com.apple.Health") # 关闭app

获取app状态:

>>> c.session().app_state("com.apple.Health") # 返回app状态
{'value': 1, 'sessionId': 'BEB6A59E-254A-428A-AB53-F52A957ABE1F', 'status': 0}

获取设备应用信息

查看设备状态信息

>>> c.status()
{'message': 'WebDriverAgent is ready to accept commands', 'state': 'success', 'os': {'testmanagerdVersion': 28, 'name': 'iOS', 'sdkVersion': '14.5', 'version': '14.6'}, 'ios': {'ip': '192.168.5.159'}, 'ready': True, 'build': {'time': 'Jul 27 2021 20:50:24', 'productBundleIdentifier': 'com.facebook.WebDriverAgentRunner'}, 'sessionId': '4D60BDFB-5D18-4EFB-8C40-97E4826B9AAB'}

获取应用信息

当前应用信息

>>> c.app_current()
{'processArguments': {'env': {}, 'args': []}, 'name': '', 'pid': 228, 'bundleId': 'com.apple.Preferences'}

获取设备信息

设备信息

>>> c.device_info()
{'timeZone': 'GMT+0800', 'currentLocale': 'zh_CN', 'model': 'iPhone', 'uuid': '1DF5DFF9-93B2-4B87-8249-DB33ADB6A330', 'userInterfaceIdiom': 0, 'userInterfaceStyle': 'light', 'name': 'iPhone12', 'isSimulator': False}
>>>

电量信息

>>> c.battery_info()
{'level': 0.9800000190734863, 'state': 2}

分辨率:

>>> c.window_size()
Size(width=375, height=812)

UI元素定位

基本选择器

通过属性值定位:

id

s(id='URL')

className

s(className="XCUIElementTypeCell")

name

s(name='屏幕使用时间')
s(nameContains='屏幕')
s(nameMatches="屏幕.*")

value

s(value="屏幕使用时间")

label

s(label="屏幕使用时间")
s(labelContains="屏幕")

也可以组合多个属性,可以组合的属性包括:className、name、label、visible、enabled。

s(className="XCUIElementTypeCell",name="屏幕使用时间").click()

子元素

# 子元素定位
s(className='XCUIElementTypeTable').child(name='通知').exists

多个实例

返回所有匹配到的元素

$ s(nameContains='模式').find_elements()
[<wda.Element(id="15000000-0000-0000-0901-000000000000")>, <wda.Element(id="1B000000-0000-0000-0901-000000000000")>, <wda.Element(id="5E000000-0000-0000-0901-000000000000")>]

使用index来选择匹配到的多个元素

s(nameContains='模式', index=2).click() # 点击匹配到的第3个元素
# 或者
s(nameContains='模式')[2].click()

XPath定位

s(xpath='//*[@name="屏幕使用时间"]')
# 或者
s.xpath('//*[@name="屏幕使用时间"]')

更多xpath语法可参考 Web自动化测试:xpath & CSS Selector定位

Predicate定位

Predicate定位是iOS原生支持的定位方式,定位速度比较快,它可以通过使用多个匹配条件来准确定位某一个或某一组元素。

s(predicate='name BEGINSWITH "屏幕"').click() # 点击屏幕使用时间

更详细的Predicate语法及定位示例可参考: iOS APP自动化:predicate定位方法介绍

classChain定位

classChain是Predicate和Xpath定位的结合,搜索效率比XPath更高。

s(classChain='**/XCUIElementTypeTable/*[`name == "通知"`]').click() # 点击【通知】

更详细的使用方法参考: iOS APP自动化:class chain定位方法介绍

获取元素信息

检查元素是否存在

s(name="屏幕使用时间").exists # Return True or False

读取UI元素的属性信息

ele = s(name="屏幕使用时间").get(timeout=3.0) # 如果10s内没有找到,会抛出WDAElementNotFoundError错误
ele = s(name="屏幕使用时间").wait(timeout=3.0)# 获取元素属性
ele.className # XCUIElementTypeCell
ele.name # XCUIElementTypeCell
ele.visible # True
ele.value
ele.label # 屏幕使用时间
ele.text # 屏幕使用时间
ele.enabled # True
ele.displayed # True
ele.accessiblex, y, w, h = ele.bounds # Rect(x=0, y=744, width=375, height=46)

元素操作方法

点击

点击UI元素

s(name="屏幕使用时间").get(timeout=3.0).tap()
s(name="屏幕使用时间").tap()
s(name="设置").tap_hold(2.0) # 长按s(name="屏幕使用时间").click()s(text='屏幕使用时间').click_exists() # return True or False
s(text='屏幕使用时间').click_exists(timeout=5.0)

点击像素坐标

s = c.session('com.apple.Preferences')
s.tap(490, 1885) # 通过像素坐标点击s.click(490, 1885)
s.click(0.426, 0.716)s.double_tap(490, 1885)  # 双击

文本输入

文本值输入与清除

ele = s(text='搜索').get()ele.set_text("NFC") # 输入文本
ele.clear_text() # 清除文本
ele.set_text("\b\b\b\n") # 删除3个字符
ele.set_text("NFC\n") # 输入文本并确认

等待wait

设置隐式等待:

s.implicitly_wait(5) # 5s

设置超时时间

s.set_timeout(10.0)

等待元素

s(name="屏幕使用时间").wait(timeout=3.0) # 等待元素出现
s(name="屏幕使用时间").wait_gone(timeout=3.0) # 等待元素消失

Alert操作

对Alert弹框进行处理

>>> print(s.alert.exists)
True
>>> print(s.alert.text)
移除“设置”?
“从主屏幕移除”会将App保留在App资源库中。
s.alert.accept() # 确认
s.alert.dismiss() # 取消
s.alert.wait(5) # 等待出现s.alert.buttons() # 返回选项,例如:['取消', '从主屏幕移除']s.alert.click("取消") # 点击取消
s.alert.click(["取消", "cancel"]) # 点击出现的列表中的某个选项

也可以监控到Alert出现后进行操作:

with c.alert.watch_and_click(['好', '确定']):s(label="Settings").click() #

滑动swipe

根据像素坐标滑动

c.swipe(fx, fy, tx, ty, duration=0.5) # 从(fx, fy)滑到(tx, ty),坐标值可以是迅速值或者百分比,duration单位秒
c.swipe_left() # 向左滑动
c.swipe_right()
c.swipe_up()
c.swipe_down()

截图

s.screenshot().save("test.png")
from PIL import Image
s.screenshot().transpose(Image.ROTATE_90).save("correct.png") # 横屏截图

设备截屏

c.screenshot().save("screen.png")
c.press_duration("snapshot", 0.1)

pytest + facebook-wda实例

测试步骤:

  1. 打开【设置】
  2. 点击搜索
  3. 输入“NFC”
  4. 关闭NFC
  5. 断言NFC是否关闭

Python代码:

#!/usr/bin/python3
# -*-coding:utf-8-*-import wda
import time
wda.DEBUG = False # default False
wda.HTTP_TIMEOUT = 180.0 # default 180 seconds
wda.DEVICE_WAIT_TIMEOUT = 180.0class TestDemo():def setup(self):self.c = wda.USBClient("00008101-000255021E08001E", port=8100)self.c.wait_ready(timeout=300)self.c.implicitly_wait(30.0)def teardown(self):self.c.session().app_terminate("com.apple.Preferences")def test_NFC(self):self.c.session('com.apple.Preferences')self.c.swipe_down()self.c(name="搜索").set_text("NFC")  # 搜索 NFCself.c(name="NFC").click()  # 点击NFCtime.sleep(1)ele = self.c(xpath='//Switch').wait(timeout=3.0)sw = ele.valueif sw == '1':ele.click()self.c.alert.wait(3)self.c.alert.click("关闭")time.sleep(1)sw = ele.valueassert sw == '0'

--THE END--

我之前一个人,到处找学习资料,吃尽了苦头,还遇到不少坑,所以我把我整理的学习资料都归类整理好。环境对于一个人的成长很重要,我们一起加油,互相鼓励,从此不再孤单,所以小编决定,不能再低调了,毕竟实力不允许啊!如果有小伙伴想提升自己,未雨绸缪,为自己的未来提前规划,关注我,2021最新的软件测试电子版书籍、视频、还可以找我一起交流技术。更多软件测试资源分享微信公众号:【程序员阿沐】软件测试技术交流群:810119819

逆水行舟,不进则退!共勉!软件测试与你同行!点赞是最大的支持!

使用facebook-wda进行iOS APP自动化测试相关推荐

  1. Windows上实现iOS APP自动化测试:tidevice + WDA + facebook-wda / appium

    本文介绍如何在Windows下构建iOS APP自动化测试环境,采用的主要工具为tidevice,WebDriverAgent,facebook-wda或者appium. 目录 测试架构介绍 WebD ...

  2. Appium搭建MacOS环境下的iOS App自动化测试环境(Windows搭个MacOS虚拟机就行,亦无须iPhone)

    前言 经过上篇文章<Windows上Appium自动化测试Android应用>的介绍,我们已经学习App自动化测试的基本知识,接下来我们来学习如何对iOS进行基于Appium的自动化测试. ...

  3. App自动化测试工具Uiautomator2

    UI Automator是 google 在 Android4.1 版本发布时推出的一款用Java编写的Android UI 自动化测试工具,基于Android Accessibility 服务,Ac ...

  4. 解决Xcode couldn‘t find any iOS App Development provisioning profiles matching ‘com.facebook.WebDriver

    ① 目的: 昨天还好好的,今天早上环境启动好无法启动手机APP了. 但是使用模拟器好好地. ② 环境 Python+appium+IOS真机 ③ 错误信息 3.1错误信息: Xcode couldn' ...

  5. 在Facebook iOS app中减少FOOMs

    最近在看FOOM,翻译一下facebook的解决方案. 原文链接在Facebook iOS app中减少FOOMs 在Facebook iOS app中减少FOOMs 在Facebook,我们致力于使 ...

  6. (一)app自动化测试环境搭建(mac+ios+airtest )

    环境搭建的效果如下: IOS手机屏幕显示Automation Running 电脑端airtest设备窗口上可以看到手机屏幕 以下是在mac电脑的搭建过程,只演示连接IOS真机部分,安卓机较为简单暂时 ...

  7. python脚本控制ios手机app_appium 下 python 脚本自动化测试iOS APP 实例

    环境:Mac,Xcode, appium python 本文基于appium 环境搭建成功后.如何使用python 编写脚本测试iOS APP 1.下载python-client https://gi ...

  8. [facebook-wda]搭建iOS App自动化环境

    搭建iOS App自动化环境 一.测试结构介绍 手机端的WDA Runner(WebDriverAgent)类似于appium测试框架中的 UIAutomator Server,将从客户端接收到的控制 ...

  9. 基于 KIF 的 iOS UI 自动化测试和持续集成

    客户端 UI 自动化测试是大多数测试团队的研究重点,本文介绍猫眼测试团队在猫眼 iOS 客户端实践的基于 KIF 的 UI 自动化测试和持续集成过程. 一.测试框架的选择 iOS UI 自动化测试框架 ...

最新文章

  1. [转][android深入学习]android窗口管理机制
  2. OpenvSwitch — 操作实践
  3. python3.7安装turtle步骤-Python turtle安装和使用教程
  4. 那些年,我在游戏开发中改过的bug:坑爹的Vista与中间件
  5. Mysql 执行流程
  6. 远程mysql用ssh连接_使用SSH密钥连接到远程MySQL服务器
  7. win10基于anaconda下的tensorflow2.0.0及cuda10.0、cudnn安装成功
  8. [转载] 说说Python 面向对象编程
  9. Nordic fds 文件系统源码探究
  10. c语言外心,下面说法正确的是( )A.三点确定一个圆B.外心在三角形的内部C.平...
  11. 油猴脚本屏蔽CSND个人博客主页烦人广告
  12. 23andme的申请流程和注意事项
  13. Android apk 腾讯云-乐固的加固及签名
  14. 重装系统进入PE的快捷键大全
  15. 数理化解题研究杂志数理化解题研究杂志社数理化解题研究编辑部2022年第34期目录
  16. GIt远程仓库pull拉取代码
  17. Axure怎么制作文字滚动的动态效果
  18. 在Power BI中用DAX计算现值PV
  19. SharePoint 2013(rtm版) 安装与配置
  20. 域名过了赎回期多久可以开放注册

热门文章

  1. python 之 多继承的顺序
  2. color-scheme,颜色方案,jetbrains主题,webstrom
  3. OKEX及OKCoin量化交易入门-API入门及实践(Python语言)
  4. 利用sklearn计算决定系数R2
  5. iCore-3588Q 8K人工智能核心板
  6. 一个简单的方法,快速给多个小视频加GIF动态的图片水印
  7. 批处理编写以及修改注册表
  8. 数据结构之“如何判断一个序列为堆”
  9. 网秦发布2012Q3全球手机安全报告
  10. !important的用法