2016-12-11 5 views
0

So hatte ich es früher arbeiten, aber ich habe etwas in meinem Code vermasselt und jetzt scheint die FluentWait-Methode nicht richtig zu nennen. Wenn ich es mit quickRun auf false gesetzt habe, funktioniert es wie vorgesehen (wegen des impliziten), aber wenn ich es auf wahr setze, tut es das nicht, da es nicht darauf wartet, dass die Elemente korrekt geladen werden. Weiß jemand genau was ich falsch gemacht habe?FluentWait funktioniert nicht richtig: Youtube Beispiel

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

 
}

Antwort

0

würde ich dieses eine andere Art und Weise schreiben und einige Ratschläge anbieten.

  1. Verlangsamen Sie nicht Ihren Test mit "Debug-Modus". Wenn Sie Ihren Test debuggen möchten, verwenden Sie Haltepunkte und gehen Sie durch den Code, um zu sehen, wie es funktioniert.

  2. Sie brauchen FluentWait hier nicht. Eine einfache WebDriverWait mit ExpectedConditions.elementToBeClickable(locator) wird gut funktionieren und ist weniger kompliziert. Sie sollten es nicht einmal brauchen, wenn Sie meine Änderungen akzeptieren.

  3. Lokatoren nicht unter Verwendung von String passie- ren, die gewünschte Lokalisierungsklasse verwenden, By. Sie müssen es nicht interpretieren, übersetzen usw., und es wird schneller und flexibler.

  4. Sofern Sie nicht versuchen, die Benutzeroberfläche zu testen (was davon ausgeht, dass Sie nicht für youtube arbeiten), können Sie einfach über den Link "Trending" oben auf der Seite zur Trendseite navigieren. Es spart Ihnen Zeit und Klicks. Wenn Sie es nicht testen, testen Sie es nicht ... gehen Sie so schnell wie möglich zu Ihrem Ziel. Sie möchten nicht, dass Ihr Test aufgrund der Benutzeroberfläche fehlschlägt, die Sie nicht testen möchten, und Sie möchten, dass Ihre Tests so schnell wie möglich ausgeführt werden. (HINWEIS: Sie können sogar direkt zur Trend-URL navigieren.)

  5. Sie benötigen keine locateClickableElement() Funktionen. Klicken Sie einfach auf die Links ... es sollte ein Liner sein. Wenn es einen Fehler gibt, wird es offensichtlich sein. Sie müssen nicht drucken: "Es ist ein Fehler aufgetreten." nachdem eine Ausnahmemeldung gedruckt wurde.

  6. Sie benötigen nicht die stopTest() Funktionen ... einfach den Test beenden. Wenn der Browser geschlossen wird, ist es offensichtlich, dass der Test abgeschlossen ist.

Der neu geschriebene Code ist unten. Es ist schön und einfach (und kurz) und sollte schneller sein.

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

Wenn Sie nicht wollen, das alles zu ändern, ist die einfache Antwort auf Ihre Frage FluentWait mit WebDriverWait ersetzen.

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

würde durch

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

Wow das ist wirklich half mir so viel zu verstehen, ersetzt werden. Ich sollte daran denken, die Dinge einfach zu halten. 1) Gute Idee .. ich habe es übertrieben, krank machen Sie das unbedingt. 2) Wann brauche ich fluentwait? Wann ist die Ladezeit höchst unvorhersehbar? 3) Ill stellen Sie sicher, dass Sie das direkt tun und erklären Sie sie wie in Ihrem Beispiel 4) Ich teste die Benutzeroberfläche für unsere Software. Es ist hauptsächlich UI-Navigation. Es ist eine maßgeschneiderte RocketChat App. Also ist jede Klasse ein Unit-Test für jedes Modul? Würde ich zu dem Link navigieren oder würde ich mit einem öffentlichen statischen Treiber referenzieren?Ill all dies auf den Code anwenden, an dem ich heute arbeitete – Potion

+0

'FluentWait' ist für, wenn Sie eine benutzerdefinierte warten müssen ... etwas, das nicht von' ExpectedConditions' abgedeckt ist. Ich würde vorschlagen, dass Sie einige Best Practices-Artikel zu Java Unit Test lesen. Ich mache nicht viel Unit-Testing. – JeffC

+0

Ich werde auf jeden Fall in mehr Artikel gehen. Es ist ein wenig Eile, da diese Aufgabe mit wenig oder gar keinem Wissen über den Testprozess oder das Schema auf mich geworfen wurde. Vielen Dank für Ihre Hilfe. – Potion

Verwandte Themen