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. Простой WebDriverWait с использованием ExpectedConditions.elementToBeClickable(locator) будет работать просто отлично и менее сложно. Вы даже не нуждаетесь в этом, если принимаете мои изменения.

  3. Не пропускайте локаторы с использованием String, используйте назначенный класс локатора, By. Вам не придется его интерпретировать, переводить и т. Д., И это будет быстрее и гибче.

  4. Если вы не пытаетесь протестировать пользовательский интерфейс (который я предполагаю, что вы не работаете на YouTube), вы можете просто перейти на страницу «Тренд», используя ссылку «Тренд» в верхней части страницы. Это сэкономит вам время и клики. Если вы не тестируете его, не проверяйте его ... добирайтесь туда, куда вы отправляетесь как можно быстрее. Вы не хотите, чтобы ваш тест потерпел неудачу из-за пользовательского интерфейса, который вы не пытаетесь протестировать, и вы всегда хотите, чтобы ваши тесты проходили как можно быстрее. (ПРИМЕЧАНИЕ. Вы можете даже перейти непосредственно к 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(); 
    } 
} 

Если вы не хотите, чтобы все это изменить, простой ответ на ваш вопрос заменить FluentWait с WebDriverWait.

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

будет заменен

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

Wow это действительно помогло мне понять так много. Я должен помнить, что все просто. 1) Хорошая идея .. я переусердствовал, плохо сделай это. 2) Когда мне понадобится использовать fluentwait? Когда время загрузки очень непредсказуемо? 3) Не забудьте просто сделать это прямо и объявить их так же, как в своем примере. 4) Я тестирую интерфейс для нашего программного обеспечения. Его главным образом интерфейс навигации. Его настроенное приложение RocketChat. Итак, каждый класс является модульным тестом для каждого модуля? Могу ли я перейти к ссылке или ссылаться на публичный статический драйвер?Ill применить все это к коду, который я работал сегодня. – Potion

+0

'FluentWait' предназначен для тех случаев, когда вам требуется пользовательское ожидание ... что-то, что не покрывается' ExpectedConditions'. Я бы посоветовал вам прочитать некоторые статьи по лучшей практике Java Unit Test. Я не делаю много модульного тестирования. – JeffC

+0

Я обязательно зайду в другие статьи. Его немного поспешил, так как это задание было брошено на меня с небольшим количеством знаний о процессе или схеме тестирования. Спасибо за помощь – Potion