How to deal with various pop-up windows in Android automated testing

Table of contents

Types of popups:

Business pop-up window in APP

Pop-up processing

The use of watchers

Practical case

 Summarize:


Pop-up windows are a major factor affecting the stability of automation use cases in UI automation testing. How to deal with pop-up windows in various situations conveniently and quickly is a problem that must be faced in UI automation testing.

Types of popups:


There are generally two types of system pop-up windows when installing APP. One is that the initialization of the automated test box itself also needs to install some APPs. For example, uiautomator2 will install atx-agent and com.github.uiautomator. These pop-up windows are in the initialization environment . It can be manually clicked off, and there is no need to pay attention to it in the case. The other is to install our app under test, like the following

We have to deal with it, otherwise, automation is not automatic.
Permission pop-up window when APP starts

This kind of pop-up window is that the APP will apply for some basic permissions when it starts

Business pop-up window in APP

Pop-up processing

This article uses the automation framework uiautomator2, which provides a watcher object that can be used to configure the elements to be monitored. Here we configure the pop-up windows on the page to be monitored. Let's see how to do it.

The use of watchers

# 常用写法,注册匿名监控
d.watcher.when("安装").click()

# 注册名为ANR的监控,当出现ANR和Force Close时,点击Force Close
d.watcher("ANR").when(xpath="ANR").when("Force Close").click()

# 其他回调例子
d.watcher.when("抢红包").press("back")
d.watcher.when("//*[@text = 'Out of memory']").call(lambda d: d.shell('am force-stop com.im.qq'))

# 回调说明
def click_callback(d: u2.Device):
    d.xpath("确定").click() # 在回调中调用不会再次触发watcher

d.xpath("继续").click() # 使用d.xpath检查元素的时候,会触发watcher(目前最多触发5次

# 移除ANR的监控
d.watcher.remove("ANR")
# 移除所有的监控
d.watcher.remove()
# 开始后台监控
d.watcher.start()
d.watcher.start(2.0) # 默认监控间隔2.0s
# 强制运行所有监控
d.watcher.run()
# 停止监控
d.watcher.stop()
# 停止并移除所有的监控,常用于初始化
d.watcher.reset()

The above are some commonly used APIs and explanations of watcher, which come from github. Hee hee, I was too lazy to write.

Practical case

Let's take the apk of station B as an example to deal with a series of pop-up windows from installation to login.

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')

# 从安装到登录成功后,可能会出现的弹窗,在这里进行注册,这个是华为手机出现的弹窗类型
d.watcher.when('继续安装').click()
d.watcher.when('完成').click()
d.watcher.when('同意并继续').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='首页').click()

The core idea of ​​pop-up window processing is to start a thread and keep monitoring whether there is a pop-up window on the page, and click when it appears, or click to cancel or click to confirm, etc.

The core idea of ​​uiautomator2 processing pop-up windows

The method of running a thread in the background (depending on the threading library) is adopted, and then the hierarchy is dumped every once in a while, and the corresponding operation is performed after the element is matched.

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)

The Watcher object has a self._watchers attribute to maintain all the elements to be monitored. d.watcher.when('continue to install') will return an XPathWatcher object when we call the when method, and then call the click method of this object to realize the monitoring element operation.

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)

The click method is to put the click operation into the callback function, and then call the call method of the XPathWatcher object. This method will generate a monitoring rule and put the monitoring rule into the self._watchers attribute of the Watcher object we mentioned earlier.

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

Then call the start method of the Watcher object, start a thread, dump information from the page according to the specified interval, check whether there is an element to be monitored, and call the callback function after finding it.

 Summarize:

Thanks to everyone who read my article carefully! ! !

I personally sorted out some technical materials I have compiled in my software testing career in the past few years, including: e-books, resume modules, various job templates, interview books, self-study projects, etc. Welcome everyone to click on the business card below to get it for free, don't miss it.

   Python automated testing learning exchange group: a full set of automated testing interview resume learning materials to obtain Click the link to join the group chat [python automated testing exchange]: http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DhOSZDNS -qzT5QKbFQMsfJ7DsrFfKpOF&authKey=eBt%2BF%2FBK81lVLcsLKaFqnvDAVA8IdNsGC7J0YV73w8V%2FJpdbby66r7vJ1rsPIifg&noverify=0&group_code=198408628

Guess you like

Origin blog.csdn.net/MXB_1220/article/details/131689979