2016-12-11 116 views
0

因此,我讓它工作得更早,但是我弄亂了我的代碼中的某些內容,現在FluentWait方法似乎沒有正確調用。如果我運行它使用quickRun設置爲false,它會按預期工作(因爲隱式),但是當我將它設置爲true時,它不會等待元素正確加載。有誰知道我做錯了什麼?FluentWait無法正常工作:Youtube示例

package myPackage; 
 

 
import java.util.concurrent.TimeUnit; 
 
import org.junit.After; 
 
import org.junit.Before; 
 
import org.junit.Test; 
 
import org.openqa.selenium.By; 
 
import org.openqa.selenium.NoSuchElementException; 
 
import org.openqa.selenium.WebDriver; 
 
import org.openqa.selenium.WebElement; 
 
import org.openqa.selenium.safari.SafariDriver; 
 
import org.openqa.selenium.support.ui.FluentWait; 
 
import org.openqa.selenium.support.ui.Wait; 
 
import com.google.common.base.Function; 
 

 
//import com.gargoylesoftware.htmlunit.javascript.host.Console; 
 
//https://www.codeproject.com/articles/143430/test-your-web-application-s-ui-with-junit-and-sele 
 

 
//this will open a dynamic page example (ie. youtube) trending 
 
public class youtubeTest { 
 

 
    public boolean quickRun = false; //Disable for debugging otherwise full speed 
 
    private static int defaultDebugDelay = 2; //Time in sec for next test to occur in debug 
 

 
    //do no change any of the below 
 
    private String testUrl; //target url destination ie youtube 
 
    private WebDriver driver; //webdriver instance to reference within class 
 
    private int testIndex = 1; //initial index value for console outputting 
 

 
    public WebElement fluentWait(final By locator) { 
 
    Wait <WebDriver> wait = new FluentWait <WebDriver> (driver) 
 
     .withTimeout(30, TimeUnit.SECONDS) 
 
     .pollingEvery(1, TimeUnit.SECONDS) 
 
     .ignoring(NoSuchElementException.class); 
 

 
    WebElement foo = wait.until(new Function < WebDriver, WebElement >() { 
 
     public WebElement apply(WebDriver driver) { 
 
     return driver.findElement(locator); 
 
     } 
 
    }); 
 

 
    return foo; 
 
    }; 
 

 
    @ 
 
    Before 
 
    public void beforeTest() { 
 
    driver = new SafariDriver(); 
 
    System.out.println("Setting up Test..."); 
 
    if (quickRun) { 
 
     System.out.println("Test Type: Quick Run (Fastest Mode)"); 
 
    } else { 
 
     System.out.println("Test Type: Slow Run (Debug Mode) - Each Test has a " + defaultDebugDelay + " sec call time buffer"); 
 
    } 
 
    testUrl = "https://www.youtube.com"; 
 
    driver.get(testUrl); 
 
    System.out.println("Setting Driver " + driver + "for url: " + testUrl); 
 

 
    } 
 

 
    @ 
 
    Test 
 
    public void Test() { 
 
    //insert unit tests within here 
 
    //open yt nav menu 
 
    locateClickableElement("#appbar-guide-button"); 
 
    //go to trending 
 
    locateClickableElement("#trending-guide-item"); 
 
    //click on 4th Trending video from list 
 
    //locateClickableElement(".expanded-shelf-content-item-wrapper", 3); 
 
    locateClickableElement(".expanded-shelf-content-item-wrapper"); 
 

 

 
    } 
 

 
    @ 
 
    After 
 
    public void afterTest() throws Exception { 
 
    //wait 10 sec before closing test indefinitely 
 
    System.out.println("Test auto ending in 10 seconds..."); 
 
    Thread.sleep(10000); 
 
    stopTest(); 
 
    } 
 

 
    //individual unit tests 
 
