Appium Android定位元素與操作


文章寫得很好,轉載備用
一、常用識別元素的工具
uiautomator:Android SDK自帶的一個工具,在tools目錄下
monitor:Android SDK自帶的一個工具,在tools目錄下
Appium Inspector:Appium自帶的一個功能,只有mac下可以使用該功能
 
下面是用monitor抓取到的頁面元素
 
 
下面使用Appium Inspector定位的元素
 
二、元素定位
 
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("new UiSelector().text(\"+關注\")")
 
使用這里需要注意一下,通過text定位的結果是個list,不能直接click。所以如果要點擊需要取數組的值,比如下面是點擊找到的第一個元素
driver.find_elements_by_android_uiautomator("new UiSelector().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)
需要導入這個包:from selenium.webdriver.common.by import By
 
例如:定位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_id
By.CLASS_NAME  相當於by_class_name
By.XPATH   相當於by_xpath
By.NAME   相當於by_name
By.TAG_NAME   相當於by_tag_name
By.CSS_SELECTOR  相當於by_css_selector
By.LINK_TEXT  相當於by_link_text
 
 
3.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(xx)
//輸入框內輸入內容
driver.find_element_by_id("com.wuba.zhuanzhuan:id/ij").send_keys("test content")
 
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非必填項,滑動時間
(滑動的坐標不能超過屏幕的寬高)
可以通過【driver.get_window_size()】命令獲得窗口高和寬,結果為{'width': 1080, 'height': 1776}
 
一個鼠標向上下左右活動的例子如下:
#獲得屏幕大小寬和高
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)
 
 
五、系統按鍵事件
 
 press_keycode(AndroidKeyCode)//發送按鍵事件
例如:點擊home鍵,home鍵的KeyCode是3
driver.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可以查看下面的博客:
 
 
六、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
//獲得所有contexts
driver.contexts
 
結果如下:
['NATIVE_APP', 'WEBVIEW_com.android.browser']
 
NATIVE_APP:native的context
WEBVIEW_com.android.browser:webview的context,存放html的容器
 
4.current_context
//查看當前的context
driver.current_context
 
5.switch_to.context(context名)
//切換context
driver.switch_to.context("WEBVIEW_com.wuba.zhuanzhuan")
 
NATIVE時不能定位WEBVIEW的內容,在WEBVIEW的context時不能定位NATIVE的內容。
所以需要切換到對應的context中去進行操作
 
6.setNetworkConnection(bitmask掩碼)
//設置網絡類型
例如:設置網絡類型為只開wifi
driver.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.補充一些driver啟動時可能用到的項
其實這些在上一篇啟動里都有介紹,但是有些可能大家沒注意到的點再列一下。這些點也是我在測試中實際遇到的點
 
autoLaunch :Appium是否要自動啟動或安裝app,默認true
desired_caps['autoLaunch'] = 'false'
有的時候我不想讓appium每次都啟動app,想自己去啟動activity,那這個項這時就可以起作用了
 
noReset:在會話前是否重置app狀態。默認是false
desired_caps['noReset'] = 'true'
 
newCommandTimeout:設置未接收到新命令的超時時間,默認60s
如果60s內沒有接收到新命令,appium會自動斷開連接,如果我需要很長時間做driver之外的操作,可能延長接收新命令的超時時間
desired_caps["newCommandTimeout"]=1800

 

https://i.cnblogs.com/EditPosts.aspx?opt=1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM