自动化测试也能控制系统设置?HMNextAuto 通知栏操作详解
自动化测试中的通知栏操作实践 摘要:本文介绍了HMNextAuto框架如何通过NotificationPanel类实现鸿蒙系统通知栏的自动化操作。主要内容包括: 通知栏操作的价值:解决网络切换、通知测试等场景下的手动操作痛点 核心API功能:支持打开/关闭通知栏、快捷设置面板操作、通知消息管理及亮度控制 快捷开关控制:内置WiFi、蓝牙等常用开关的控件映射,支持一键切换状态 实战应用场景:网络切换
自动化测试也能控制系统设置?HMNextAuto 通知栏操作详解
本文将带你深入 HMNextAuto 的通知栏操作模块,从基础的打开/关闭通知栏,到快捷开关控制、通知消息处理,再到完整的实战场景,掌握自动化测试中的系统级控制能力。
一、引言:为什么自动化测试需要操作通知栏?
1.1 一个真实的测试痛点
做过移动端自动化测试的同学一定遇到过这样的场景:你需要测试 App 在不同网络环境下的表现,于是手动打开设置、关闭 WiFi、开启移动数据、再回到 App 观察结果。整个过程反复操作,耗时且容易出错。更头疼的是,当你需要测试飞行模式切换、低电量模式、蓝牙连接断开等场景时,手动操作几乎不可控——你无法精确记录每次切换的时机,也无法保证操作的一致性。
在鸿蒙 NEXT 系统上,这类问题更加突出。鸿蒙的快捷设置面板和通知中心与 Android 有着显著差异,传统的 UIAutomator 方案在鸿蒙设备上往往无法正确识别和控制这些系统级界面。测试工程师们迫切需要一个稳定、可靠的方案来通过代码控制通知栏和系统设置。
1.2 通知栏操作在测试中的核心价值
| 测试场景 | 手动操作痛点 | 自动化价值 |
|---|---|---|
| 网络切换测试 | 需反复进入设置切换 WiFi/数据,操作繁琐 | 一行代码切换,精确控制时机 |
| 通知消息测试 | 需等待推送、手动点击通知 | 自动获取通知列表、按条件点击 |
| 系统设置测试 | 不同设备设置入口不同 | 统一 API,屏蔽设备差异 |
| 兼容性测试 | 需在多台设备上重复操作 | 脚本复用,大幅提升效率 |
| 弱网/断网测试 | 难以精确控制断网时机 | 代码精确控制,结果可复现 |
1.3 HMNextAuto 的通知栏操作方案
HMNextAuto 通过 NotificationPanel 类提供了完整的系统级控制能力,核心优势包括:
- 统一 API:一套代码适配不同鸿蒙设备
- 上下文管理器:自动打开/关闭通知栏,避免状态残留
- 快捷开关映射:内置 WiFi、蓝牙、飞行模式等常用开关的控件 ID 映射
- 通知消息管理:获取通知列表、按索引或文本点击通知、清除所有通知
- 亮度控制:直接设置屏幕亮度等级
二、通知栏操作能力总览
2.1 架构设计
HMNextAuto 的通知栏操作通过 NotificationPanel 类实现,通过 Driver 实例的 notification 属性访问。整体架构如下:
[外链图片转存中…(img-H9OWDG6K-1779760150522)]
2.2 核心 API 一览
NotificationPanel 类提供了以下核心方法:
| 方法 | 功能 | 参数说明 |
|---|---|---|
open() |
打开通知栏 | wait_time=0.5 等待动画完成时间 |
close() |
关闭通知栏 | wait_time=0.3 等待动画完成时间 |
toggle() |
切换通知栏状态 | 无参数 |
open_quick_settings() |
打开快捷设置面板 | wait_time=0.5 等待动画完成时间 |
get_notifications() |
获取通知列表 | 返回 List[Dict] |
click_notification() |
点击通知消息 | index=0 按索引,text=None 按文本 |
clear_all_notifications() |
清除所有通知 | 无参数 |
click_quick_setting() |
点击快捷设置项 | name 开关名称 |
set_brightness() |
设置屏幕亮度 | level 亮度值 0-100 |
2.3 基础用法:打开与关闭通知栏
from hmnextauto.driver import Driver
d = Driver()
# 打开通知栏(从屏幕顶部左侧下滑)
d.notification.open()
# 关闭通知栏(向上滑动关闭)
d.notification.close()
# 切换通知栏状态(打开↔关闭)
d.notification.toggle()
打开通知栏时,HMNextAuto 会从屏幕顶部左侧区域执行下滑手势,模拟用户手动拉出通知栏的操作。关闭时则执行上滑手势,确保通知栏完全收起。wait_time 参数用于等待系统动画完成,避免在动画过程中执行后续操作导致失败。
三、快捷开关操作:控制系统设置
3.1 快捷设置面板
鸿蒙系统的快捷设置面板(Quick Settings Panel)集成了大量系统开关,是日常使用中最频繁操作的系统界面之一。HMNextAuto 提供了 open_quick_settings() 方法来打开这个面板:
from hmnextauto.driver import Driver
d = Driver()
# 打开快捷设置面板(从屏幕顶部右侧下滑)
d.notification.open_quick_settings()

