自動化測試--8種定位方式以及等待詳解

1.id--標籤中id 的值css

若是開發人員編程規範,頁面的元素id 不重複的且不是動態生成的id時,使用id 定位很是容易。web

//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
//使用id定位元素
WebElement element =  driver.findElement(By.id("CityCode"));

2.name--標籤中name的值chrome

//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">

//使用name定位元素
WebElement cityelement = driver.findElement(By.name("CityCode"));

3.className--標籤中class屬性的值編程

 //<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
//使用className定位
WebElement element = driver.findElement(By.className("form-control"));

4.tagName--標籤名瀏覽器

//<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
//使用標籤名定位元素
WebElement element = driver.findElement(By.tagName("select"));

5.linkText--a標籤中所有的文本值app

//<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="尋寶機器人賽" class="link item_title">尋寶機器人賽</a>
    WebElement comElement = driver.findElement(By.linkText("尋寶機器人賽"));

6.partialLinkText--a標籤中部分的文本值框架

//<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="尋寶機器人賽" class="link item_title">尋寶機器人賽</a>
     WebElement comElement = driver.findElement(By.partialLinkText("尋寶"));

7.CSSSelector--css選擇器(很是重要)dom

 //<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
     WebElement element = driver.findElement(By.cssSelector(".form-control"));
        WebElement element1= driver.findElement(By.cssSelector("select.form-control"));
  /**
       * (有屬性的標籤)很是經常使用CssSelector:標籤名[屬性名='屬性值'][屬性名='屬性值'][屬性名='屬性值'][屬性名='屬性值']
       */
     //<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
    WebElement cityelement = driver.findElement(By.cssSelector("select#CityCode"));
    WebElement cityelement1 = driver.findElement(By.cssSelector("#CityCode"));
    WebElement cityelement2 = driver.findElement(By.cssSelector("select[name='CityCode']"));
    WebElement cityelement3 = driver.findElement(By.cssSelector("select[class='form-control lopicker'][name='CityCode']"));

8.xpath--相對路徑/絕對路徑異步

使用chrome自帶或者火狐的xpath的插件能夠得到元素的相對或者絕對路徑。ide

chrome:

 

fireFox:

     //<select style="width: 33%" id="AreaCode" name="AreaCode" class="form-control lopicker">
     //經過單個屬性定位
     WebElement areaElement = driver.findElement(By.xpath("//*[@id=\"AreaCode\"]"));
     //經過多個屬性定位
     WebElement areaElement1 = driver.findElement(By.xpath("//select[@style='width: 33%' and @name='AreaCode']"));

 

    //<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="尋寶機器人賽" class="link item_title">尋寶機器人賽</a>
     //經過contains表達式
     WebElement comElement1 = driver.findElement(By.xpath("//a[@class='link item_title' and contains(text(),'機器人賽')]"));
     //經過startsWith表達式
     WebElement comElement2 = driver.findElement(By.xpath("//a[@class='link item_title' and starts-with(text(),'尋寶')]"));
     //若是讀者的谷歌版本只支持xpath1.0,因此ends-with不能使用
    // WebElement comElement3 = driver.findElement(By.xpath("//a[@class='link item_title' and ends-with(text(),'機器人賽')]"));
     //若是ends-with不支持,可使用下面方式代替
     WebElement comElement4 = driver.findElement(By.xpath("//a[substring(text(), string-length(text()) - string-length('人賽') +1) = '人賽']"));

 

上面總結了8種定位元素的方法。

下面說明一些特殊狀況:

1.id是動態生成的。

這種狀況下,能夠選擇其餘的定位方式。如cssSelector xPath等

如,生成的id老是以register字符串結尾:

<input id="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" name="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" class="aranea-checkbox" type="checkbox"> </td>

此時,能夠經過xpath的方式來查找

driver.findElement(By.xpath("//input[ends-with(@id,'register')]"));

若是這個動態id有規律可循的話,也能夠經過id來定位元素。具體就不舉例了。

 

2.能夠將查找元素封裝成相應的方法,直接調用。方便添加日誌信息。

    /**
     * 查找元素的方法 element
     */
    public WebElement findElementBy(By by) {
        return driver.findElement(by);
    }

    /**
     * 查找多個元素的方法 elements
     */
    public List<WebElement> findElementsBy(By by) {
        return driver.findElements(by);
    }

    /**
     * 查找到多個元素後,繼續向下查找(定位出一個元素這是一堆相同的elements中 選擇 其中方的 一個 而後在這個選定的中 繼續定位
  */
public WebElement getOneElement(By bys, By by, int index) {
    return findElementsBy(bys).get(index).findElement(by);
}

 

3.在查找元素的時候,會考慮到該元素資源是否已經加載完成。

下面給你們總結一下,關於自動化測試中的「等待」:

1.硬性等待---封裝成方法,方便調用。

