当前位置: 代码网 > it编程>软件设计>软件测试 > Selenium 自动化 —— 四种等待(wait)机制

Selenium 自动化 —— 四种等待(wait)机制

2024年08月02日 软件测试 我要评论
本文介绍了4种等待机制(包括默认的),有了这些等待,可以大大的提高我们测试的准确性和稳定性。这几种机制没有哪个最好,我们需要根据实际的情况选择最合适的等待。

 更多关于selenium的知识请访问csnd论坛“兰亭序咖啡”的专栏:专栏《selenium 从入门到精通》


目录

目录

需要等待的场景

自己实现等待逻辑

selenium 提供的三种等待机制

隐式等待(implicit waits)

隐式等待的优点

隐式等待的缺点

显式等待(explicit waits)

显式等待的优点

显式等待的缺点

自定义等待(custom waits)

自定义等待的优点

自定义等待的缺点

总结


需要等待的场景

在 ui 自动化时,我们通常需要等待,比如以下场景:

  •  登录后,页面会跳转,我们需要等待页面完全加载(否则,没ready访问元素会找不到
  • 点击搜索按钮后,页面异步刷新,我们需要等待加载框消失(否则,结果还没有update,拿到错误的数据
  • 页面满足部分条件后,预定按钮才会可以点击,我们需要等待它变成激活状态(否则,按钮还是disabled的状态,出现点击报错
  • ……

总之,这些等待,对于我们测试的稳定性和正确性非常重要。

自己实现等待逻辑

最简单的方法是,我们自己写一个while循环不断地检查条件是否满足。

while(true){
   if(checkcondition()){
      dosomething();
   }else{
      thread.sleep(n秒);
   }
}

不过这么做不但麻烦,自己实现也容易出错。值得庆幸的是,selenium 就提供了内置的机制,帮助我们实现等待的功能。

selenium 提供的三种等待机制

selenium 查找元素默认是没有等待的,也就是说找到了就返回webelement,否则就抛出异常。

我们测试一下,没有配置任何等待:

@test
public void testdefault(){
    webdriver driver = null;
    long begin = 0;
    try{
        driver = new chromedriver();

        driver.get("https://mail.163.com");
        begin = system.currenttimemillis();
        webelement element = driver.findelement(by.id("inexistence"));
    }finally {
        long end = system.currenttimemillis();
        log.info("花费时间:{}毫秒", end-begin);
        driver.close();
    }
}

日志打印:-- 花费时间:100毫秒(这个很短的时间是findelement本身执行遍历dom需要的一些时间

抛出异常:

selenium 提供了等待机制,我们可以通过配置或者调用,很方便的实现我们等待的需求。

selenium 主要分为:

  1. 显式等待(explicit waits)
  2. 隐式等待(implicit waits)
  3. 自定义等待(custom waits)

 下面我们分别介绍它们。

隐式等待(implicit waits)

隐式等待是全局设置,设置一次后,对整个webdriver实例生命周期内的所有查找元素操作生效。

它会让webdriver在寻找元素时,如果元素没有立即找到,就等待一段时间再查找,直到超过设定的最大时间或者找到元素为止。

下面是我们显式等待的测试代码:

@test
public void testimplicit (){
    webdriver driver = null;
    long begin = 0;
    try{
        driver = new chromedriver();
        // 设置隐式等待时间为10秒
        driver.manage().timeouts().implicitlywait(duration.ofseconds(10));

        driver.get("https://mail.163.com");
        webelement element = driver.findelement(by.id("inexistence"));
    }finally {
        long end = system.currenttimemillis();
        log.info("花费时间:{}毫秒", end-begin);
        driver.close();
    }
}

其实相对于默认的机制,我们只是加了一行配置的代码:

driver.manage().timeouts().implicitlywait(duration.ofseconds(10));

但是效果却非常大:

日志打印:-- 花费时间:10129毫秒(去除方法本身的执行时间,等待时间大于就是10秒

抛出的异常还是找不到元素:

当然不是说一定要等待这么久,如果找到了元素,会立刻返回!

等待时间只是超时时间。

隐式等待的优点

简单,一条配置,全局都有效。

driver.manage().timeouts().implicitlywait(duration.ofseconds(10));

隐式等待的缺点

等待的时间是全局的,但是不同元素、不同页面、甚至不同网络的加载情况不一样,不能对每种元素设置不同的等待时间。

使用不当的话,会对整个测试的效率造成非常大的影响。

比如,我们很多地方会用检查一个元素存不存在,来判断不同的情况。

element ele = findelement(xxx);
if(ele == null){ // 当然默认找不到元素会抛异常而不是为null,不过我们可以使用findelements
   dosometing();
}else{
   dootherthing();
}

如果很多地方都这样检查,那么花费的时间会很长很长!

显式等待(explicit waits)

上面说过,隐式等待是全局一致的,如果我们想更灵活的等待,对一些元素希望等待时间可以短一些,对另一些希望能够多等一些时间,这时显式等待就派上用场了。

@test
public void testexplicitwait(){
    webdriver driver = null;
    long begin = 0;
    try{
        driver = new chromedriver();

        driver.get("https://mail.163.com");
        begin = system.currenttimemillis();

        // 等待id为"someid"的元素出现
        webelement element = new webdriverwait(driver, duration.ofseconds(10))
                .until(expectedconditions.presenceofelementlocated(by.id("someid")));

        // 等待加载图标(class为"loading-spinner")消失
        new webdriverwait(driver, duration.ofseconds(10))
                .until(expectedconditions.invisibilityofelementlocated(by.classname("loading-spinner")));

    }finally {
        long end = system.currenttimemillis();
        log.info("花费时间:{}毫秒", end-begin);
        driver.close();
    }
}

可以看到,我们可以对不同的元素设置不同的等待时间

new webdriverwait(driver, java.time.duration.ofseconds(10))

这些wait,其实也是可以复用的,比如10s的等待的wait,可以被用来检查各种元素。

还能对它们设置不同的条件,比如等待元素的出现、消失

wait.until(expectedconditions.presenceofelementlocated(by.id("someid")));
wait..until(expectedconditions.invisibilityofelementlocated(by.classname("loading-spinner")));

expectedconditions 类内置了常用的各种等待条件,满足我们大部分的场景:

显式等待的优点

更精细更灵活的控制:

1. 对不同的元素设置不同的等待时间

2. 对不同的元素设置不同的等待条件

显式等待的缺点

更复杂,维护起来也麻烦。

如果不是很熟悉,乱使用,容易适得其反。

自定义等待(custom waits)

显式等待看上去很强大了,是不是就很完美了呢?

特殊场景下,如果你又更苛刻的要求,你也可以定制化自己的等待,进一步的更精细的控制等待,比如:

  •  自定义重试检查的周期
  • 找不到抛异常时,想根据exception做一些处理(因为隐式、显式等待超时后都是直接抛出timeout异常的,默认不做处理往外抛)
  • 定制超时后的异常消息文本
    @test
    public void test() {
        webdriver driver = null;
        long begin = 0;
        try {
            driver = new chromedriver();

            driver.get("https://mail.163.com");
            begin = system.currenttimemillis();

            wait<webdriver> wait =
                    new fluentwait<>(driver)
                            .withtimeout(duration.ofseconds(2))
                            .pollingevery(duration.ofmillis(300))
                            .ignoring(elementnotinteractableexception.class);
            wait.until(expectedconditions.visibilityofelementlocated(by.classname("no-no")));
        } finally {
            long end = system.currenttimemillis();
            log.info("花费时间:{}毫秒", end - begin);
            driver.close();
        }
    }

自定义等待的优点

更灵活、更精细的控制

自定义等待的缺点

太复杂,使用前请认真思考,我们真的需要这么细致的控制吗?

总结

本文介绍了4种等待机制(包括默认的),有了这些等待,可以大大的提高我们测试的准确性和稳定性。这几种机制没有哪个最好,我们需要根据实际的情况选择最合适的等待。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com