RFT无法识别windows对话框的处理方法
上一篇 / 下一篇 2008-07-02 22:36:20 / 个人分类:RFT
一、概述
!} G~O}V;}6OS051Testing软件测试网7@*p n*L6zP/R1l#PRFT中提供了find方法,这是一个很强大的工具,可以让我们在脱离测试对象的情况下运行测试脚本,这样我们的脚本就有了很好的健壮性和可移植性(在去年的自动化测试项目中,QTP就经常因为测试对象的属性问题导致脚本运行失败)。但是今天在利用测试对象检查器获取windows对话框属性时,碰到了一个很极端的问题,对象检查器竟然无法识别windows对话框。最后几经周折,终于解决了这个问题
+o:^G+J'i bx!k1F051Testing软件测试网(ng0| @0@:U,S*k+o二、问题51Testing软件测试网#q~Qnf$K5URF*Q!W
v-n,c5o1A0dG:_0脚本的操作过程是这样的,首先点击界面中的导出按钮,这时系统会弹出一个是否保存的确认提示框,这时点击“是”,然后系统会在该对话框的基础上打开一个新的文件保存对话框。这时我发现用测试对象检查器根本无法获取到该对象的任何属性,用find方法查找时也找不到任何的对象。使用的属性是“.name”,属性值是"另存为"
:^ lu"Q1_051Testing软件测试网#A5u$}!SG^vR三、分析
;Q |!sVX6K-J051Testing软件测试网9?Z$|t8{O该问题的根本原因在于RFT的对象识别机制。通过查阅资料和api,我觉的RFT所能处理的对象关系可以分为两种,一种是父子关系的对象集合,另一种我们暂且叫做顶层——下层关系的对象集合。举个简单的例子,一个拥有“确定”“取消”两个按钮的确认提示框就是父子关系的对象,确认提示框是父对象,确定按钮和取消按钮就是这个按钮的子对象。父子类型的对象可以很容易的被对象检查器或find方法找到;顶层——下层关系的对象就象我们上面举的那个例子:在已经存在的windows对话框的基础上,又出现了一个对话框。两个对话框并非是父子关系,而是一种嵌套关系,并且很明显,其中有一个对话框是顶层窗口,也就是焦点的拥有者,在开发上也有叫做模态窗口的。顶层——下层对象不能被对象检查器所识别。当然,这些都是我目前对rft的理解,IBM的网站并没见过类似的解释。利用GuiTestObject我们可以很方便的处理父子关系的对象,但是对于顶层——下层关系的对象,GuiTestObject对象则无能为力(至少在我这里是这样)
"Iku+fH051Testing软件测试网(S3hnUpcVv四、解决
:cr8mkv eJ!u I\+LQ@051Testing软件测试网Y U$u0qpyop3z要解决该问题不妨换一个角度,RFT提供了访问window平台控件的接口,那就是IWindow。既然我们不能通过TestObject类获取保存对话框的属性,那么我们就把保存对话框当成是一个windows对象,用IWindow来识别。我们需要解决以下问题:
yy8e(@,?p0K,|e6{4e @01、首先让脚本获取到文件保存对话框对象,该对象的类型是IWindow,对象获取可以使用getText返回的属性,文件保存对话框的getText会返回“另存为”。
/u|LNc^b0.sH3Drl[.~'h02、调用IWindow的inputChars录入文件保存的目录。51Testing软件测试网:k5FTcg%LG
51Testing软件测试网?5Hw1pE/X3、让脚本获取到该保存对话框对象的子对象“保存”按钮,并执行点击操作51Testing软件测试网$u#Z)S+La0^(|G
J@ sr"Zb0为了实现以上的功能,我们需要两个方法,分别是getTopWindow和getLevelWindow,在IBM网站上有篇相关的文章,链接请见第五节,这里直接贴出代码:51Testing软件测试网M E"V.`"Wh*o
- /**
- * 返回window系统中顶层窗口的对象,例如getTopWindow("另存为")将返回一个windows另存为对话框,与getLevelWindow不同的是,Topwindow对象可以执行inputChars方法,而LevelWindow则不行.
- * @param objName windows窗体、对话框、元素的getText属性
- * @return IWindow windows控件(对象),该对象是顶层窗口
- */
- public IWindow getTopWindow(String objName) {
- IWindow[] wins = RationalTestscrīpt.getTopWindows();
- int length = wins.length;
- for (int i = 0; i < length; i++) {
- if (wins[i].getText().matches(objName)) {
- return wins[i];
- }
- }
- return null;
- }
/** * 返回window系统中顶层窗口的对象,例如getTopWindow("另存为")将返回一个windows另存为对话框,与getLevelWindow不同的是,Topwindow对象可以执行inputChars方法,而LevelWindow则不行. * @param objName windows窗体、对话框、元素的getText属性 * @return IWindow windows控件(对象),该对象是顶层窗口 */ public IWindow getTopWindow(String objName) { IWindow[] wins = RationalTestscrīpt.getTopWindows(); int length = wins.length; for (int i = 0; i < length; i++) { if (wins[i].getText().matches(objName)) { return wins[i]; } } return null; }
- <PRE class=java name="code">/**
- * 对于某些二级弹出窗口,可用该方法进行识别和操作,该方法返回指定名称的对象,例如getWinObject("另存为","保存(&S)"),该方法回返回windows保存对话框中的"保存"按钮.
- *
- * @param topWinName
- * 顶层窗口对象的getText属性
- * @param levelWinName
- * 顶层对象下子对象的getText属性
- * @return IWindow对象,该对象可执行单击和双击的操作.
- */
- public IWindow getLevelWindow(String topWinName, String levelWinName) {
- IWindow winobjects = null;
- IWindow[] wins = RationalTestscrīpt.getTopWindows();// 返回windows对象数组
- for (int i = 0; i < wins.length; i++) {// 在数组中查找所有符合topWinName属性的对象
- if (wins[i].getText().equals(topWinName)) {
- winobjects = wins[i];
- }
- }
- IWindow[] winobj = winobjects.getChildren();
- for (int i = 0; i < winobj.length; i++) {
- if (winobj[i].getText().equals(levelWinName)) {// 在顶层对象中,查找符合levelName属性的对象
- return winobj[i];
- }
- }
- return null;
- }</PRE>
- <PRE class=java name="code">最后实现文件保存框识别和文件保存的代码如下:</PRE>
- <PRE class=java name="code">test.getLevelWindow("另存为", "文件名(&N):").click();//点击文件保存文本框,获取焦点.
- test.getTopWindow("另存为").inputChars("c:\\result.xls");//录入保存文件的对话框</PRE>
- /**
- * 对于某些二级弹出窗口,可用该方法进行识别和操作,该方法返回指定名称的对象,例如getWinObject("另存为","保存(&S)"),该方法回返回windows保存对话框中的"保存"按钮.
- *
- * @param topWinName
- * 顶层窗口对象的getText属性
- * @param levelWinName
- * 顶层对象下子对象的getText属性
- * @return IWindow对象,该对象可执行单击和双击的操作.
- */
- public IWindow getLevelWindow(String topWinName, String levelWinName) {
- IWindow winobjects = null;
- IWindow[] wins = RationalTestscrīpt.getTopWindows();// 返回windows对象数组
- for (int i = 0; i < wins.length; i++) {// 在数组中查找所有符合topWinName属性的对象
- if (wins[i].getText().equals(topWinName)) {
- winobjects = wins[i];
- }
- }
- IWindow[] winobj = winobjects.getChildren();
- for (int i = 0; i < winobj.length; i++) {
- if (winobj[i].getText().equals(levelWinName)) {// 在顶层对象中,查找符合levelName属性的对象
- return winobj[i];
- }
- }
- return null;
- }
/** * 对于某些二级弹出窗口,可用该方法进行识别和操作,该方法返回指定名称的对象,例如getWinObject("另存为","保存(&S)"),该方法回返回windows保存对话框中的"保存"按钮. * * @param topWinName * 顶层窗口对象的getText属性 * @param levelWinName * 顶层对象下子对象的getText属性 * @return IWindow对象,该对象可执行单击和双击的操作. */ public IWindow getLevelWindow(String topWinName, String levelWinName) { IWindow winobjects = null; IWindow[] wins = RationalTestscrīpt.getTopWindows();// 返回windows对象数组 for (int i = 0; i < wins.length; i++) {// 在数组中查找所有符合topWinName属性的对象 if (wins[i].getText().equals(topWinName)) { winobjects = wins[i]; } } IWindow[] winobj = winobjects.getChildren(); for (int i = 0; i < winobj.length; i++) { if (winobj[i].getText().equals(levelWinName)) {// 在顶层对象中,查找符合levelName属性的对象 return winobj[i]; } } return null; }
- 最后实现文件保存框识别和文件保存的代码如下:
最后实现文件保存框识别和文件保存的代码如下:
- test.getLevelWindow("另存为", "文件名(&N):").click();//点击文件保存文本框,获取焦点.
- test.getTopWindow("另存为").inputChars("c:\\result.xls");//录入保存文件的对话框
test.getLevelWindow("另存为", "文件名(&N):").click();//点击文件保存文本框,获取焦点. test.getTopWindow("另存为").inputChars("c:\\result.xls");//录入保存文件的对话框
w FLx5_ u4v!N.@0五、小结
n.v\i0[guG0当代码完成后,我发现这个问题其实并不复杂,所有的类和方法rft都已经提供了,只是由于以前我不熟悉IWindow的用法,所以走了不少的弯路,直到看到ibm网站上的一篇文章才豁然开朗。其实不仅仅是保存对话框,任何windows平台的控件,我们都可以用IWindow来实现查找和定位。
b5gi_:f*lns0
六、参考
《扩展 Rational Functional Tester 的对象识别技术》