UFT 对象定位的问题及技巧(含正则实战 & 无代码对比)
本文探讨了UFT自动化测试中对象定位的核心问题及解决方案。作者指出动态ID、层级变动和多语言适配是导致定位失败的三大主因,提出使用正则表达式匹配、描述性编程和层级缩减策略等技巧提升稳定性。针对金融系统常见的Grid控件,文章分享了特殊处理方法,并总结了对象定位的四大稳定原则。最后对比了传统UFT脚本与无代码自动化系统(MARS)的差异,强调语义封装和对象模型库的重要性。文章认为,在AI时代,稳定的
UFT 对象定位的问题及技巧(含正则实战 & 无代码对比)
这几天,忙着找国内推广自己无代码的自动化测试平台的事情,所以“混迹”在几个测试群中,看大家插科打诨。虽然大家群里各类八卦聊的不少,也有“正经”的时候。就在我问“为什么不用自动化测试”时,居然有个“正经”的回答,说,“搞不起”。我以为是定价,我记得红杉印度投资的一个测试平台,一个月要几十刀。本来,我计划在国内推广时候,采用低价策略,所以我说,一个月不到10块总搞得起吧。后来才知道,是“搞不起来”的意思。
现在的脚本式自动化测试平台确实是“搞不起来”。对象的定位就是首要的问题。GUI 的测试的首要任务就是对象的定位。如果连对象定位都磕磕碰碰,怎么测试?怎么快速回归?怎么快速迭代?
AI 时代尤其需要回归测试系统的高效、正确,这也是对自动化测试系统的首要挑战之一。那么,这里就聊聊 Unified Functional Testing(以下简称 UFT)的对象定位问题。
一、UFT 的对象分类机制:先看插件
UFT 的对象识别是基于技术栈插件的:
-
swf*:.NET WinForm -
wpf*:WPF -
java*:Java -
win*:Win32 / VC++ -
web*:Web
如果插件没加载,对象直接降级为 WinObject。
后面所有定位技巧都白搭。
第一原则:
先确认 Add-in,再谈定位。
二、.NET 下常见关键属性
在 .NET 应用中常见定位属性:
-
swfName -
swfType -
swfNamePath -
text
UFT 内部有一套优选机制,会自动组合属性。
但问题是:
自动选的,未必是最稳的。
三、对象“搞不起来”的核心原因
1️⃣ 控件改名
动态 ID:
TradeGrid_12345
TradeGrid_67890
下次执行直接挂。
我见过一个比较流行的金融资管系统TPG就是如此,控件是动态生成,导致普通的录制脚本,基本没法用。
2️⃣ 层级增加 / 减少
原来:
MainWindow;Panel;TradeGrid
后来:
MainWindow;Panel;GroupBox;TradeGrid
swfNamePath 立即失效。
3️⃣ 多语言问题
Text="Submit"
改成中文:
Text="提交"
全线崩溃。
四、正则表达式:应对改名的利器
UFT 支持正则表达式匹配属性,这是很多人忽略的武器。
示例一:匹配动态编号
SwfWindow("swfName:=TradeGrid_.*")
或者:
Set desc = Description.Create
desc("swfName").RegularExpression = True
desc("swfName").Value = "TradeGrid_\d+"
优势:
-
不怕编号变化
-
不怕流水号递增
示例二:应对名称前后缀变化
假设控件名:
OrderTradeGrid_Main
OrderTradeGrid_Backup
可以:
desc("swfName").Value = ".*TradeGrid.*"
desc("swfName").RegularExpression = True
五、正则应对层级变动(缩减层次问题)
很多人过度依赖 swfNamePath。
这几乎是灾难。
解决策略:
1️⃣ 不用完整路径
改为:
-
锁定稳定父对象
-
子对象使用 index 或局部匹配
示例:
Window("Main").SwfWindow("Trade").ChildObjects(desc)(0)
2️⃣ 使用正则模糊路径
desc("swfNamePath").RegularExpression = True
desc("swfNamePath").Value = ".*TradeGrid"
这样即便中间多嵌套一层,也不会崩。
3️⃣ 局部层级锁定策略(推荐)
不要锁死:
Main;Panel;Group;Grid
改成:
-
锁定 Window
-
锁定核心容器
-
Grid 用正则匹配
这叫“层级缩减策略”。
核心原则:
层级越少,稳定性越高。
六、描述性编程:替代对象库的关键
大型项目里 Object Repository 是维护灾难。
建议使用描述性编程:
Set gridDesc = Description.Create
gridDesc("swfType").Value = "DataGridView"
gridDesc("visible").Value = True
Set grids = Window("Main").ChildObjects(gridDesc)
grids(0).Click
优点:
-
可组合
-
可封装
-
可正则扩展
七、Grid 才是真正的“雷区”
金融系统几乎全是 Grid。
问题包括:
-
虚拟滚动
-
Cell 不可直接识别
-
自定义绘制
常用技巧:
gridObj.ActivateCell 3, "Amount"
gridObj.SetCellData 3, "Amount", "1000000"
这里讲一个Finastra(国内已经被恒生电子收购)的拳头产品之一:Opics。这个系统架构(个人认为)及其优秀。几乎是配置化软件的“巅峰”,通过配置文件加载交易录入,审批等模块。而这些模块的表达几乎全部用Infragistics的Grid实现,而且支持“随心所欲”的个性化。所以,UFT上面的定位那一套几乎全失效。
如果是复杂自定义控件:
-
使用
NativeObject -
或调用 .NET 方法
这已经进入高级阶段。
八、对象定位的四个稳定原则
-
不信任动态 Name
-
尽量减少层级依赖
-
使用正则匹配变化部分
-
避免全局对象库爆炸
当定位不稳定时:
自动化永远搞不起来。
九、AI 时代下的现实问题
很多人问:
“现在都 AI 了,还研究 UFT 定位?”
我要说一句现实的话:
AI 生成脚本 ≠ 定位问题解决。
如果对象识别层不稳:
-
AI 生成的脚本只会更脆弱
-
回归失败率更高
-
CI/CD 变成摆设
十、为什么我后来做无代码自动化系统
传统脚本式自动化的痛点:
-
依赖技术栈插件
-
依赖属性稳定性
-
依赖工程师水平
-
维护成本极高
后来我做自动化系统时,核心改进在三点:
1️⃣ 语义层封装
不是针对某个技术栈的直接操作:
SwfButton("xxx").Click
JavaButton("xxxxx").Click
而是操作:
ClickButton("xxxx", parameter)
2️⃣ 对象抽象层独立于工具
不把定位写死在脚本。
而是建立对象模型库。
3️⃣ 无代码化
在我现在做的 MARS 自动化体系中:
-
对象通过语义建模
-
支持动态匹配
-
自动适应层级变化
-
非技术人员也可维护
对比传统 UFT:
| 维度 | UFT 脚本式 | MARS 无代码 |
|---|---|---|
| 定位方式 | 属性匹配 | 语义 + 模型 |
| 维护成本 | 高 | 低 |
| 技术依赖 | 强 | 弱 |
结语
对象定位,是 GUI 自动化的地基。
UFT 很强,但必须懂技巧:
-
正则表达式
-
层级缩减
-
描述性编程
-
语义封装
否则,“搞不起”就会变成“搞不起来”。
如果大家愿意,下一篇可以讲:
-
金融桌面系统自动化架构设计
-
UFT 插件识别原理深度解析
-
或 AI + 无代码自动化的融合路径
评论区见。
更多推荐



所有评论(0)