SMAT/ArkAnalyzer-HapRay DSL系统:领域特定语言设计与实现
引言:UI自动化测试的痛点与解决方案
在移动应用性能测试领域,UI自动化测试一直面临着诸多挑战:测试脚本编写复杂、维护成本高、可读性差、跨平台兼容性差等问题。传统的录制回放工具虽然简化了操作录制,但生成的代码往往需要开发者二次加工,无法直接满足性能测试的复杂需求。
SMAT/ArkAnalyzer-HapRay DSL(Domain-Specific Language,领域特定语言)系统正是为了解决这些痛点而生。它通过定义一套专门针对OpenHarmony应用UI自动化测试的领域特定语言,实现了测试用例的声明式编写、配置化管理和自动化执行。
一、DSL系统架构设计
1.1 整体架构概览
1.2 核心设计原则
- 声明式编程:通过YAML配置描述测试意图,而非具体实现
- 类型安全:基于JSON Schema的严格类型验证
- 可扩展性:模块化设计,支持新事件类型的灵活添加
- 跨平台兼容:抽象底层驱动差异,提供统一接口
二、DSL语法规范详解
2.1 配置文件结构
config:
source_screen: [1084, 2412] # 设计基准分辨率
app_package: 'com.example.app' # 应用包名
app_name: '示例应用' # 应用显示名称
scene_name: '性能测试场景' # 测试场景标识符
test_case:
setup: # 前置准备步骤
- type: "start_app" # 启动应用
- type: "wait" # 等待应用启动
duration: 5
steps: # 主测试步骤
- name: "浏览商品列表"
performance:
duration: 20 # 性能采集20秒
events:
- type: "loop" # 循环操作
count: 10
events:
- type: "swipe" # 上滑浏览
direction: "UP"
- type: "wait" # 等待加载
duration: 1
cleanup: # 清理步骤
- type: "stop_app" # 停止应用
2.2 组件选择器系统
DSL提供了丰富的组件定位机制,支持多种选择策略:
| 选择器类型 | 语法示例 | 说明 |
|---|---|---|
| 文本选择器 | text: "登录" | 按控件文本内容定位 |
| 类型选择器 | type: "Button" | 按控件类型定位 |
| 键值选择器 | key: "submit_btn" | 按控件key属性定位 |
| XPath选择器 | xpath: "//Button[@text='确定']" | 使用XPath表达式定位 |
| 坐标选择器 | pos: [0.5, 0.8] | 按屏幕比例坐标定位 |
复合选择器示例:
target:
text: "设置"
type: "Button"
relations:
- relation: "isAfter"
target:
text: "个人中心"
2.3 事件类型系统
DSL支持8种核心事件类型,覆盖了移动应用测试的常见操作:
2.3.1 触摸事件 (Touch Event)
- type: "touch"
target:
text: "搜索"
mode: "normal" # 点击模式:normal/long/double
wait_time: 0.1 # 点击后等待时间
2.3.2 滑动事件 (Swipe Event)
- type: "swipe"
direction: "UP" # 滑动方向:UP/DOWN/LEFT/RIGHT
distance: 60 # 滑动距离百分比(1-100)
area: # 滑动区域
type: "ScrollView"
swipe_time: 0.3 # 滑动持续时间
2.3.3 输入事件 (Input Event)
- type: "input_text"
component:
type: "TextField"
key: "username_input"
text: "testuser@example.com"
2.3.4 循环事件 (Loop Event)
- type: "loop"
count: 5 # 循环次数
events: # 循环内事件序列
- type: "swipe"
direction: "UP"
- type: "wait"
duration: 1
2.4 性能采集配置
DSL集成了性能数据采集功能,支持在特定测试步骤中采集性能指标:
- name: "视频播放性能测试"
performance:
duration: 30 # 采集持续时间(秒)
events:
- type: "touch"
target:
text: "播放"
# 后续事件将在性能监控下执行
三、DSL实现技术解析
3.1 解析器架构设计
3.2 核心实现代码
3.2.1 配置解析与验证
class DSLTestRunner(PerfTestCase):
schema_path = files('hapray.core.dsl').joinpath('dsl_schema.yaml')
def _load_config(self, path: str) -> dict[str, Any]:
"""加载并验证YAML配置文件"""
if not os.path.exists(path):
raise FileNotFoundError(path)
with open(path, encoding='UTF-8') as f:
config = yaml.safe_load(f)
# Schema验证确保配置合法性
with open(self.schema_path, encoding='UTF-8') as f:
schema = yaml.safe_load(f)
validate(instance=config, schema=schema)
return config
3.2.2 组件选择器解析
def _parse_component_selector(self, selector_data: dict) -> ComponentSelector:
"""解析组件选择器配置"""
selector = ComponentSelector()
# 解析基本属性
if 'text' in selector_data:
selector.text = selector_data['text']
if 'key' in selector_data:
selector.key = selector_data['key']
if 'type' in selector_data:
selector.type = selector_data['type']
if 'xpath' in selector_data:
selector.xpath = selector_data['xpath']
if 'pos' in selector_data:
selector.pos = selector_data['pos']
# 解析关系属性
if 'relations' in selector_data:
for rel_data in selector_data['relations']:
relation = {
'relation': rel_data['relation'],
'target': self._parse_component_selector(rel_data['target']),
}
selector.relations.append(relation)
return selector
3.2.3 事件分发与执行
def _execute_event(self, event: UIEvent):
"""执行单个UI事件"""
try:
if isinstance(event, TouchEvent):
self._process_touch(event)
elif isinstance(event, SwipeEvent):
self._process_swipe(event)
elif isinstance(event, InputEvent):
self._process_input_text(event)
elif isinstance(event, WaitEvent):
self._process_wait(event)
elif isinstance(event, LoopEvent):
self._process_loop(event)
# ... 其他事件类型处理
except Exception as e:
logging.error('执行事件失败: %s - 错误: %s', event.event_type, str(e))
raise
四、DSL在实际测试中的应用
4.1 电商应用测试用例
config:
source_screen: [1080, 2400]
app_package: 'com.example.ecommerce'
app_name: '电商应用'
scene_name: '商品浏览性能测试'
test_case:
setup:
- type: "start_app"
- type: "wait"
duration: 5
steps:
- name: "首页浏览"
performance:
duration: 15
events:
- type: "swipe"
direction: "UP"
distance: 80
- type: "wait"
duration: 2
- type: "swipe"
direction: "DOWN"
distance: 40
- name: "商品搜索"
events:
- type: "touch"
target:
text: "搜索"
- type: "input_text"
component:
type: "TextField"
text: "智能手机"
- type: "touch"
target:
text: "搜索"
mode: "normal"
- name: "商品详情页性能"
performance:
duration: 20
events:
- type: "touch"
target:
text: "华为Mate60"
- type: "wait"
duration: 3
- type: "loop"
count: 3
events:
- type: "swipe"
direction: "UP"
- type: "wait"
duration: 1
cleanup:
- type: "stop_app"
4.2 社交媒体应用测试用例
config:
source_screen: [1170, 2532]
app_package: 'com.example.social'
app_name: '社交媒体'
scene_name: '信息流滚动性能测试'
test_case:
steps:
- name: "信息流无限滚动"
performance:
duration: 30
events:
- type: "loop"
count: 20
events:
- type: "swipe"
direction: "UP"
distance: 70
swipe_time: 0.5
- type: "wait"
duration: 1.5
五、DSL系统的优势与价值
5.1 技术优势对比
| 特性 | 传统代码测试 | HapRay DSL测试 |
|---|---|---|
| 编写复杂度 | 高,需要编程知识 | 低,YAML配置即可 |
| 可读性 | 一般,代码逻辑复杂 | 优秀,声明式配置 |
| 维护成本 | 高,代码修改困难 | 低,配置修改简单 |
| 跨平台支持 | 需要适配不同平台 | 统一DSL抽象层 |
| 性能集成 | 需要手动添加监控 | 内置性能采集 |
5.2 业务价值体现
- 测试效率提升:DSL配置相比代码编写效率提升3-5倍
- 维护成本降低:配置修改无需重新编译,维护成本降低60%
- 协作门槛降低:测试人员无需编程背景即可编写测试用例
- 质量保障增强:Schema验证确保测试用例的正确性
六、最佳实践与使用建议
6.1 DSL编写规范
- 命名规范:使用有意义的场景名称和步骤名称
- 模块化设计:将复杂测试拆分为多个可重用的步骤
- 错误处理:合理设置等待时间,避免因网络延迟导致的失败
- 性能优化:根据实际需求设置合适的采集持续时间
6.2 调试与排查技巧
- 日志分析:充分利用系统日志定位执行问题
- 逐步执行:复杂用例先分步验证再组合执行
- Schema验证:编写完成后先用Schema验证配置合法性
- 性能监控:关注性能采集数据的准确性和完整性
七、未来发展方向
7.1 技术演进路线
7.2 功能扩展计划
- 智能元素定位:集成计算机视觉技术,增强元素定位能力
- 测试用例生成:基于用户行为分析自动生成测试用例
- 跨平台扩展:支持更多移动操作系统和测试框架
- 云测试集成:与云端测试平台深度集成,实现分布式执行
结语
SMAT/ArkAnalyzer-HapRay DSL系统通过领域特定语言的设计,成功解决了OpenHarmony应用UI自动化测试中的诸多痛点。其声明式的编程模型、严格的类型验证、丰富的操作支持和内置的性能采集功能,为移动应用性能测试提供了全新的解决方案。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



