Android 自動化測試


Python +Android +uiautomator test  在init中定義的方法

 

 

 

uiautomator

 

建立 覆蓋狀態 皮皮 下載

該模塊是android的一個python包裝uiautomator測試框架。它適用於Android 4.1+,只需通過adb連接Android設備,無需在Android設備上安裝任何東西。

從 uiautomator 進口設備的 ð d.screen.on() D(id= “時鍾”)。點擊()

安裝

$ pip install uiautomator

前提條件

  • 安裝Android的SDK,並設置ANDROID_HOME環境以正確的路徑。
  • 啟用設備上的ADB設置,並使用USB連接您的Android設備與您的電腦。

導入uiautomator

  • 如果ANDROID_SERIAL在環境中定義的,或只有一個連接的設備:

    從 uiautomator 進口設備的 ð
  • 檢索設備對象時,限制序列號

    從 uiautomator 進口設備 ð =設備(' 014E05DE0F02000E “)
  • speficy在其他計算機上運行的adb服務器主機和端口

    雖然亞行支持-a選項SDK 4.3以來,但現在它有一個bug。在所有接口而不是localhost上啟動adb服務器偵聽的唯一方法是adb -a -P 5037 fork-server server &

    從 uiautomator 進口設備 ð =設備(' 014E05DE0F02000E ',adb_server_host = “ 192.168.1.68 ”,adb_server_port = 5037)

注:在下面的例子中,我們使用d代表Android設備對象。

目錄

基本API用法

觀察者介紹

處理程序介紹

選擇器介紹

基本API用法

此部分通過一些簡單的示例顯示設備的正常操作。

  • 檢索設備信息

    d.info

    以下是可能的結果:

    { u'displayRotation': 0,
      u'displaySizeDpY': 640,
      u'displaySizeDpX': 360,
      u'currentPackageName': u'com.android.launcher',
      u'productName': u'takju',
      u'displayWidth': 720,
      u'sdkInt': 18,
      u'displayHeight': 1184,
      u'naturalOrientation': True
    }
    

關鍵事件設備的操作

  • 打開/關閉屏幕

    #在屏幕上打開 d.screen.on() 關閉屏幕 d.screen.off() 

    替代方法是:

    #喚醒設備 d.wakeup() 睡眠設備,一樣關閉屏幕。 d.sleep() 
  • 按硬/軟鍵

    #按home鍵 d.press.home() 按返回鍵 d.press.back() 正常的方式按返回鍵 d.press( ”) 按下鍵碼0×07(0)與元ALT (0X02)上 d.press( 0x的 07, 0X 02) 
  • 目前支持下列鍵:

    • home
    • back
    • left
    • right
    • up
    • down
    • center
    • menu
    • search
    • enter
    • delete(或del
    • recent(最近的應用程式)
    • volume_up
    • volume_down
    • volume_mute
    • camera
    • power

    你可以找到所有關鍵代碼定義的Android的KeyEvent

手勢設備的交互

  • 單擊屏幕

    #點擊(X,Y)在屏幕上 d.click(X,Y)
  • 長按屏幕

    #長按(X,Y)在屏幕上 d.long_click(X,Y)
  • 滑動

    #從(SX,SY)輕掃(EX,EY) d.swipe(SX,SY,EX,EY) 從(SX,SY)輕掃(EX,EY)與10個步驟 d.swipe(SX,SY ,前,安永,步驟= 10) 
  • 拖動

    #從(SX,SY)拖動(EX,EY) d.drag(SX,SY,EX,EY) 從(SX,SY)拖動(EX,EY)與10個步驟 d.drag(SX,SY ,前,安永,步驟= 10) 

屏幕設備的操作

  • 檢索/設置方向

    可能的方向是:

    • natural 要么 n
    • left 要么 l
    • right 要么 r
    • upsidedownu(不能設定)
    #檢索方向,也可能是“天然”或“左”或“右”或“upsidedown” 方向 = d.orientation #設置定向和凍結旋轉。 #指出:“upsidedown”不能設置到Android 4.3的。 d.orientation = “升#或“左”的 d.orientation = “ - [R ”  #或“右” d.orientation = “ ñ #或“自然”
  • 凍結/取消凍結旋轉

    #凍結旋轉 d.freeze_rotation() 取消凍結旋轉 d.freeze_rotation(假) 
  • 截取屏幕截圖

    #采取截圖並保存到本地文件“home.png”,直到Android 4.2或不能工作。 d.screenshot( “ home.png ”)
  • 轉儲窗口層次結構

    #轉儲widown層次結構並保存到本地文件“hierarchy.xml” d.dump( “ hierarchy.xml ”) #或獲得回報傾倒內容(Unicode)的。 XML = d.dump()
  • 打開通知或快速設置

    #開放的通知,不能工作,直到Android 4.3的。 d.open.notification() 開啟快速設定,不能工作,直到Android 4.3的。 d.open.quick_settings() 
  • 等待空閑或窗口更新

    #等待當前窗口空閑 d.wait.idle() 等待,直到窗口更新事件發生 d.wait.update() 

觀察者

你可以注冊守望者執行某些動作時,選擇器不能找到匹配。

  • 注冊觀察者

    當選擇器找不到匹配項時,uiautomator將運行所有注冊的觀察器。

    • 條件匹配時點擊目標
    d.watcher( “ AUTO_FC_WHEN_ANR ”)。當(= “ ANR ”)。當(= “等待”)\ 。點擊(文字= “強制關閉”) # d.watcher(名)##創建一個新的命名觀察者。 # 。當(條件)##觀察者的UiSelector條件。 # 。點擊(目標)##執行對目標UiSelector點擊動作。
    • 條件匹配時按鍵
    d.watcher( “ AUTO_FC_WHEN_ANR ”)。當(= “ ANR ”)。當(= “等待”)\ .press.back.home() 另類的方式來定義它,如下 d.watcher(  AUTO_FC_WHEN_ANR ”)。當(=  ANR ”)。當(= 等待”)\ 。按(”,”)  d.watcher(名)##創建一個新的名為守望。 。當(條件)##觀察者的UiSelector條件。 。按<鍵名> ...... <鍵名>。()##按下按鍵逐個順序。 Alternavie方式定義按鍵順序是按(<keybname>,...,<鍵名>) 
  • 檢查命名的監視器是否觸發

    觸發觀察者,這意味着觀察者運行並且其所有條件都匹配。

    d.watcher( “ watcher_name ”).triggered #真在指定守望的情況下觸發,否則為假
  • 刪除命名監視器

    #刪除觀察者 d.watcher( “ watcher_name ”)上卸下擺臂()
  • 列出所有觀察者

    d.watchers
     #所有注冊wachers'名稱的列表
  • 檢查是否有任何觀察者觸發

    d.watchers.triggered
     # 真正的觸發任何看守的情況下,
  • 重置所有觸發的觀察者

    #重置所有觸發觀察家,在那之后,d.watchers.triggered會是假的。 d.watchers.reset()
  • Remvoe觀察者

    #刪除所有已注冊的觀察家 d.watchers.remove() 刪除指定的守望者一樣,同樣d.watcher(“watcher_name”)。remove()方法 d.watchers.remove(  watcher_name ”) 
  • 強制運行所有觀察者

    #力量來運行所有注冊的觀察者 d.watchers.run()

處理程序

處理程序的功能與Watcher相同,只是它實現了我們的Android uiautomator。處理程序和觀察程序之間最不同的用法是,處理程序可以使用自定義的回調函數。

高清 fc_close(設備): 如果設備(= '強制關閉“).exists: 設備(= '強制關閉”)。點擊() 返回 #返回True手段打破處理程序回調函數的循環。 #在處理回調函數反過來 d.handlers.on(fc_close) 關閉句柄回調函數 d.handlers.off(fc_close) 

選擇器

選擇器是標識當前窗口中的特定ui對象。

#要入圍對象,文字是“時鍾”和它的類名是“android.widget.TextView' D(= '時鍾',的className = ' android.widget.TextView ')

選擇器支持以下參數。請參閱UiSelector DOC java的詳細信息。

  • texttextContainstextMatchestextStartsWith
  • className, classNameMatches
  • descriptiondescriptionContainsdescriptionMatchesdescriptionStartsWith
  • checkablecheckedclickablelongClickable
  • scrollableenabledfocusablefocusedselected
  • packageName, packageNameMatches
  • resourceId, resourceIdMatches
  • index, instance

子對象和同級UI對象

  • 兒童

    #得到孩子或孫子 D(的className = “ android.widget.ListView ”).child(= “藍牙”)
  • 兄弟

    #得到同胞的兄弟姐妹或子女 D(= “谷歌”).sibling(的className = “ android.widget.ImageView ”)
  • 子文本或描述或實例

    #得到孩子匹配的className =“android.widget.LinearLayout” #而且它或它的子女或孫子包含文本“藍牙” D(的className = “ android.widget.ListView ”, RESOURCEID = “機器人:ID /列表”) \ .child_by_text( “藍牙”,的className = “ android.widget.LinearLayout ”)允許滾動搜索,獲得子 D(的className =  android.widget.ListView ”, RESOURCEID = 機器人:ID /列表”)\ 。 child_by_text( 藍牙”,  allow_scroll_search = 真, 的className =  android.widget.LinearLayout ” ) 
    • child_by_description是找到子哪個或哪些是孫子包含指定的描述中,其他是相同的child_by_text

    • child_by_instance是在其子層次結構中指定實例的任何位置找到具有子UI元素的子項。這是一個沒有可見的意見進行滾動。

    詳情請參閱以下鏈接:

    • UiScrollablegetChildByDescriptiongetChildByTextgetChildByInstance
    • UiCollectiongetChildByDescriptiongetChildByTextgetChildByInstance

    上面的方法支持鏈接調用,例如對於下層

    < 節點 指數 = “ 0 文本 = 資源ID = “機器人:ID /列表級 = “ android.widget.ListView ” ...> < 節點 指數 = “ 0 文本 = “ WIRELESS & NETWORKS 資源-id = 類 = “ android.widget.TextView ” ... /> < 節點 索引 = “ 1 文本 = 資源ID = 類 = “ android.widget.LinearLayout ” ...> < 節點 指數 = “ 1 文本 = 資源ID = 級 = “ android.widget.RelativeLayout ” ...> < 節點 指數 = “ 0 文本 = “無線網絡連接資源ID = “機器人: ID /標題級 = ” android.widget.TextView “ ... /> </ 節點 > < 節點 指數 = ” 2 文本 = ” ON 資源ID = ” com.android.settings:ID / switchWidget 類 = “ android.widget.Switch ” ... /> </ 節點 > ... </ 節點 >

    設置

    我們要點擊文本“Wi-Fi”右側的開關打開/打開Wi-Fi。因為有幾個開關,幾乎相同的屬性,所以我們不能使用類似d(className="android.widget.Switch")選擇的UI對象。相反,我們可以使用下面的代碼來選擇它。

    D(的className = “ android.widget.ListView ”,RESOURCEID = “機器人:ID /列表”)\ .child_by_text( “無線網絡連接”,的className = “ android.widget.LinearLayout ”)\ .child(的className = “機器人.widget.Switch “)\ 。點擊()
  • 相對位置

    此外,我們可以用相對位置的方法來獲取視圖:leftrighttopbottom

    • d(A).left(B),意味着在左側選擇B。
    • d(A).right(B),表示選擇A右側的B.
    • d(A).up(B),表示選擇B以上的A.
    • d(A).down(B),表示在A下選擇B.

    所以對於上面的情況,我們可以寫代碼:

    ##選擇的“無線網絡連接”右側的“開關” D(= “無線網絡連接”).right(的className = “ android.widget.Switch ”)。點擊()
  • 多個實例

    有時,屏幕可能包含多個視圖與相同的例如文本,那么你將不得不使用選擇器中的“實例”屬性,如下所示:

    D(= “新增”,比如= 0) #這意味着一審文本“新增”

    但是,uiautomator提供了類似的方法來使用它。

    #得到的文本意見的計當前屏幕上的“添加新的” D(= “新增”).Count之間一樣count屬性LEN(D(= 新增”)) 通過索引獲取實例 ð (= 新增”)[ 0 ] D(= 新增”)[ 1 ]  ... 迭代器的視圖中 D(= 添加新”): view.info  ... 

    注意:當您使用選擇喜歡的列表,你必須確保屏幕保持不變,否則你可能會得到UI未找到錯誤。

獲取所選的ui對象狀態及其信息

  • 檢查特定ui對象是否存在

    D(= “設置”).exists #是否存在真,否則假 d.exists(= “設置”)#以上財產的別名。
  • 檢索特定ui對象的信息

    D(= “設置”).INFO

    以下是可能的結果:

    { u'contentDescription': u'',
      u'checked': False,
      u'scrollable': False,
      u'text': u'Settings',
      u'packageName': u'com.android.launcher',
      u'selected': False,
      u'enabled': True,
      u'bounds': {u'top': 385,
                  u'right': 360,
                  u'bottom': 585,
                  u'left': 200},
      u'className': u'android.widget.TextView',
      u'focused': False,
      u'focusable': True,
      u'clickable': True,
      u'chileCount': 0,
      u'longClickable': True,
      u'visibleBounds': {u'top': 385,
                         u'right': 360,
                         u'bottom': 585,
                         u'left': 200},
      u'checkable': False
    }
    
  • 設置/清除可編輯字段的文本

    D(= “設置”).clear_text() #清除文字 D(= “設置”).set_text( “我的文字...... ”) #設置文本

對選中的ui對象執行單擊操作

  • 點擊特定的ui對象

    #點擊特定的UI對象的中心 D(= “設置”)。單擊() #點擊具體的UI對象的bottomright角落 D(= “設置”)).click.bottomright( #請點擊具體的UI對象的左上邊角 D(= “設置”).click.topleft() #點擊等到新窗口更新 D(= “設置”).click.wait()
  • 長時間點擊特定的ui對象

    #長按一下特定的UI對象的中心 D(= “設置”).long_click() #長按具體的UI對象的bottomright角落 D(= “設置”).long_click.bottomright() #長按具體的UI對象的左上邊角 D(= “設置”).long_click.topleft()

針對特定ui對象的手勢動作

  • 將ui對象拖動到另一個點或ui對象

    #注:拖不能設置到Android 4.3的。 #拖拽的UI對象,以點(X,Y) D(= “設置”).drag.to(X,Y,步驟= 100) #拖拽的UI對象到另一個UI對象(中心), D(= “設置“).drag.to(= ”時鍾“,步驟= 50)
  • 從ui對象的中央滑動到其邊緣

    滑動支持4個方向:

    • left
    • right
    • top
    • bottom
    D(= “設置”).swipe.right() D(= “設置”).swipe.left(步驟= 10), D(= “設置”).swipe.up(步驟= 10), D(文字= “設置”).swipe.down()
  • 兩點手勢從一個點到另一個點

    D(= “設置”).gesture((SX1,SY1),(SX2,SY2))\ 。要((EX1,EY1),(EX2,EY2))
  • 在特定ui對象的兩點姿態

    支持兩種手勢:

    • In,從邊到中心
    • Out,從中心到邊緣
    #注:捏不能設置到Android 4.3的。 #從邊緣到中心。這里是“在”不“,在” D(= “設置”).pinch.In(百分比= 100,= 10) #從中心到邊緣 D(= “設置”).pinch.Out()
  • 等待特定ui對象出現或消失

    #等到UI對象出現 D(= “設置”).wait.exists(超時= 3000) #等待,直到UI對象轉眼 D(= “設置”).wait.gone(超時= 1000)
  • 對特定的ui對象執行fling(可滾動)

    可能的屬性:

    • horiz 要么 vert
    • forwardbackwardtoBeginningtoEnd
    #一扔前進(默認)垂直(默認) D(滾動= 真).fling() #一扔前進horizentally D(滾動= 真).fling.horiz.forward() #一扔向后垂直 D(滾動= 真).fling .vert.backward() #一扔到horizentally開始 D(滾動= 真).fling.horiz.toBeginning( max_swipes = 1000) #來結束垂直一扔 D(滾動= 真).fling.toEnd()
  • 在特定的ui對象上滾動(可滾動)

    可能的屬性:

    • horiz 要么 vert
    • forwardbackwardtoBeginningtoEndto
    #向前滾動(默認)垂直(默認) D(滾動= 真).scroll(步驟= 10) #向前滾動horizentally D(滾動= 真).scroll.horiz.forward(步驟= 100) #向后滾動垂直 D(滾動= 真).scroll.vert.backward() #滾動到horizentally開始 D(滾動= 真).scroll.horiz.toBeginning(步驟= 100, max_swipes = 1000) #滾動到年底垂直 D(滾動= 真)。 scroll.toEnd() #向前滾動,直到垂直特定的UI對象出現 D(滾動= 真).scroll.to(= “安全性”)

貢獻

  • 分叉repo,並克隆到您的計算機。
  • 從檢出一個新分支develop的分支
  • 安裝要求: pip install -r requirements.txt
  • 進行更改,然后更新測試。不要忘記在“提供者”部分的末尾添加您的姓名
  • 通過所有的測試和代碼必須包括:tox
  • 提交你的修改,並提交拉請求develop分支。

貢獻者

問題和討論

如果您有任何錯誤報告或煩惱請報告給我們的問題跟蹤GitHub的問題

如果你有你想討論任何建議,新的功能要求或話題,請提交您的主題ostio

筆記

  • Android的uiautomator適用於Android 4.1及以上版本,所以在使用它之前,請確保你的設備是Android4.1 +。
  • 有些方法僅工作在Android 4.2 / 4.3,所以你最好閱讀詳細uiautomator的Java文檔在使用它之前。
  • 該模塊采用uiautomator-jsonrpc服務器作為后台程序與設備進行通信。
  • 該模塊僅在python2.7 / 3.2 / 3.3 / pypy上測試。

常問問題

  • 無法啟動JSONRPC服務器: raise IOError("RPC server not started!")

    它可能是由網絡,設備或環境引起的。因此,當您遇到此問題,請按照以下步驟,嘗試手動啟動JSONRPC服務器。

    1. 從下載jar文件uiautomator jsonrpc服務器

    2. Adb將下載的jar文件推送到 /data/local/tmp/

    3. 通過命令啟動jsonrpc服務器:

      adb shell uiautomator runtest bundle.jar uiautomator-stub.jar -c com.github.uiautomatorstub.Stub
      
    4. Adb將本地端口轉發到設備端口:

      adb forward tcp:9008 tcp:9008
      
    5. 檢查jsonrpc服務器是否正常:

      curl -d '{"jsonrpc":"2.0","method":"deviceInfo","id":1}' localhost:9008/jsonrpc/0
      

      如果你看到類似的消息{"jsonrpc":"2.0","id":1,"result":{"currentPackageName":"android","displayHeight":1280,"displayRotation":0,"displaySizeDpX":0,"displaySizeDpY":0,"displayWidth":720,"productName":"falcon","sdkInt":17,"naturalOrientation":true}},則表示服務器已啟動。

    如果你可以手動啟動jsonrpc服務器,但你的腳本總是滿足IOError("RPC server not started!"),請提交問題github上的問題

  • 錯誤 httplib.BadStatusLine: ''

    JsonRPC服務器需要訪問設備上的臨時目錄,但在一些低層設備上,它可能會遇到錯誤,在訪問臨時文件沒有連接SD卡。因此,如果您遇到錯誤,請插入SD卡,然后重試。


免責聲明!

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



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