溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Android自動(dòng)化測(cè)試如何處理各種彈窗

發(fā)布時(shí)間:2022-03-30 10:48:35 來(lái)源:億速云 閱讀:714 作者:iii 欄目:移動(dòng)開(kāi)發(fā)

今天小編給大家分享一下Android自動(dòng)化測(cè)試如何處理各種彈窗的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

彈窗的種類(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)限彈窗

Android自動(dòng)化測(cè)試如何處理各種彈窗

這類(lèi)彈窗是APP在啟動(dòng)時(shí)會(huì)申請(qǐng)一些基礎(chǔ)的權(quán)限

APP內(nèi)的業(yè)務(wù)彈窗

彈窗處理

本文使用的是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ě)了。

實(shí)戰(zhàn)案例

下面我們用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)等等。

uiautomator2處理彈窗的核心思想

采用了后臺(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è)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI