首页 > 代码库 > java + selenium测试框架(之等待机制) 版本演化二

java + selenium测试框架(之等待机制) 版本演化二

使用selenium-ide录制,以及直接用selenium-java.jar写测试用例,你会发现它的执行速度很快。大大超过了手工操作的速度,甚至可能也超过了浏览器加载的速度(比浏览器都快?结果就是找不到元素)。

如果页面上确实有某个元素,但是在测试时提示NoSuchElementException,那原因有两个:1,你抓取元素的策略错了;2,执行时元素还没加载出来。

在调用了driver.get(url)之后,为了保证元素能够取到正确初始化,需要增加一个等待加载完成的函数,保证页面完成加载。

抛出第一个问题 如何确认页面加载完成?

如何确认页面加载完成?

在selenium中,提供了一个class WaitForPageToLoad,WaitForPageToLoad中的等待机制,提供了两种方法:一是使用js执行document[‘readyState‘];。如果不支持该方法,则使用第二种方法,如果在1s中,页面的长度没有发生变化,则认为已经加载完了。

如果在等待一个设定的超长时间没有完成,则终止。

页面加载时调用waitforpagetoload

WebDriver中并没有提供该函数,它被封装在selenium中。为了在使用WebDriver的程序中,能够使用selenium RC的功能,需要引入向前兼容的WebDriverBackedSelenium。

public class BaiduMainPageWaitTest{    protected WebDriver driver = null;    protected Selenium  selenium = null;    protected BaiduMainPage page = null;    @BeforeClass    public void init() {        System.setProperty("webdriver.ie.driver","lib\\IEDriverServer.exe");        DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();        ieCapabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);        /**         * <b>WebDriverBackedSelenium </b>         * Allows for WebDriver and Selenium to live side-by-side.<br/>         * Provides a simple mechanism for a managed migration from the          * existing Selenium API to WebDriver‘s.<br/>         * Does not require the standalone Selenium RC server to be run.<br/>         */        driver = new InternetExplorerDriver(ieCapabilities);    }    @BeforeMethod    public void initPage() {        String path = "http://www.baidu.com/";        page = new BaiduMainPage(driver);        selenium = new WebDriverBackedSelenium(driver,path);    //  selenium.open(path);        driver.get(path);        selenium.waitForPageToLoad("5000");        PageFactory.initElements(driver, page);    }    /**     * After creating a WebDriverBackedSelenium instance with a given Driver,      * one does not have to call start() - as the creation of the Driver already started the session.     * At the end of the test, stop() should be called instead of the Driver‘s quit() method.     *     * @see <a href="https://code.google.com/p/selenium/wiki/SeleniumEmulation">Selenium Emulation  Wiki</a>     */    @AfterClass    public void quit() {        try{            selenium.stop();            if(driver != null)                driver.quit();        }   finally {            driver = null;        }    }}

对异步加载的元素增加等待机制

//如下这段摘自网上在Selenium中,提交会引起页面加载的情况下,需要调用waitforpagetoload。   但是在我们的测试中,我发现就算waitforpagetoload成功返回后,也不意味着页面所有元素加载成功。如果此时针对某一个元素进行断言/操作,就会失败。   原来Selenium中的waitforpagetoload方法成功返回后,并未包括页面onload部分的javascript。这就造成测试脚本概率性失败,并且调试十分困难。   

因为页面可能有延迟加载的情况。虽然页面已经渲染完毕,但是可能有AJX延迟加载。有些元素需要等AJAX调用完成后才能显示。这时就需要在页面上增加一个等待机制了。

/** * 用于等待某个元素出现,软等待 * @param by */public boolean wait(final By by){    new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {        public Boolean apply(WebDriver arg0) {            return arg0.findElement(by).isDisplayed();        }    });    return true;}

比如说,你想找某个id="name"的元素:

if (wait(By.id("name")))     xxx;else    throw new ElementNotFoundException("xxx not found");

终极大招 硬等待

方案一:

driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.SECONDS);   

方案二:

public static void sleep(int seconds) {    try {        TimeUnit.SECONDS.sleep(seconds);    } catch (InterruptedException e) {        e.printStackTrace();    }}

java + selenium测试框架(之等待机制) 版本演化二