/**
* 硬性等待,等待時間爲:sleepTime。
*/
public void Wait(int sleepTime) {
if (sleepTime <= 0) {
return;
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

 

2.隱式等待---這個等待是全局的,是針對當前driver的。一旦設置以後,只要該driver執行findElement或者findElements方法,首先回去找元素,若是沒找到,會在設置的時間內一直輪詢查找,直到timeOut.因爲是全局性的,有些元素不須要等待,因此會形成時間的浪費。由於瀏覽器是自上而下渲染的,若是元素1在元素2的上面,當你第一次查找過元素2,以後再查找元素1的時候,是不須要等待的。可是設置了該全局參數以後,仍是會去等待。

driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

3.顯示等待(推薦使用)

/**
     * 對外提供智能等待 查找元素的方法
     * @param driver
     * @param time
     * 元素的超時等待時間
     * @param by
     * @return
     */
    public static WebElement waitElement(WebDriver driver,int time,By by) {
        WebElement element=null;
        
        WebDriverWait wait = new WebDriverWait(driver, time);
        
        try {
            element = wait.until(new ExpectedCondition<WebElement>() {

                public WebElement apply(WebDriver driver) {
                    WebElement element = driver.findElement(by);
                    return element;
                }
            });
        } catch (TimeoutException e) {
            System.out.println("元素"+by.toString()+" "+time+"S內未能找到");
            logger.info("元素未找到");
        }
        
        
        return element;
        
    }
    
    /**
     * 對外提供智能等待 查找元素的方法,固定的等待超時時間爲5S
     * @param by
     * @return
     */
    public static WebElement waitElement(By by) {
        
        WebDriver driver= GetDriverUtil.getDriver();
        return waitElement(driver, 5, by);
        /*WebElement element = null;
        try {
            element = (new WebDriverWait(driver, 5)).until(new ExpectedCondition<WebElement>() {

                @Override
                public WebElement apply(WebDriver driver) {
                    
                    return driver.findElement(by);
                }

            
            });
        } catch (Exception e) {
            System.out.println("元素"+by.toString()+" "+"5S內未能找到");
            e.printStackTrace();
        }
        
        return element;*/
    }

 上面的ExpectedCondition是咱們本身編寫的,實際上,在selenium的ExpectedConditions類中,已經封裝了各類元素等待條件。有興趣能夠去了解下

能夠去看一下源碼,內部也是使用的匿名內部類new ExpectedCondition{},下面是拿出一個來舉例:

判斷一個元素是否可點擊:

1.該元素在dom中存在

2.該元素可見

3.該元素爲enabled

 

  /**
   * An expectation for checking an element is visible and enabled such that you can click it.
   *
   * @param locator used to find the element
   * @return the WebElement once it is located and clickable (visible and enabled)
   */
  public static ExpectedCondition<WebElement> elementToBeClickable(final By locator) {
//匿名內部類
return new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver driver) {
//判斷元素是否可見 WebElement element
= visibilityOfElementLocated(locator).apply(driver); try {
//若是元素可見而且元素生效的話則返回元素
if (element != null && element.isEnabled()) { return element; } return null; } catch (StaleElementReferenceException e) { return null; } } @Override public String toString() { return "element to be clickable: " + locator; } }; }

 

上面總結的是元素的等待,自動化測試用,還有:等待頁面加載的超時時間測試

a.等待頁面加載,設置超時時間。超時以後,再也不等待,直接去定位某元素。(須要執行js腳本)

    /**
     *等待頁面加載,設置頁面加載的超時時間,若是規定時間內還未加載完成,則中止加載,並定位指定元素
     * @param driver
     * @param timeout
     * @param by
     */
    
    public static void pageLoad(WebDriver driver,int timeout,String url) {
        try {
            //設置頁面加載超時時間
            driver.manage().timeouts().pageLoadTimeout(timeout, TimeUnit.SECONDS);
            driver.get(url);
        } catch (Exception e) {
            ((JavascriptExecutor)driver).executeScript("window.stop()");
        }
        
        driver.findElement(By.id("user[login]")).sendKeys("feifeifei");
        
    }
    

b.有時加載頁面超時,須要刷新一次,並輸出頁面的加載狀態。(須要執行js腳本)

/***
     * 啓動瀏覽器並打開頁面
     */
    public void launchBrowser(String webUrl, int timeOut) {
        //getDriver()就是上一篇博客中講的 封裝獲取driver的方法
        driver = GetDriverUtil.getDriver();
        try {
            //最大化瀏覽器窗口(已經封裝成方法)
            maxWindow();
            //設置等待頁面加載的時間(已經封裝成方法)
            waitForPageLoading(timeOut);
            //打開瀏覽器指定頁面(已經封裝成方法)
            get(webUrl);
        } catch (TimeoutException e) {
            logger.warn("頁面沒有徹底加載出來,刷新重試");
            //刷新頁面
            refresh();
            //建立js腳本執行器
            JavascriptExecutor js = (JavascriptExecutor) driver;
            //執行腳本,描述了文檔的加載狀態. 狀態分爲
            //loading document 仍在加載
            //interactive / 互動    文檔已經完成加載,文檔已被解析,可是諸如圖像,樣式表和框架之類的子資源仍在加載
            //complete / 完成   T文檔和全部子資源已完成加載。狀態表示 load 事件即將被觸發。
            
            String status = (String) js.executeScript("return document.readyState");
            //將返回的狀態經過日誌打印出來
            logger.info("打印狀態:" + status);
        }

    }

 

    在自動化測試過程當中,還常常遇到異步請求的狀況,以下圖:


當須要進行異步請求元素的定位時,則須要等待異步腳本執行完成並返回結果。這時須要設置異步腳本的超時時間。
/** setScriptTimeout。異步腳本的超時時間。(封裝成方法,方便調用)webdriver能夠異步執行腳本,這個是設置異步執行腳本腳本返回結果的超時時間 */
    public void setScriptTimeout(int timeOut) {
        driver.manage().timeouts().setScriptTimeout(timeOut, TimeUnit.SECONDS);
    }
 

 

以上,詳細介紹了硬性等待、隱式等待、只能等待、頁面加載超時、異步腳本超時的經常使用方法。但願給你們帶來幫助。
相關文章
相關標籤/搜索