一、元素定位
(1)id定位
find_element_by_id(“resrouce-id”)
driver.find_element_by_id('com.android.calculator2:id/digit8')
(2)name定位
find_element_by_name(“text”)
driver.find_element_by_name("昵称")
(3)class_name定位
find_element_by_class_name(“class”)
driver.find_element_by_class_name("android.widget.Button")
(4)accessibility_id定位
find_element_by_accessibility_id(“content-desc”)
driver.find_element_by_accessibility_id("delete")
(5)xpath定位
find_element_by_xpath(“xpath”)
driver.find_element_by_xpath("//android.widget.Button[@text='8']")
(6)uiautomator定位
find_element_by_android_uiautomator(uia_string)
uiautomator可以针对resourceid、Text、description、class、package、index、instance等进行定位。
1)resourceId方式
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("%s")')
2)text方式
driver.find_element_by_android_uiautomator('new UiSelector().text("%s")')
3)description方式
driver.find_element_by_android_uiautomator('new UiSelector().description("%s")')
4)className方式
driver.find_element_by_android_uiautomator('new UiSelector().className("%s")')
5)packageName方式
driver.find_element_by_android_uiautomator('new UiSelector().packageName("%s")')
6)index方式
driver.find_element_by_android_uiautomator('new UiSelector().index("%s")')
7)instance方式
driver.find_element_by_android_uiautomator('new UiSelector().instance("%s")')
8)className+index方式
driver.find_element_by_android_uiautomator('new UiSelector().className("%s").childSelector(new UiSelector().index("%d"))')
9)伪xpath方法定位
a.通过同级元素定位同级元素
driver.find_element_by_android_uiautomator(‘new UiSelector().text("Custom View").fromParent(new UiSelector().text("Accessibility Service"))‘).click()
b.通过父级元素定位子集元素
driver.find_element_by_android_uiautomator(‘new UiSelector().className("android.widget.ListView").childSelector(new UiSelector().text("Custom View"))‘).click()
(7)用By定位
- By.ID #相当于by_id
- By.NAME #相当于by_name
- By.CLASS_NAME #相当于by_class_name
- By.ACCESSIBILITY_ID #相当于by_accessibility_id
- By.XPATH #相当于by_xpath
find_element(By.ID,"com.android.calculator2:id/digit8")
二、应用操作
(1)安装应用install_app()
#安装应用到设备中去。需要apk包的路径。
driver.install_app("path/to/my.apk")
driver.install_app("D:\\android\\apk\\ContactManager.apk")
(2)卸载应用remove_app()
#从设备中删除一个应用。
driver.remove_app("com.example.android.apis")
(3)关闭应用close_app()
#关闭打开的应用,默认关闭当前打开的应用,所以不需要入参。相当于按home键将应用置于后台,可以通过launch_app()再次启动。
driver.close_app()
(4)启动应用launch_app()
#该方法需要配合close_app()使用的。
driver.launch_app()
(5)检查应用是否安装is_app_installed()
#检查应用是否已经安装。需要传参应用包的名字。返回结果为Ture或False。
driver.is_app_installed('com.example.android.apis')
(6)将应用置于后台background_app()
#将当前活跃的应用程序发送到后台。这个方法需要入参,需要指定应用置于后台的时长。
driver.background_app(2)
(7)应用重置reset_app()
#重置当前被测程序到出始化状态。该方法不需要入参。
driver.reset_app()
(8)启动activitystart_activity()
#启动一个app或者在当前app中打开一个新的activity,仅适用于android。
driver.start_activity('com.example.android.apis', '.Foo')
三、键盘操作
ps:appium键值表
(1)send_keys()方法
driver.find_element_by_name(“Name”).send_keys("jack")
(2)keyevent()方法
`driver.keyevent(4)
#点击Android的返回键`
(3)press_keycode()方法
driver.press_keycode(3)
#点击Android的HOME键
(4)long_press_keycode()方法
driver.long_press_keycode(4)
#长按Android的返回键
(5)隐藏键盘
driver.hide_keyboard()
#android不需要参数,ios需要传参key_name
四、TouchAction操作
使用前导入TouchAction模块from appium.webdriver.common.touch_action import TouchAction
(1)点击tap(self,el=None,x=None,y=None,count=1)
(2)短按press(self, el=None, x=None, y=None)
(3)长按long_press(self, el=None, x=None, y=None, duration=1000(ms))
(4)释放release(self)
(5)移动到move_to(self,el=None,x=None,y=None)
(6)等待wait(self,ms=0)
(7)执行perform(self)
1
2
3
4
5 #关于perform官网给的伪代码中讲
TouchAction().tap(el).perform()
#与
driver.perform(TouchAction().tap(el))
#效果一致
(8)多点触控MultiTouch()
#多点触控,它只提供了两个方法:一个add()
、一个执行perform()
。
使用前导入MultiAction模块from appium.webdriver.common.multi_action import MultiAction
1
2
3
4
5
6 from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.common.multi_action import MultiAction
action0 = TouchAction().tap(el1)
action1 = TouchAction().tap(el2)
MultiTouch().add(action0).add(action1).perform()
五、上下文操作
(1)当前会话中的所有上下文,使用后可以识别H5页面的控件driver.contexts
获取的是一个list列表:
- NATIVE_APP:这个就是native,也就是原生的
- WEBVIEW_com.xxxx :这个就是webview
(2)当前会话的当前上下文driver.current_context
(3)切换上下文driver.switch_to.context("content_str")
1)切换到webview
方法一:
driver.switch_to.context('webview的context')
方法二:driver.switch_to.context(contexts[1])
#从contexts列表里取第二个参数2)切回native
方法一:
driver.switch_to.context("NATIVE_APP")
#这个NATIVE_APP是固定的参数
方法二:driver.switch_to.context(contexts[0])
#从contexts列表里取第一个参数
(4)应用的字符串driver.app_strings
六、屏幕操作
(1)点击
1)click()
driver.find_element_by_id("com.wuba.zhuanzhuan:id/ae8").click()
2)driver.tap()
driver.tap([(216,1776)],200)
(2)滑动driver.swipe(x1, y1, x2, y2,duration)
#从坐标(x1,x2)滑动到坐标(x2,y2),duration非必填项,滑动时间
一个向上下左右滑动的方法封装:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #获得屏幕大小宽和高
def getSize(driver):
x = driver.get_window_size()['width']
y = driver.get_window_size()['height']
return (x, y)
#屏幕向上滑动
def swipeUp(driver,t=1000):
l = getSize(driver)
x1 = int(l[0] * 0.5) #x坐标
y1 = int(l[1] * 0.75) #起始y坐标
y2 = int(l[1] * 0.25) #终点y坐标
driver.swipe(x1, y1, x1, y2,t)
#屏幕向下滑动
def swipeDown(driver,t=1000):
l = getSize(driver)
x1 = int(l[0] * 0.5) #x坐标
y1 = int(l[1] * 0.25) #起始y坐标
y2 = int(l[1] * 0.75) #终点y坐标
driver.swipe(x1, y1, x1, y2,t)
#屏幕向左滑动
def swipLeft(driver,t):
l=getSize(driver)
x1=int(l[0]*0.75)
y1=int(l[1]*0.5)
x2=int(l[0]*0.05)
driver.swipe(x1,y1,x2,y1,t)
#屏幕向右滑动
def swipRight(driver,t=1000):
l=getSize(driver)
x1=int(l[0]*0.05)
y1=int(l[1]*0.5)
x2=int(l[0]*0.75)
driver.swipe(x1,y1,x2,y1,t)
#调用向下滑动的方法
swipeDown(driver)
(3)滚动driver.scroll(origin_el,destination_el)
(4)拖动driver.drag_and_drop(el1,el2)
(5)快速滑动driver.flick(start_x, start_y, end_x, end_y)
(6)缩小driver.pinch(element)
(7)放大driver.zoom(element)
(8)锁屏driver.lock()
#android不需要传参,ios可以传参锁屏多少秒
(9)截屏get_screenshot_as_file()
driver.get_screenshot_as_file('../screenshot/foo.png')
#保存的图片路径和名称
(10)屏幕旋转rotate(ScreenOrientation orientation)
- landscape:限制界面为横屏,旋转屏幕也不会改变当前状态。
- portrait:限制界面为竖屏,旋转屏幕也不会改变当前状态。
- sensor:根据传感器定位方向,旋转手机90度,180,270,360,界面都会发生变化。
- sensorLandscape:(横屏的旋转,不会出现竖屏的现象)根据传感器定位方向,旋转手机180度界面旋转。一般横屏游戏会是这个属性。
- sensorPortrait:(竖屏的旋转,不会出现横屏的现象)根据传感器定位方向,旋转手机180度界面会旋转。
- unspecified:由系统选择显示方向,不同的设备可能会有所不同。(旋转手机,界面会跟着旋转)
- user: 用户当前的首选方向。
- nosensor:不由传感器确定方向。旋转设备的时候,界面不会跟着旋转。初始界面方向由系统提供。
(11)获取当前屏幕的方向get_orientation()
七、网络设置
(1)返回网络类型数值driver.network_connection
(2)网络设置driver.setNetworkConnection(bitmask掩码)
使用前导入ConnectionType模块from appium.webdriver.connectiontype import ConnectionType
driver.set_network_connection(2)
driver.set_network_connection(ConnectionType.WIFI_ONLY)
网络的bitmask掩码如下:
值 (别名) | 数据连接 | Wifi连接 | 飞行模式 |
---|---|---|---|
0 (NO_CONNECTION) | 0 | 0 | 0 |
1 (AIRPLANE_MODE) | 0 | 0 | 1 |
2 (WIFI_ONLY) | 0 | 1 | 0 |
4 (DATA_ONLY) | 1 | 0 | 0 |
6 (ALL_NETWORK_ON) | 1 | 1 | 0 |
八、位置设置
(1)打开定位设置driver.toggle_location_services()
(2)设置设备的经纬度driver.set_location(latitude纬度,longitude经度,altitude海拔高度)
九、文件操作
(1)把本地文件push到设备上。push_file()
1
2
3 data = "some data for the file"
path = "/data/local/tmp/file.txt"
driver.push_file(path, data.encode('base64'))
(2)将设备上的文件pull到本地硬盘上pull_file()
driver.pull_file('Library/AddressBook/AddressBook.sqlitedb')
(3)将设备上的文件夹pull到本地硬盘上,一般远程文件为/data/local/tmp下的文件。pull_folder()
十、activity操作
(1)启动activitydriver.start_activity()
(2)获取当前activitydriver.current_activity
1
2 activity = self.driver.current_activity
print(u"当前的activity是:", activity)
(3)等待activity启动直到x秒超时,每隔y秒扫描一次driver.wait_activity(activity, x, y)
(4)检查是否存在某个activity(未找到则返回异常)driver.find_element_by_id(activity)
ps:查看包名和activity的方法:
1
2
3
4
5
6 # 1)启动应用,输入命令,查看
adb shell dumpsys window | findstr mCurrentFocus
# 2)启动应用,输入命令,查看
adb shell dumpsys activity activities
# 3)有安装包,cmd输入命令,查看
aapt dump badging <file_path.apk>
十一、其他操作
(1)打开通知栏driver.open_notifications()
(2)摇一摇手机driver.shake()
(3)获取控件各种属性get_attribute()
可获取的字符串类型:
- name(返回content-desc或text)
- text(返回text)
- className(返回class,只有API=>18才能支持)
- resourceId(返回resource-id,只有API=>18才能支持)
- …uiautomator获得的属性
driver.find_element_by_id().get_attribute(name)
(4)返回元素是否选择element.is_slected()
(5)返回元素是否可用element.is_enabled()
(6)返回元素的文本值element.text()
(7)清除输入的内容element.clear()
(8)获取元素的大小driver.element.size
- new_size[“height”] = size[“height”]
- new_size[“width”] = size[“width”]
(9)获取元素左上角的坐标driver.element.location
1
2
3
4 #返回element的x坐标, int类型
driver.element.location.get('x')
#返回element的y坐标, int类型
driver.element.location.get('y')
十二、unittest断言
在unittest单元测试框架中,TestCase类提供了一些方法来检查并报告故障:
(1)assertEqual(first, second, msg=None)
#判断first和second的值是否相等,如果不相等则测试失败,msg用于定义失败后所抛出的异常信息。
(2)assertNotEqual(first, second, msg=None)
#测试first和second不相等,如果相等,则测试失败。
(3)assertTure(expr,msg=None)
(4)assertFalse(expr,msg=None)
#测试expr为Ture(或为False)
(5)assertIs(first, second, msg=None)
(6)assertIsNot(first, second, msg=None)
#测试的first和second是(或不是)相同的对象。
(7)assertIsNone(expr, msg=None)
(8)assertIsNotNone(expr, msg=None)
#测试expr是(或不是)为None
(9)assertIn(first, second, msg=None)
(10)assertNotIn(first, second, msg=None)
#测试first是(或不是)在second中。second包含是否包含first。
十三、脚本设计原则
(1)LOVE原则(NativeApp):
1)Locate定位元素
2)Operate操作元素
3)Verify验证结果
4)Exception异常处理
(2)S-LOVE原则(HybridApp):
1)Switch切换上下文
2)Locate定位元素
3)Operate操作元素
4)Verify验证结果
5)Exception异常处理
持续更新…
最后更新: 2018年05月11日 14:54