美文网首页软件测试
Selenium Web Driver自动化测试(java版)系

Selenium Web Driver自动化测试(java版)系

作者: 马可吃菠萝 | 来源:发表于2018-08-03 12:49 被阅读0次

    这篇文章讨论等待和同步的问题。过去我举例子总是用java自带的线程类Thread调用静态方法sleep()来让程序等待一会儿,目的是给网页足够的时间刷新或显示下一个要操作的元素,否则有可能元素还没显示出来呢但代码已经开始定位了。

    但是,这种方式有个缺点,如果你代码中需要等待的情况很多,那你需要在每一个有可能出危险的步骤后面写上这句,比如你写一个网上购物代码:

    而且有时候会浪费很多没必要等待的时间,因为不管怎么样一定会等一个固定的时间。比如你给它定10秒,万一控件在上一步程序执行后就马上出现了呢?那也得等10秒,没商量,没明白的朋友一会儿通过演示就知道了。其实Thread类中还有一个方法叫wait(),也是用来等待的。wait()和sleep()这两者都属线程类方法,控制有限,被称为无条件同步。鉴于无条件同步的缺陷,selenium的开发人员特别设计了一个有条件同步,功能要更强大一些,可以更好地完成同步工作。有条件同步分隐式等待(Implicit Wait)和显示等待(Explicit Wait)。

    首先是隐式等待,代码是:

    implicitlyWait()这个方法接受两个参数,第一个是等待时间数值,用整型表示;第二个是时间单位,用java中的TimeUnit类调用一些枚举常量表示。这些枚举常量包括时(HOURS)/分(MINUTES)/秒(SECONDS)等等,调用的格式是TimeUnit.HOURS/TimeUnit.MINUTES/TimeUnit.SECONDS。这些其实java api里都写了,大家可以去看。有隐式等待参与的代码执行情况如下:每当程序要找某一个或某一组元素时,首先先检查元素在不在,如果在则不用执行隐式等待语句;如果不在,先不报异常,而是等待一段给定的时间,之后再次寻找,还不在则抛异常。举个例子,如果我想给它设置等待10秒,那我的代码可以写成:

    假如我的程序里这时要找一个登录按钮。执行过程就是先找这个按钮,如果没找到不马上抛异常,而是等10秒再检查,再没找到才报异常。再强调一遍,它只作用于寻找某个或某组元素的时候。大家或许已经猜到了,也就是说,隐式等待只在findElement()和findElements()执行时才有可能执行。

    如果你的程序里有好几步关于寻找的代码也没关系,隐式等待让所有的元素都必须按照同一种设置执行,这样写一遍就够了,免去了在危险步骤后都写的麻烦。按惯例把它写在创建driver之后和打开网页之前:

    虽然只写一遍,但它的生命周期却延续至整个程序执行完毕的时候。现在用示例网站hrsystem举个完整的例子。我的测试步骤如下:

    1. 打开网页;
    2. 输入用户名和密码;
    3. 点击登录按钮;
    4. 点击Employee菜单;
    5. 点击Timesheet菜单;
    6. 退出。

    因为篇幅的关系我就不断言了,只写步骤。用隐式等待的写法如下:

    findElement()占了6步,可隐式等待的代码只写了一遍。虽然只是一遍,可这6步每次执行的时候如果当时定位不到要找的元素都会执行一下这句。但这已经很省时间了,你执行一下很可能就会发现好几个元素出现时间很快,根本不用等待。但如果要用无条件同步的话,你不确定哪步需要等待,只好在每步后面都写上等待,既麻烦又浪费时间。

    有隐式就有显式,第二种显式等待要比隐式更高级一点。隐式等待只用写一遍,由每个寻找元素的步骤共享,这本来是优点,但现在假如是大多数元素都不用等多久,只有一个元素需要等待很长时间呢?这种情况特别讨厌,但特容易遇到。只能再判断得精确点了。显式等待就提供了很多种判断方式:

    这些判断方式都是为了检查能不能结束等待的条件。显式等待的语法如下:

    第一句是初始化WebDriverWait这个类,同时设置一个等待时间。与隐式等待不一样的是这个等待时间只能是秒,不能表示小时/分钟/毫秒等其它单位。第二句用WebDriverWait的对象调用until()方法,里面接受一个参数,就是能不能结束等待的条件,ExpectedConditions就是"期望条件"的意思。我选了其中一个判断方式visibilityOfElementLocated,意思是只要被找的元素出现就停止等待。算上前面给的10秒,这两句代码的意思就是在这10秒内不停地检查,只要元素出现就继续执行,不用非要等完这10秒。如果10秒过后还不出现则抛异常。又看出一点比隐式等待强的地方了吧?这10秒不用等完,而是只要满足条件就继续,完全是动态控制。如果要是隐式虽然有时没必要等,可一旦真的开始等了,那也必须把给定的等待时间耗完才能继续。

    当然,显式等待只用在耗时长的元素寻找过程中,别的元素还可以使用统一的隐式等待。还用刚才那个test case,假如Employee菜单出来得比较慢,我需要设置一个显式等待。我把程序改一下:

    我只觉得登录时会花点时间,有可能会影响到下一步,所以我只在点击登录按钮之后加上了显式等待。其他步骤还依然用隐式。大家有时间可以再用另外几种判断方式当作条件试一试。

    有条件同步的功能比无条件同步更强大,感觉也更科学。以后大家写项目时可以扔掉Thread.sleep()了,改用ImplicitlyWait或ExpectedConditions。

    这篇源代码在SeleniumImplicitWaitSeleniumExplicitWait这两个小项目中。

    本篇知识点及注意事项:

    1.有隐式等待参与的代码执行情况如下:每当程序要找某一个或某一组元素时,首先先检查元素在不在,如果在则不用执行隐式等待语句;如果不在,先不报异常,而是等待一段给定的时间,之后再次寻找,还不在则抛异常。隐式等待只在findElement()和findElements()执行时才有可能执行。
    2.隐式等待写在创建driver之后和打开网页之前,其生命周期延续至整个程序执行完毕的时候。
    3.显式等待通过用某种判断方式设置条件这种方法来实现,意思是在一段给定的时间内不停检查条件是否满足,一旦满足则停止等待继续执行后边的程序。超过这段时间还没找到则抛异常。
    4.显式等待比隐式强大的地方有两点 - 1.可以对某些需要很长时间等待的元素额外设置等待时间;2.显式等待在给定时间内一直在检查条件是否满足,只要满足条件就停止等待继续执行后面代码,完全是动态控制。隐式虽然有时没必要等,可一旦真的开始等了,那也必须把给定的等待时间耗完才能继续。

    相关文章

      网友评论

        本文标题:Selenium Web Driver自动化测试(java版)系

        本文链接:https://www.haomeiwen.com/subject/tuuyvftx.html