提示:鸿蒙系统中,从顶部左侧下滑打开的是通知中心,从顶部右侧下滑打开的是快捷设置面板。HMNextAuto 的
open()和open_quick_settings()分别对应这两种操作。
3.2 内置快捷开关映射
click_quick_setting() 方法内置了常用快捷开关的控件 ID 映射表,你只需要传入开关的中文名称或英文名称即可:
| 支持的名称 | 对应功能 | 内部控件 ID |
|---|---|---|
wifi / wlan |
WiFi 开关 | transition_togglewifi_ui_extension |
蓝牙 / bluetooth |
蓝牙开关 | transition_togglebluetooth_ui_extension |
飞行模式 / 飞行 |
飞行模式开关 | transition_toggleairplane_ui_extension |
静音 |
静音开关 | transition_togglemute_ui_extension |
手电筒 |
手电筒开关 | transition_toggleflashlight_ui_extension |
定位 |
GPS 定位开关 | transition_togglegps_ui_extension |
数据 |
移动数据开关 | transition_togglemobile_ui_extension |
3.3 快捷开关操作示例
from hmnextauto.driver import Driver
import time
d = Driver()
# 打开快捷设置面板
d.notification.open_quick_settings()
# 关闭 WiFi
d.notification.click_quick_setting("wifi")
time.sleep(1)
# 开启蓝牙
d.notification.click_quick_setting("蓝牙")
time.sleep(1)
# 开启飞行模式
d.notification.click_quick_setting("飞行模式")
time.sleep(2)
# 关闭飞行模式
d.notification.click_quick_setting("飞行模式")
time.sleep(1)
# 关闭快捷设置面板
d.notification.close()
注意:
click_quick_setting()实际上是**切换(toggle)**操作,即点击一次开启,再点击一次关闭。如果你需要确保某个开关处于特定状态,建议先检测当前状态再决定是否点击。
3.4 屏幕亮度控制
除了快捷开关,HMNextAuto 还支持直接设置屏幕亮度:
from hmnextauto.driver import Driver
d = Driver()
# 打开快捷设置面板
d.notification.open_quick_settings()
# 设置亮度为 50%(中等亮度)
d.notification.set_brightness(50)
# 设置亮度为 0%(最低亮度)
d.notification.set_brightness(0)
# 设置亮度为 100%(最高亮度)
d.notification.set_brightness(100)
# 关闭面板
d.notification.close()
亮度值的范围为 0-100,其中 0 代表最低亮度,100 代表最高亮度。这个功能在测试 App 在不同亮度条件下的显示效果时非常实用。
四、实战场景
接下来通过三个真实场景,展示通知栏操作在实际测试中的运用。
[外链图片转存中…(img-cWiI42jp-1779760150523)]
4.1 场景一:网络切换测试
测试目标:验证 App 在 WiFi 与移动数据之间切换时的网络请求处理能力。
#!/usr/bin/env python3
"""
网络切换测试:验证 App 在不同网络环境下的表现
"""
from hmnextauto.driver import Driver
import time
def test_network_switch():
"""网络切换测试"""
d = Driver()
# 启动被测应用
d.start_app("com.example.myapp")
time.sleep(3)
# 使用上下文管理器自动管理通知栏状态
with d.notification:
# 打开快捷设置面板
d.notification.open_quick_settings()
time.sleep(0.5)
# 第一步:关闭 WiFi,切换到移动数据
print("[测试] 关闭 WiFi...")
d.notification.click_quick_setting("wifi")
time.sleep(2) # 等待网络切换完成
# 验证 App 是否正确处理了网络变化
# (这里假设 App 会显示网络异常提示)
network_tip = d.xpath('//Text[contains(@text, "网络")]').wait(timeout=5)
if network_tip.exists:
print("[通过] App 正确检测到网络变化")
# 第二步:重新开启 WiFi
print("[测试] 重新开启 WiFi...")
d.notification.click_quick_setting("wifi")
time.sleep(3) # WiFi 重连需要更长时间
# 验证 App 是否自动恢复网络请求
# (这里假设 App 会自动刷新数据)
refresh_result = d.xpath('//Text[contains(@text, "刷新成功")]').wait(timeout=10)
if refresh_result.exists:
print("[通过] App 自动恢复了网络请求")
# 上下文管理器退出时自动关闭通知栏
print("[完成] 网络切换测试结束")
if __name__ == "__main__":
test_network_switch()
代码要点:
- 使用
with d.notification上下文管理器,确保测试结束后通知栏自动关闭 - 每次网络切换后留出足够的等待时间,让系统完成网络状态变更
- 通过 XPath 定位 App 内的网络状态提示,验证 App 的网络变化处理逻辑
4.2 场景二:低电量模式测试
测试目标:验证 App 在低电量模式下的功能降级策略。
#!/usr/bin/env python3
"""
低电量模式测试:验证 App 在省电模式下的表现
"""
from hmnextauto.driver import Driver
import time
def test_low_battery_mode():
"""低电量模式测试"""
d = Driver()
d.start_app("com.example.myapp")
time.sleep(3)
# 记录正常模式下的关键指标
print("[基线] 记录正常模式下的表现...")
with d.notification:
d.notification.open_quick_settings()
time.sleep(0.5)
# 开启省电模式(通过快捷设置中的省电开关)
# 注意:不同鸿蒙版本的省电开关名称可能不同
print("[测试] 开启省电模式...")
# 如果快捷设置中没有省电开关,可以通过点击"更多设置"进入
# 这里以亮度调节来模拟系统资源受限的场景
d.notification.set_brightness(30) # 降低亮度模拟省电
time.sleep(2)
# 验证 App 是否进入功能降级模式
# 例如:动画效果简化、后台刷新暂停、视频自动降质等
time.sleep(2)
# 检查 App 是否降低了动画帧率
# 检查 App 是否暂停了后台数据同步
print("[验证] 检查 App 功能降级策略...")
# 恢复正常模式
with d.notification:
d.notification.open_quick_settings()
time.sleep(0.5)
d.notification.set_brightness(80) # 恢复亮度
time.sleep(1)
print("[完成] 低电量模式测试结束")
if __name__ == "__main__":
test_low_battery_mode()
4.3 场景三:通知消息处理
测试目标:验证 App 推送通知的展示与点击跳转逻辑。
#!/usr/bin/env python3
"""
通知消息处理测试:验证推送通知的展示与跳转
"""
from hmnextauto.driver import Driver
import time
def test_notification_handling():
"""通知消息处理测试"""
d = Driver()
# 确保应用在后台运行
d.start_app("com.example.myapp")
time.sleep(2)
d.press_home() # 将应用切到后台
time.sleep(1)
# 模拟等待推送通知到达
print("[等待] 等待推送通知...")
time.sleep(5)
# 打开通知栏并获取通知列表
with d.notification:
# 获取当前所有通知
notifications = d.notification.get_notifications()
print(f"[信息] 当前通知数量: {len(notifications)}")
# 打印通知详情
for i, notif in enumerate(notifications):
print(f" 通知 {i}: {notif.get('title', '无标题')} - {notif.get('text', '无内容')}")
# 方式一:按文本匹配点击通知
try:
d.notification.click_notification(text="我的应用")
print("[通过] 成功点击目标通知")
except Exception as e:
print(f"[警告] 按文本点击失败: {e}")
# 方式二:按索引点击(兜底方案)
if len(notifications) > 0:
d.notification.click_notification(index=0)
print("[通过] 按索引点击了第一条通知")
# 验证通知点击后是否正确跳转到目标页面
time.sleep(2)
target_page = d.xpath('//Text[@text="消息详情"]').wait(timeout=5)
if target_page.exists:
print("[通过] 通知点击后正确跳转到目标页面")
else:
print("[失败] 通知点击后未跳转到目标页面")
# 测试完成后清除所有通知
with d.notification:
d.notification.clear_all_notifications()
print("[清理] 已清除所有通知")
if __name__ == "__main__":
test_notification_handling()
代码要点:
get_notifications()返回通知列表,每条通知包含标题、内容等信息click_notification()支持两种定位方式:按文本匹配和按索引定位- 使用
clear_all_notifications()清理测试残留,保证测试环境干净 - 上下文管理器确保通知栏在操作完成后自动关闭
五、高级技巧
5.1 上下文管理器:优雅的资源管理
NotificationPanel 实现了 __enter__ 和 __exit__ 方法,支持 Python 的上下文管理器协议。这意味着你可以使用 with 语句来自动管理通知栏的打开和关闭:
from hmnextauto.driver import Driver
d = Driver()
# 推荐写法:使用上下文管理器
with d.notification:
# 进入 with 块时自动打开通知栏
d.notification.open_quick_settings()
d.notification.click_quick_setting("wifi")
d.notification.set_brightness(50)
# 退出 with 块时自动关闭通知栏
# 这里通知栏已经自动关闭,无需手动调用 close()
上下文管理器的优势:
- 防止状态残留:即使代码中途抛出异常,通知栏也会被自动关闭
- 代码更简洁:不需要在每个分支都写
close()调用 - 可读性更强:
with块清晰地标示了通知栏操作的范围
5.2 状态检测与等待
在实际测试中,系统设置的变化往往需要一定时间才能生效。建议结合等待机制来确保操作完成:
from hmnextauto.driver import Driver
import time
def wait_for_wifi_state(d, expected_on=True, timeout=10):
"""等待 WiFi 达到预期状态"""
start_time = time.time()
while time.time() - start_time < timeout:
# 通过快捷设置面板检测 WiFi 状态
# (实际项目中可通过 adb 命令或系统 API 获取精确状态)
with d.notification:
d.notification.open_quick_settings()
time.sleep(0.5)
# 获取当前 WiFi 开关状态
wifi_toggle = d.xpath(
'//Text[contains(@resource-id, "togglewifi")]'
)
# 根据状态判断是否达到预期
# 这里简化处理,实际需要根据控件状态判断
time.sleep(1)
print(f"WiFi 状态检测超时({timeout}s)")
def safe_toggle_wifi(d, turn_on=True):
"""安全切换 WiFi 状态"""
with d.notification:
d.notification.open_quick_settings()
time.sleep(0.5)
# 点击 WiFi 开关
d.notification.click_quick_setting("wifi")
time.sleep(1)
# 等待网络状态稳定
time.sleep(3)
print(f"WiFi 已{'开启' if turn_on else '关闭'}")
5.3 异常处理与重试机制
系统级操作容易受到设备状态、动画延迟等因素的影响,建议加入异常处理和重试逻辑:
from hmnextauto.driver import Driver
import time
def robust_click_quick_setting(d, name, max_retries=3):
"""
带重试机制的快捷设置点击
:param d: Driver 实例
:param name: 快捷设置名称
:param max_retries: 最大重试次数
"""
for attempt in range(1, max_retries + 1):
try:
with d.notification:
d.notification.open_quick_settings()
time.sleep(0.5) # 等待面板动画完成
d.notification.click_quick_setting(name)
print(f"[成功] 第 {attempt} 次尝试点击 '{name}' 成功")
return True
except Exception as e:
print(f"[重试] 第 {attempt} 次点击 '{name}' 失败: {e}")
if attempt < max_retries:
time.sleep(2) # 等待后重试
else:
print(f"[失败] 点击 '{name}' 达到最大重试次数 {max_retries}")
return False
return False
def test_with_retry():
"""带异常处理的测试示例"""
d = Driver()
# 安全地切换飞行模式
if not robust_click_quick_setting(d, "飞行模式"):
print("[跳过] 飞行模式切换失败,跳过相关测试用例")
return
try:
# 执行需要飞行模式的测试
time.sleep(3)
print("[测试] 在飞行模式下执行测试...")
finally:
# 确保测试结束后恢复飞行模式状态
print("[恢复] 关闭飞行模式...")
robust_click_quick_setting(d, "飞行模式")
六、注意事项
6.1 不同机型的差异
鸿蒙生态中设备型号众多,不同设备在通知栏和快捷设置面板的布局上可能存在差异:
| 差异点 | 说明 | 应对策略 |
|---|---|---|
| 面板布局 | 不同设备的快捷开关排列顺序不同 | 使用名称匹配而非位置定位 |
| 滑动区域 | 部分设备的通知栏触发区域有差异 | HMNextAuto 已做适配,保持库版本最新 |
| 动画时长 | 高端设备和低端设备的动画速度不同 | 适当增大 wait_time 参数 |
| 系统版本 | 不同鸿蒙版本的控件 ID 可能变化 | 关注 HMNextAuto 的版本更新日志 |
6.2 权限要求
使用通知栏操作功能需要确保测试环境满足以下条件:
- USB 调试权限:设备需开启 USB 调试模式
- 无障碍服务:部分操作可能依赖无障碍服务权限
- 系统签名:某些深度系统操作可能需要系统级权限
- 锁屏状态:操作前确保设备处于解锁状态
6.3 稳定性建议
在实际项目中使用通知栏操作时,建议遵循以下最佳实践:
- 操作间隔:每次快捷开关操作后,至少等待 1-2 秒,让系统完成状态切换
- 状态恢复:测试结束后,务必恢复所有被修改的系统设置(如 WiFi、蓝牙、亮度等)
- 异常兜底:使用
try-finally或上下文管理器确保通知栏不会残留打开 - 日志记录:记录每次系统设置变更的时间和状态,便于问题排查
- 设备预热:首次操作通知栏时可能较慢,建议在测试开始前做一次预热操作
# 推荐的测试前后状态管理模板
from hmnextauto.driver import Driver
import time
class SystemStateManager:
"""系统设置状态管理器"""
def __init__(self, d):
self.d = d
self.initial_state = {}
def save_state(self):
"""保存当前系统设置状态"""
# 记录当前 WiFi、蓝牙等状态
# (实际项目中可通过 adb shell 命令获取)
print("[状态] 已保存当前系统设置")
def restore_state(self):
"""恢复到初始系统设置状态"""
with self.d.notification:
self.d.notification.open_quick_settings()
time.sleep(0.5)
# 恢复各项设置...
self.d.notification.set_brightness(80)
print("[状态] 已恢复系统设置")
def __enter__(self):
self.save_state()
return self
def __exit__(self, *args):
self.restore_state()
# 使用示例
d = Driver()
with SystemStateManager(d):
# 在这里执行测试,系统设置会自动恢复
d.notification.open_quick_settings()
d.notification.click_quick_setting("飞行模式")
time.sleep(5)
七、总结与预告
本文要点回顾
通过本文,我们系统地学习了 HMNextAuto 通知栏操作的完整能力:
| 能力 | 核心方法 | 典型场景 |
|---|---|---|
| 通知栏控制 | open() / close() / toggle() |
通知消息测试 |
| 快捷设置面板 | open_quick_settings() |
系统设置操作 |
| 快捷开关 | click_quick_setting() |
WiFi/蓝牙/飞行模式切换 |
| 亮度控制 | set_brightness() |
显示效果测试 |
| 通知消息 | get_notifications() / click_notification() |
推送通知测试 |
| 资源管理 | with d.notification |
自动关闭通知栏 |
核心收获:
- 通知栏操作让自动化测试从"应用内"拓展到了"系统级",覆盖了更多测试场景
- 上下文管理器是管理通知栏状态的最佳实践,能有效避免状态残留
- 系统级操作需要考虑设备差异和稳定性,重试机制和状态管理是必不可少的
- 结合网络切换、通知处理等实战场景,可以构建更全面的测试覆盖
下期预告
Week 6 将带来 HMNextAuto 的迁移指南,详细介绍如何从传统的 UIAutomator/Hypium 测试框架平滑迁移到 HMNextAuto,包括 API 对照表、常见迁移问题及解决方案。如果你正在考虑升级测试框架,不要错过!
参考资料
- 项目地址: https://github.com/ziguiway/HMNextAuto
- PyPI: https://pypi.org/project/hmnextauto/
- 文档: https://github.com/ziguiway/HMNextAuto/blob/main/docs/API.md
如果这篇文章对你有帮助,请给个 Star 支持一下!
有任何问题欢迎在评论区留言交流
更多推荐



所有评论(0)