Fork me on GitHub
Google

思路决定出路

思路决定出路

现在, 3条产品线的自动化都已在进行中,平时大家也都会碰到一些问题,这些问题的解决思路也是决定我们的工作效率的一个关键因素。

今天帮媛媛解决一个问题后,突然有一点感触,就把它写了下来,比较凌乱,大家凑合看看吧!

重点不是在这个问题的复杂程度,而是在我们平时的问题解决思路上。

问题重现:

最初,我们对这个问题的定位:如何实现点击弹出框上的确定按钮。

好,这种情况,我们第一反应肯定是会想到popupwin

  • 于是,不加思索的就直接在代码后面添加了如下的代码

    ie.popupwin.button(:name=>"确定").click

运行代码,页面如上面截图所示,hold在这里,没有继续的意思,关掉IE再想想。

这个时候,我以为是popupwin的问题,接着,思路就开始偏离了。我对问题的定义变为: “这个弹出框是通过一个js弹出来的,捕获不到。”

接着,我google了下“waitr js弹出框”,找到了下面的2种方法,打算分别式试一试:

1.watir1.6.5中有原生方法操作JS的弹出框。

在watir/dialog文件中定义了2个类:Dialog和DialogButton。

Dialog.close方法可以关闭1个js弹出框; Dialog.exists?方法可以判断弹出框是否存在; Dialog.button(name).click方法包含name的窗口模拟按下Enter键;

使用方法:

require 'watir/dialog' 
dia = Watir.Dialog.new 
Dialog::WindowName = '' #IE7和IE8中,js弹出框的title是不同的 
dia.exists? #可以用来判断js alert或js confirm是否存在 
dia.close #关闭弹出的对话框

当然,结果还是一样的,依然hold在那个弹出框界面上。

2. 利用win 32 api 去解决这个问题

大师在博客上的一篇文章:http://www.51testing.com/?uid-170805-action-viewspace-itemid-96033后来还是看了下,大师的代码里居然真的有个死循环,呵呵

利用win 32 api 去解决这个问题,我在copy这大段代码的时候,突然想到了一个问题:

“为什么页面是处在hold的状态,如果说是控件找不到,那么也应该有一个超时的时间,会不会并不是pwaitr识别弹出框的问题?”

于是,我放弃了继续copy这段代码的机会。在代码中加入一些输出来验证自己的猜想:

执行了之后,发现输出“11111111111”之后,就会一直hold,所以我就更加坚信了问题不是在后面的对话框识别问题,因为代码根本就没有运行到这段代码。

最终结论

到这里,基本上定位问题到下面这行代码:

ie.div(:class=>"box-blue-comm").button(:id=>"addCategory").click

事实上,这段代码的确执行成功了,因为我们也看到了该对话框。那么可以肯定的是:这个问题的关键肯定在click方法,很有可能是资源没释放,一直在等待中。

进入到click方法的源码:

    #点击页面控件 
    def click  
      assert_enabled 
      @ole_object.scrollIntoView 
      @ole_object.fireEvent("onmousedown") 
      @ole_object.fireEvent("onmouseup") 
      @ole_object.click(0) 
      @page_container.wait  rescue nil 
    end

很明显,click方法针对的就是ole对象点击实现的,但是注意到最后的一段代码. ole_object 和 page_container之间肯定是有问题的,简单分析一下,不难得出一个结论:

Click方法采用ole对象点击机制实现,而js弹出框是window对象,所以点击完成后,@page_container还存在,@page_container.wait,没法进入到下一段代码的操作中。

OK, click方法不行了,那么doclick方法可以么?(当然试一下就知道肯定可行的).

于是,一个新的尝试就可以进行了。继续看看源码,发现doclick方法和click方法存在着很大的不同。

def doclick(x_point = nil, y_point =nil,timeout = 40)
      if self.class == IELink || self.class == IEButton 
        remote_opera("click",timeout)
      else
        if self.attribute_value("tagName").downcase =="object" || !x_point.nil? || !y_point.nil?
          do_click x_point,y_point
        else
          remote_opera("click",timeout)
        end
      end
   end

Doclick方法实现机制是取到被点对象的区域坐标,模拟鼠标进行点击,所以它会占用鼠标资源,但是不会对出现上面的情况,满足我们的需求。于是问题很好解决了,不需要去copy大段的代码。只需将click改成doclick即可:

ie.div(:class=>"box-blue-comm").button(:id=>"addCategory").doclick

总结:

回过头来,想想最初我们的问题其实是:“如何实现点击弹出框上的确定按钮”,但在解决的过程中变成了:“waitr如何识别js对话框”。

思考了这整个过程,并简单的总结一下,2个问题需要注意:

1. 你的问题是什么?

以前看过一本书<<你的灯亮着么>>,作者用了整本书都围绕着如何解决问题,从定义描述问题-》分析问题-》解决问题的思路。而很多时间出现的问题是,我们在还没弄清楚问题是什么的情况下,就已经开始着手解决问题了,往往会越走越远,在过程中会不断发现新的问题。

共性:google惹的祸,对一些问题不加思考就丢给google了! 看到了大量的信息,会引导你到一个新的问题上。

Action: 想清楚你的问题是什么,然后带着问题去google或向其它同学请教。

2. 平时思考总结了么?

类似Click,doclick,ie.start, ie.navigate,ie.goto,ie.attach…….这些方法,我们都有用过,但我们注意到它们之间的差异了吗?我们有想过去了解他们的差异了吗?存在必定有一定的道理,但我们却最容易忽略这些东西。

共性:能用起来,运行没问题就不会去管它的实现及意义!

Action:在写自动化代码的过程中,适当的去看看它的实现,了解你每个步骤调用的用意,知其所以然才是王道,而不是重复得做着copy,然后修改修改。

comments powered by Disqus

top