2016-12-11 7 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이 필요하지 않습니다. ExpectedConditions.elementToBeClickable(locator)을 사용하는 간단한 WebDriverWait은 잘 작동하며 덜 복잡합니다. 당신이 나의 변화를 받아들이면 당신은 그것을 필요로하지 않아야합니다.

  3. String을 사용하여 로케이터를 전달하지 않으려면 로케이터 클래스 By을 사용하십시오. 이를 해석하고 번역 할 필요가 없으며 더 빠르고 유연 해집니다.

  4. YouTube를 테스트하지 않는 한 (내가 youtube에서 작동하지 않는다고 가정 할 때) 페이지 위쪽의 Trending 링크를 사용하여 Trending 페이지로 이동할 수 있습니다. 시간과 클릭을 절약 해줍니다. 테스트하지 않는 경우 테스트하지 말고 최대한 빨리 어디로 가는지 확인하십시오. 테스트하지 않으려는 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(); 
    } 
} 

당신이 모든을 변경하지 않으려면

는 질문에 대한 대답은 간단 WebDriverWaitFluentWait을 대체합니다.

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

이 정말 나를 많이 이해하는 데 도움

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

와우로 대체 될 것이다. 나는 물건을 간단하게하는 것을 기억해야한다. 1) 좋은 생각 .. 나는 그것을 overthinking했다, 아픈 그 일을해야합니다. 2) 언제 플루 언트 타임을 사용해야합니까? 로딩 시간이 예측할 수 없을 때? 3) 당신이보기에서했던 것처럼 직접 선언하고 선언하십시오. 4) 소프트웨어의 UI를 테스트하고 있습니다. 그것의 주로 UI 탐색. 그것의 맞춤형 RocketChat 응용 프로그램. 그래서 각 클래스는 각 모듈에 대한 단위 테스트입니까? 링크로 이동하거나 공용 정적 드라이버를 참조합니까?오늘 오후에 작업 한 코드에 모든 것을 적용하십시오. – Potion

+0

'FluentWait'는'ExpectedConditions'에 의해 커버되지 않는 커스텀 wait ... something이 필요할 때를위한 것입니다. Java Unit Test 베스트 프랙티스 기사를 읽는 것이 좋습니다. 나는 단위 테스트를 많이하지 않는다. – JeffC

+0

나는 확실히 더 많은 기사에 들어갈 것이다. 테스트 과정이나 계획에 대해 거의 알지 못하고이 임무가 나에게 던져진 이후 조금 붐 .다. 도와 주셔서 감사합니다 – Potion