    private void locateClickableElement(String ExpectedElement, int child) { 
 
    //format string into something like: "ELEMENT:nth-child(1)" 
 
    String formattedString = ExpectedElement + ":nth-child(" + child + ")"; 
 
    System.out.println("Strung: " + formattedString); 
 
    locateClickableElement(formattedString); 
 
    } 
 

 
    private void locateClickableElement(String ExpectedElement) { 
 
    try { 
 
     System.out.println("Test " + testIndex + ": locateClickableElement(" + ExpectedElement + ")"); 
 

 
     //do absolute delay for visual debugging 
 
     if (!quickRun) Thread.sleep(2000); 
 

 
     //click on target if found 
 
     fluentWait(By.cssSelector(ExpectedElement)).click(); 
 
     System.out.println("Test " + testIndex + ": Successful Click on Element(" + ExpectedElement + ")"); 
 

 
    } catch (Exception e) { 
 
     //whenever error is found output it and end program 
 
     System.out.println("Error Could not locateClickableElement(" + ExpectedElement + ")"); 
 
     System.out.println("Exception Handled:" + e.getMessage()); 
 
     stopTest("error"); 
 
    } 
 
    testIndex++; 
 
    } 
 

 
    private void stopTest() { 
 
    System.out.println("Test Completed: Reached End."); 
 
    driver.quit(); 
 
    } 
 

 
    private void stopTest(String typeError) { 
 
    System.out.println("Test Completed: With an Error."); 
 
    driver.quit(); 
 
    } 
 

 
}

回答

0

我會寫這樣一個不同的方式,並提供一些建議。

  1. 不要使用「調試模式」降低測試速度。如果您想調試您的測試,請使用斷點並單步執行代碼以查看它的工作方式。

  2. 這裏你不需要FluentWait。一個簡單的WebDriverWait使用ExpectedConditions.elementToBeClickable(locator)將工作得很好,並不複雜。如果您接受我的更改,您甚至不需要它。

  3. 請勿使用String傳遞定位器,請使用預期的定位器類By。你不需要翻譯它,翻譯它等,它會更快,更靈活。

  4. 除非您嘗試測試用戶界面(我假設您不適用於YouTube),那麼您可以使用頁面頂部的趨勢鏈接導航到趨勢頁面。這將節省您的時間和點擊。如果你不測試它,不要測試它......儘可能快地到達你要去的地方。你不希望你的測試失敗,因爲你沒有嘗試測試UI,你總是希望你的測試儘可能快。 (注意:您甚至可以直接導航到趨勢URL。)

  5. 您不需要locateClickableElement()函數。只需點擊鏈接...它應該是一個班輪。如果出現錯誤,這將是顯而易見的。您不需要打印,「出現錯誤。」在打印異常消息之後。

  6. 你不需要stopTest()功能...只是停止測試。當瀏覽器關閉時,顯然測試完成。

重寫的代碼如下。這很好,很簡單(和很短),應該更快。

public class youtubeTest 
{ 
    // do no change any of the below 
    private String testUrl = "https://www.youtube.com"; // target url destination ie youtube 
    private WebDriver driver; // webdriver instance to reference within class 

    private By trendingGuideLinkLocator = By.cssSelector("#trending-guide-item"); 
    private By trendingLinkLocator = By.xpath("//h2[contains(.,'Trending')]"); 

    @Before 
    public void beforeTest() 
    { 
     System.out.println("Setting up Test..."); // if you are going to have this statement, put it at the start of beforeTest() 
     driver = new SafariDriver(); 
     driver.get(testUrl); 
     System.out.println("Set Driver " + driver + "for url: " + testUrl); 
    } 

    @Test 
    public void Test() 
    { 
     // insert unit tests within here 
     driver.findElement(trendingLinkLocator).click(); // just click the Trending link, it's faster 
     driver.findElements(trendingGuideLinkLocator).get(3).click(); 
    } 

    @After 
    public void afterTest() 
    { 
     driver.close(); 
     driver.quit(); 
    } 
} 

如果你不想改變這一切,簡單的回答你的問題是WebDriverWait取代FluentWait

fluentWait(By.cssSelector(ExpectedElement)).click(); 

將由

new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(trendingLinkLocator)).click(); 
+0

哇更換這真的幫助我瞭解了這麼多。我應該記住保持簡單。 1)好主意..我正在推翻它,生病一定要這樣做。 2)我什麼時候需要使用fluentwait?當加載時間非常難以預測? 3)請確保直接執行此操作,並按照您的示例進行聲明4)我正在測試用於我們軟件的UI。它主要是UI導航。它是一個定製的RocketChat應用程序。所以每個類是每個模塊的單元測試?我會導航到鏈接還是我會參考一個公共靜態驅動程序?我將這一切應用到我今天工作的代碼中 – Potion

+0

'FluentWait'適用於需要自定義等待的情況......未由ExpectedConditions覆蓋的情況。我建議你閱讀一些Java單元測試最佳實踐文章。我不做很多單元測試。 – JeffC

+0

我一定會進入更多的文章。由於這項任務幾乎沒有關於測試過程或方案的知識,因此我感到有些匆忙。感謝您的幫助 – Potion

相關問題