UI自动化测试遇弹窗怎么办?这个解决方法你get到了没?

本文介绍了在UI自动化测试中如何处理各种类型的弹窗,特别是使用uiautomator2的watcher对象进行监控和响应。通过实战案例展示了如何处理安装和启动APP过程中的弹窗,以及如何使用watcher的API进行操作。同时,文章提到了软件测试技术的多个方面,包括测试基础、Linux知识、Shell脚本等,为读者提供了全面的技术准备和建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

引言

弹窗的种类:

APP内的业务弹窗

弹窗处理

watcher的使用

实战案例

软件测试技术的准备和建议

一、测试基础

二、Linux必备知识

三、Shell脚本

四、互联网程序原理

五、MySQL数据库

六、抓包工具

七、接口测试工具

八、Web自动化测试Java&Python

九、接口与移动端自动化

十、敏捷测试&TestOps构建

十一、性能测试&安全测试


引言

在UI自动化测试中遇到弹窗其实是一件非常常见的事情,不同的弹窗类型和弹出时机都会影响我们的测试结果和用例稳定性。

如果不能及时处理这些弹窗,就有可能导致测试用例失败,甚至直接影响整个测试流程。

本文将向大家介绍如何快速、便捷地解决所有弹窗的问题,让你的UI自动化测试用例稳定如一。

无论你是新手还是老手,只要认真阅读并掌握这个方法,相信你都能在日后的UI自动化测试中游刃有余,轻松应对各种弹窗的情况。

弹窗的种类:

安装APP时的系统弹窗
此类弹窗一般有两种,一种是自动化测试框初始化本身也需要安装一些APP,比如uiautomator2会安装atx-agent、com.github.uiautomator,这些弹窗在初始化环境的时候可以手动点掉,case里不需要关注。另一种就是安装我们的被测app,像下面这种

都是我们不得不去处理的,不然,自动化也就是不自动了。
APP启动时的权限弹窗

这类弹窗是APP在启动时会申请一些基础的权限

APP内的业务弹窗

弹窗处理

本文使用的是uiautomator2这个自动化框架,它提供了一种watcher对象,可以用来配置要监控的元素,这里我们配置要监控的就是页面上的弹窗,下面来看看具体怎么做。

watcher的使用

# 常用写法,注册匿名监控
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()

上面是watcher的一些常用api以及解释,来源于github。嘻嘻,自己懒的写了。

实战案例

下面我们用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')

# 从安装到登录成功后,可能会出现的弹窗,在这里进行注册,这个是华为手机出现的弹窗类型
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()

弹窗处理的核心思想是,起一个线程,不停的监听页面上有没有弹窗出现,出现了就点击,或点击取消或点击确认等等。

uiautomator2处理弹窗的核心思想

采用了后台运行了一个线程的方法(依赖threading库),然后每隔一段时间dump一次hierarchy,匹配到元素之后执行相应的操作。

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对象个self

### Web自动化测试中处理弹窗方法 在Web自动化测试领域,处理由JavaScript生成的弹窗(如`alert`、`confirm`和`prompt`),以及基于HTML元素构建的自定义弹窗是非常重要的任务之一[^1]。 #### 使用Selenium处理标准JavaScript弹窗 对于标准的JavaScript弹窗,Selenium WebDriver提供了一套简洁而有效的接口来进行交互: - **接受警报对话**:当到简单的提示或确认对话时,可以调用`accept()`方法来模拟点击“确定”按钮的行为。 ```python from selenium import webdriver driver = webdriver.Chrome() alert = driver.switch_to.alert alert.accept() # 点击 "OK" ``` - **拒绝/关闭警告**:如果需要模拟用户取消操作,则应使用`dismiss()`函数代替。 ```python alert.dismiss() # 点击 "Cancel" 或者关闭窗口 ``` - **读取并验证消息内容**:有时还需要获取显示给用户的文本信息以便于断言或其他逻辑判断,在这种情况下可利用`text`属性访问当前活动的警告内的文字描述。 ```python message = alert.text print(f"The alert says: {message}") ``` - **向Prompt输入数据**:针对带有文本域的提示(`prompt`),可以通过`send_keys()`发送字符串至该字段内完成填写动作后再做进一步响应。 ```python alert.send_keys("Emily") # 向 prompt 输入指定的内容 alert.accept() # 提交所填入的信息 ``` 以上功能均适用于浏览器内置的标准JS弹窗,并且能够很好地满足大多数场景下的需求[^3]。 #### 应对复杂类型的模态对话 除了上述提到的基础类型外,现代网站还经常采用更加复杂的UI组件作为通知机制的一部分。这类高级别的出层往往不是纯粹依靠原生DOM事件创建出来的简单对象;相反它们可能是借助第三方库或者架精心设计而成的高度定制化的界面控件。为了应对这种情况,开发者通常会采取如下策略: - 首先确保触发条件已经达成从而使得目标弹窗得以显现出来; - 接着运用常规的选择器语法(ID, Class Name, XPath等)精确定位到构成此浮层结构的关键节点上; - 最终执行必要的鼠标指针移动、按键按下释放等一系列仿真指令以达到预期效果。 ```python from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver.get('https://example.com') wait = WebDriverWait(driver, 10) # 假设这里有一个按钮用于打开模态 open_modal_button = wait.until(EC.element_to_be_clickable((By.ID, 'openModal'))) open_modal_button.click() # 定位模态内部的具体元素进行互动 modal_element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'modal-content'))) input_field_in_modal = modal_element.find_element(By.TAG_NAME, 'input') input_field_in_modal.send_keys('Test Input') submit_btn_inside_modal = modal_element.find_element(By.CSS_SELECTOR, '.btn-primary') submit_btn_inside_modal.click() ``` 这段代码展示了如何等待特定元素变得可用之后再对其进行操作的过程,这对于那些加载时间不确定性的动态网页来说尤为重要。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值