您好,登錄后才能下訂單哦!
今天小編給大家分享一下Android自動(dòng)化測(cè)試如何處理各種彈窗的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
安裝APP時(shí)的系統(tǒng)彈窗 此類(lèi)彈窗一般有兩種,一種是自動(dòng)化測(cè)試框初始化本身也需要安裝一些APP,比如uiautomator2會(huì)安裝atx-agent、com.github.uiautomator,這些彈窗在初始化環(huán)境的時(shí)候可以手動(dòng)點(diǎn)掉,case里不需要關(guān)注。另一種就是安裝我們的被測(cè)app,像下面這種
都是我們不得不去處理的,不然,自動(dòng)化也就是不自動(dòng)了。 APP啟動(dòng)時(shí)的權(quán)限彈窗
這類(lèi)彈窗是APP在啟動(dòng)時(shí)會(huì)申請(qǐng)一些基礎(chǔ)的權(quán)限
彈窗處理
本文使用的是uiautomator2這個(gè)自動(dòng)化框架,它提供了一種watcher對(duì)象,可以用來(lái)配置要監(jiān)控的元素,這里我們配置要監(jiān)控的就是頁(yè)面上的彈窗,下面來(lái)看看具體怎么做。
watcher的使用
# 常用寫(xiě)法,注冊(cè)匿名監(jiān)控 d.watcher.when("安裝").click() # 注冊(cè)名為ANR的監(jiān)控,當(dāng)出現(xiàn)ANR和Force Close時(shí),點(diǎn)擊Force Close d.watcher("ANR").when(xpath="ANR").when("Force Close").click() # 其他回調(diào)例子 d.watcher.when("搶紅包").press("back") d.watcher.when("//*[@text = "Out of memory"]").call(lambda d: d.shell("am force-stop com.im.qq")) # 回調(diào)說(shuō)明 def click_callback(d: u2.Device): d.xpath("確定").click() # 在回調(diào)中調(diào)用不會(huì)再次觸發(fā)watcher d.xpath("繼續(xù)").click() # 使用d.xpath檢查元素的時(shí)候,會(huì)觸發(fā)watcher(目前最多觸發(fā)5次 # 移除ANR的監(jiān)控 d.watcher.remove("ANR") # 移除所有的監(jiān)控 d.watcher.remove() # 開(kāi)始后臺(tái)監(jiān)控 d.watcher.start() d.watcher.start(2.0) # 默認(rèn)監(jiān)控間隔2.0s # 強(qiáng)制運(yùn)行所有監(jiān)控 d.watcher.run() # 停止監(jiān)控 d.watcher.stop() # 停止并移除所有的監(jiān)控,常用于初始化 d.watcher.reset()
上面是watcher的一些常用api以及解釋?zhuān)瑏?lái)源于github。嘻嘻,自己懶的寫(xiě)了。
下面我們用B站apk為例,處理從安裝到登錄后的一系列彈窗。
import uiautomator2 as u2 import os import time base_dir = os.path.dirname(__file__) apk_path = os.path.join(base_dir, "apks/bilibili.apk") d = u2.connect_usb(serial="MDX0220924018819") # 從安裝到登錄成功后,可能會(huì)出現(xiàn)的彈窗,在這里進(jìn)行注冊(cè),這個(gè)是華為手機(jī)出現(xiàn)的彈窗類(lèi)型 d.watcher.when("繼續(xù)安裝").click() d.watcher.when("完成").click() d.watcher.when("同意并繼續(xù)").click() d.watcher.when("我知道了").click() d.watcher.start() d.app_install(apk_path) d.app_start("tv.danmaku.bili") d(text="我的").click() time.sleep(3) if d(resourceId="tv.danmaku.bili:id/btn_change_account").exists: d(resourceId="tv.danmaku.bili:id/btn_change_account").click() else: d(resourceId="tv.danmaku.bili:id/tv_login").click() time.sleep(3) d(resourceId="tv.danmaku.bili:id/username").set_text("xxxxxxxxx") d(resourceId="tv.danmaku.bili:id/userpwd").set_text("xxxxxxxx") d(resourceId="tv.danmaku.bili:id/log_reg_checkbox").click() time.sleep(2) d(resourceId="tv.danmaku.bili:id/btn_login").click() d(text="首頁(yè)").click()
彈窗處理的核心思想是,起一個(gè)線(xiàn)程,不停的監(jiān)聽(tīng)頁(yè)面上有沒(méi)有彈窗出現(xiàn),出現(xiàn)了就點(diǎn)擊,或點(diǎn)擊取消或點(diǎn)擊確認(rèn)等等。
采用了后臺(tái)運(yùn)行了一個(gè)線(xiàn)程的方法(依賴(lài)threading庫(kù)),然后每隔一段時(shí)間dump一次hierarchy,匹配到元素之后執(zhí)行相應(yīng)的操作。
class Watcher(): def __init__(self, d: "uiautomator2.Device"): self._d = d self._watchers = [] self._watch_stop_event = threading.Event() self._watch_stopped = threading.Event() self._watching = False # func start is calling self._triggering = False self.logger = setup_logger() self.logger.setLevel(logging.INFO) def when(self, xpath=None): return XPathWatcher(self, xpath)
Watcher對(duì)象個(gè)self._watchers 屬性來(lái)維護(hù)所有要監(jiān)控的元素,d.watcher.when("繼續(xù)安裝")當(dāng)我們調(diào)用when方法后會(huì)返回一個(gè)XPathWatcher對(duì)象,然后再調(diào)用這個(gè)對(duì)象的click方法實(shí)現(xiàn)對(duì)監(jiān)控元素的操作。
class XPathWatcher(): def __init__(self, parent: Watcher, xpath: str, name: str = ""): self._name = name self._parent = parent self._xpath_list = [xpath] if xpath else [] def when(self, xpath=None): self._xpath_list.append(xpath) return self def call(self, func): """ func accept argument, key(d, el) d=self._d, el=element """ self._parent._watchers.append({ "name": self._name, "xpaths": self._xpath_list, "callback": func, }) def click(self): def _inner_click(selector): selector.get_last_match().click() self.call(_inner_click)
click方法就是將點(diǎn)擊的操作放到回調(diào)函數(shù),然后調(diào)用XPathWatcher對(duì)象的call方法,這個(gè)方法會(huì)生成一個(gè)監(jiān)控規(guī)則,并將監(jiān)控規(guī)則放到我們前面提到的Watcher對(duì)象的self._watchers 屬性。
def start(self, interval: float = 2.0): """ stop watcher """ if self._watching: self.logger.warning("already started") return self._watching = True th = threading.Thread(name="watcher", target=self._watch_forever, args=(interval, )) th.daemon = True th.start() return th
再然后調(diào)用Watcher對(duì)象的的start方法,開(kāi)啟一個(gè)線(xiàn)程,按照指定間隔時(shí)間從頁(yè)面dump信息,查看是否有要監(jiān)控的元素,找到后調(diào)用回調(diào)函數(shù)。
以上就是“Android自動(dòng)化測(cè)試如何處理各種彈窗”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。