跨平台元素定位的统一策略:从 App 到 PC 到 Web

App、PC、Web 三端各写各的定位策略,同一套业务用例的维护成本是三倍的。2024 年把三端的定位层重构成统一策略 + 自愈选择器,这篇讲设计思路和落地细节。

一、统一的定位描述:Locator 规范

三端控件标识符完全不同(resource-id / auto_id / data-testid),但语义是同一套。先定义统一的 Locator 描述:

1
2
3
4
5
6
7
8
9
@dataclass
class Locator:
"""业务语义化的定位描述,与具体平台解耦"""
role: str # send_button / chat_input / order_grid ...
platform_map: dict # 平台 -> 具体选择器
fallback: list # 主选择器失效后的兜底序列

# 用例里只写 role,不写选择器
send_btn = page.locate("send_button")

platform_map平台适配层维护,集中一处:

1
2
3
4
5
6
7
8
9
10
11
12
13
LOCATOR_REGISTRY = {
"send_button": {
"app": {"strategy": "resource_id", "value": "com.app:id/btn_send"},
"pc": {"strategy": "auto_id", "value": "btnSend"},
"web": {"strategy": "test_id", "value": "send-message-btn"},
},
"chat_input": {
"app": {"strategy": "resource_id", "value": "com.app:id/et_msg"},
"pc": {"strategy": "auto_id", "value": "edMessage"},
"web": {"strategy": "test_id", "value": "message-input"},
},
# ...
}

收益:改一处选择器,三端用例不动;新人写用例只需要认识 role 词汇表,不用学三个平台的 API。

二、选择器优先级:跨平台统一排序

不同平台的"稳定"含义不同,统一排序如下:

优先级 通用原则 App 实例 PC 实例 Web 实例
1 开发约定的稳定 ID resource-id auto_id data-testid
2 无障碍/语义属性 content-desc Name(UIA) aria-label
3 稳定文案 text title text 精确匹配
4 结构相对定位 父级 ID + 索引 容器 + 相对路径 CSS 相对选择器
5 全文查询兜底 XPath UIA XPath XPath/JS 查询

铁律:第 1、2 优先级需要开发配合(约定 ID 规范),这是"定位维护成本"从根源上降下来的唯一办法。第 3 优先级以下的选择器全部进"待治理清单",每个迭代消化一部分。

三、自愈选择器:失效后自动找替代

UI 改版后选择器失效是常态,人工修选择器是纯消耗。自愈的思路:主选择器失效时,用"锚点元素 + 相对关系"重新定位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def locate_with_healing(role, driver, platform):
primary = LocatorResolver.resolve(role, platform)
el = try_find(driver, primary, timeout=3)
if el:
return el

# 自愈路径:找锚点,再走相对关系
anchor, relation = LocatorRegistry.healing_info(role)
anchor_el = try_find(driver, anchor, timeout=3)
if anchor_el is None:
raise LocatorStaleError(role) # 锚点也没了 = 大改版,报人工介入
el = relation.apply(anchor_el, driver) # 例如:锚点右侧第 2 个可点击控件
if el:
# 上报自愈事件:记录"新位置",供下一个人工确认固化
HealingReporter.report(role, platform, primary, el)
return el
raise LocatorStaleError(role)

关键设计:自愈不是"随便找一个像的控件点掉",而是锚点 + 显式相对关系(“在 X 右边的第 N 个可点击元素”),关系是人审过的,错了能看出来。每次自愈事件进周报,连续自愈的 role 说明该控件该和开发重新约定 ID 了。

实测数据:UI 大改版周,选择器失效 47 处,自愈命中 39 处(83%),人工介入 8 处(其中 5 处是锚点自身失效的大改版)。自愈把"改版周的 2 天修选择器"压到 2 小时。

四、选择器质量门禁

定位层重构后,选择器本身也要进质量管控:

  1. 静态检查(CI lint):用例里出现裸 XPath/绝对路径直接 fail,必须走 role
  2. 脆弱度评分:每个 role 的选择器按优先级打分(1 级=100 分,5 级=40 分),平台选择器均分低于 70 的进治理看板;
  3. 失效归因:选择器失效分三类统计——“ID 被删”(开发违约,找开发)、“结构变化”(走自愈)、“文案变化”(多语言/运营改文案,换优先级)。归因数据是"ID 规范"能推下去的依据。

五、小结

统一定位层的三个层次:role 词汇表(用例与平台解耦)、优先级排序(脆弱性可控)、锚点自愈(改版周不瘫痪)。成本是一次性的重构(约 3 周),收益是之后每次 UI 改版的人力从"天"变"小时",而且选择器质量第一次有了可度量的指标。