2016-12-11 11 views
0

私は以前は動作していましたが、私のコードで何かがうんざりしていましたが、今FluentWaitメソッドが正しく呼び出されていないようです。私がquickRunをfalseに設定して実行した場合、暗黙的に意図したとおりに動作しますが、実際に正しく設定すると、要素が正しく読み込まれるのを待たずに動作します。誰かが私が間違ったことを正確に知っていますか?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は必要ありません。 ExpectedConditions.elementToBeClickable(locator)を使用して単純なWebDriverWaitはうまく動作し、それほど複雑ではありません。あなたが私の変更を受け入れるなら、あなたはそれを必要とすべきではありません。

  3. Stringを使用してロケータを渡さないでください。目的のロケータクラスByを使用してください。あなたはそれを解釈したり翻訳したりする必要はなく、より速く柔軟になります。

  4. UIをテストしようとしていない限り(あなたがyoutubeで動作しないと仮定しています)、ページの上部にある[トレンド]リンクを使用して[トレンド]ページに移動できます。それは時間とクリックを節約します。テストしていない場合は、テストしないでください。できるだけ早くどこに行くのかを確認してください。テストしようとしていないUIが原因でテストが失敗しないようにするため、テストはできるだけ速くしたいと考えています。 (注:トレンドURLに直接移動することもできます)

  5. locateClickableElement()機能は必要ありません。リンクをクリックするだけで1ライナーになるはずです。エラーがある場合は、明らかになります。印刷する必要はありません。「エラーが発生しました。」例外メッセージが印刷された後。

  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(); 
    } 
} 

あなたはこのすべてを変更したくない場合は、あなたの質問に簡単な答えはWebDriverWaitFluentWaitを交換です。

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

が、これは本当に私はあまり理解して助けた

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

うわーによって置き換えられます。物事を単純にすることを忘れないでください。 1)良いアイデア..私はそれをやり過ぎていた、それを行うことを確認してください。 2)いつFluentwaitを使う必要がありますか?ローディング時間が非常に予測できないときは? 3)私はそれを直接行い、あなたの例と同様に宣言してください。4)私たちのソフトウェアのUIをテストしています。主にUIナビゲーション。カスタマイズされたRocketChat App。だから各クラスは各モジュールのユニットテストですか?リンクに移動するか、パブリックな静的なドライバで参照しますか?病気は私が今日働いていたコードにすべて適用します – Potion

+0

'FluentWait'は' ExpectedConditions'でカバーされていないカスタム待ちを必要とするときです。私はいくつかのJava Unit Testベストプラクティスの記事を読むことをお勧めします。私は単体テストをたくさんしません。 – JeffC

+0

私は間違いなくもっと多くの記事に行きます。この課題がテストプロセスやスキームについてほとんど、あるいはまったく知らされずに私に投げられて以来、少し急いでいました。助けてくれてありがとう – Potion

関連する問題