Appium+Python之元素定位和操作,,一、常用识别元素的工


一、常用识别元素的工具uiautomatorviewer:Android SDK自带的一个工具,在tools目录下技术分享图片二、元素定位1.格式:find_element_by_定位方式(value)通过id定位(取resource-id的值):driver.find_element_by_id("com.wuba.zhuanzhuan:id/azo")也可以直接用id后面的内容driver.find_element_by_id("azo")通过class_name定位(取class的内容)driver.find_element_by_class_name("android.widget.RelativeLayout")通过xpath定位(取xpath得内容)driver.find_element_by_xpath("//android.widget.LinearLayout[1]/android.widget.XXX")通过text定位(需要使用uiautomator的定位方式,使用text的内容)driver.find_elements_by_android_uiautomator("newUiSelector().text(\"+关注\")")使用这里需要注意一下,通过text定位的结果是个list,不能直接click。所以如果要点击需要取数组的值,比如下面是点击找到的第一个元素driver.find_elements_by_android_uiautomator("newUiSelector().text(\"+关注\")")[0].click()通过css_selector定位(webview)只适用于webview的html页面,继承自webdriver,与pc版本的UI测试一致driver.find_element_by_css_selector()通过link_text定位(webview)只适用于webview容器中的html页面,继承自webdriver,与pc版本的UI测试一致driver.find_element_by_link_text()通过name定位web view容器中的html页面可以用name定位,native并没有name属性driver.find_element_by_name()2.定位元素的另一种写法:find_element(by,value)find_element_by_方式(value)实际调用的都是find_element(by,value)需要导入这个包:fromselenium.webdriver.common.byimportBy例如:定位id为ag2的元素方式一:driver.find_element_by_id("ag2)方式二:driver.find_element(By.ID,"ag2")这个操作的好处是可以直接把操作的by和value放到一个元组里,然后调用通用方法来传参获得元素结果cateid=(By.ID,"ag2")driver.find_element(*cateid).click()by的操作可以是:By.ID 相当于by_idBy.CLASS_NAME 相当于by_class_nameBy.XPATH 相当于by_xpathBy.NAME 相当于by_nameBy.TAG_NAME 相当于by_tag_nameBy.CSS_SELECTOR 相当于by_css_selectorBy.LINK_TEXT 相当于by_link_text3.find_elements_by_定位方式(value)返回元素数组用法与find_element_by_方式(value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果例如:通过class_name定位到多个元素,我想点击第一个元素driver.find_elements_by_class_name("android.widget.RelativeLayout)[0].click()4.返回元素数组的另一种写法:find_elements(by,value)用法与find_element(by,value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果例如:通过class_name定位到多个元素,我想点击第一个元素driver.find_elements(By.CLASS_NAME,"android.widget.RelativeLayout)[0].click()5.通过元素定位元素可以先找到某个元素,然后再进一步定位元素find_element_by_class_xpath(“xxx”).find_element_by_name(“yyy")三、元素操作找到元素后可以对元素进行的操作,例如上面讲的进一步定位元素1.click()//点击操作也可以用tab实现点击操作driver.find_element_by_id("com.wuba.zhuanzhuan:id/ae8").click()2.clear()//清空输入框内容driver.find_element_by_id("com.wuba.zhuanzhuan:id/ij").clear()3.send_keys(xx)//输入框内输入内容driver.find_element_by_id("com.wuba.zhuanzhuan:id/ij").send_keys("testcontent")4.text//获得元素的text内容print(driver.find_element_by_xpath("//android.widget.LinearLayout[1]//xxx").text)四、触摸操作1.driver.tap([坐标],持续点击时间)除了定位到元素的点击外,也可以通过tab实现坐标的点击driver.tap(driver.tap([(216,1776)],2))2.TouchAction(driver)TouchAction对象包含(tab)、press(短按)、move_to(滑动到某个坐标)等方法通过TouchAction对象,添加tap、move_to等操作,然后perform()执行,可以实现解锁屏幕等功能规范中的可用事件有:* 短按 (press)
* 释放 (release)
* 移动到 (moveTo)
* 点击 (tap)
* 等待 (wait)
* 长按 (longPress)
* 取消 (cancel)* 执行 (perform)技术分享图片例如:一个多次滑屏的例子:action=TouchAction(driver)action.press(x=220,y=700).move_to(x=840,y=700).move_to(x=220,y=1530).move_to(x=840,y=1530).release().perform()可以通过wait()等待操作3.MultiAction()//多点触控通过MultiAction().add()添加多个TouchAction操作,最后调用perform()一起执行这些操作action0 = TouchAction().tap(el)action1 = TouchAction().tap(el)MultiAction().add(action0).add(action1).perform()4.driver.swipe(x1,y1,x2,y2,duration) //从坐标(x1,x2)滑动到坐标(x2,y2),duration非必填项,默认滑动时间5ms(滑动的坐标不能超过屏幕的宽高)可以通过【driver.get_window_size()】命令获得窗口高和宽,结果为{‘width‘: 1080, ‘height‘: 1776}一个鼠标向上下左右活动的例子如下:#获得屏幕大小宽和高
defgetSize(driver):
x=driver.get_window_size()[‘width‘]
y=driver.get_window_size()[‘height‘]
return(x,y)

#屏幕向上滑动
defswipeUp(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)

#屏幕向下滑动
defswipeDown(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)
#屏幕向左滑动
defswipLeft(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)
#屏幕向右滑动
defswipRight(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)五、系统按键事件press_keycode(AndroidKeyCode)//发送按键事件例如:点击home键,home键的KeyCode是3driver.press_keycode(3)键名 描述 键值
KEYCODE_CALL 拨号键 5
KEYCODE_ENDCALL 挂机键 6
KEYCODE_HOME 按键Home 3
KEYCODE_MENU 菜单键 82
KEYCODE_BACK 返回键 4
KEYCODE_SEARCH 搜索键 84
KEYCODE_CAMERA 拍照键 27
KEYCODE_FOCUS 拍照对焦键 80
KEYCODE_POWER 电源键 26
KEYCODE_NOTIFICATION通知键 83
KEYCODE_MUTE 话筒静音键 91
KEYCODE_VOLUME_MUTE扬声器静音键 164
KEYCODE_VOLUME_UP 音量增加键 24
KEYCODE_VOLUME_DOWN音量减小键 25更多KeyCode可以查看下面的博客:http://blog.csdn.net/crisschan/article/details/50419963六、driver的一些比较重要操作1.reset()//重置app这时候driver会重置,相当于卸载重装应用。所以本地缓存会失效driver.reset()2.start_activity(包名,activity名)//启动app的某一个activity例如:driver.start_activity("com.wuba.zhuanzhuan","./presentation.view.activity.LaunchActivity")启动一个activity,这个activity必须是AndroidManifest.xml中有intent-filter的activity<intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/></intent-filter>这种启动activity和driver的reset()不同的是3.contexts//获得所有contextsdriver.contexts结果如下:[‘NATIVE_APP‘, ‘WEBVIEW_com.android.browser‘]NATIVE_APP:native的contextWEBVIEW_com.android.browser:webview的context,存放html的容器4.current_context//查看当前的contextdriver.current_context5.switch_to.context(context名)//切换contextdriver.switch_to.context("WEBVIEW_com.wuba.zhuanzhuan")NATIVE时不能定位WEBVIEW的内容,在WEBVIEW的context时不能定位NATIVE的内容。所以需要切换到对应的context中去进行操作6.setNetworkConnection(bitmask掩码)//设置网络类型例如:设置网络类型为只开wifidriver.set_network_connection(2)网络的bitmask掩码如下:| 值 (别名) | 数据连接 | Wifi 连接 | 飞行模式 || ------------------ | ---- | ---- | ------------- || 0 (什么都没有) | 0 | 0 | 0 || 1 (飞行模式) | 0 | 0 | 1 || 2 (只有Wifi) | 0 | 1 | 0 || 4 (只有数据连接) | 1 | 0 | 0 || 6 (开启所有网络) | 1 | 1 | 0 |7.scroll(起始元素,结束元素)driver.scroll(origin_el,destination_el)8.获得当前页面的所有元素driver.page_source这可以用来判断元素是否存在,例如assert"发布成功"indriver.page_source)9.补充一些driver启动时可能用到的项其实这些在上一篇启动里都有介绍,但是有些可能大家没注意到的点再列一下。这些点也是我在测试中实际遇到的点autoLaunch :Appium是否要自动启动或安装app,默认truedesired_caps[‘autoLaunch‘]=‘false‘有的时候我不想让appium每次都启动app,想自己去启动activity,那这个项这时就可以起作用了noReset:在会话前是否重置app状态。默认是falsedesired_caps[‘noReset‘]=‘true‘newCommandTimeout:设置未接收到新命令的超时时间,默认60s如果60s内没有接收到新命令,appium会自动断开连接,如果我需要很长时间做driver之外的操作,可能延长接收新命令的超时时间desired_caps["newCommandTimeout"]=1800参考地址:https://www.cnblogs.com/meitian/p/6103391.html

Appium+Python之元素定位和操作

评论关闭