Appium + Selenium Android:没有Thread.sleep时没有点击ListView项目

Vea*_*rji 6 selenium android automated-tests selenium-webdriver appium

我讨厌(Thread.sleep(millis)在测试中使用"睡眠者" ,但没有睡眠者,一些测试失败了.

我有一个ListView在我的Android应用程序中,我想点击列表中的第一项(在我们的案例中是沙特阿拉伯).

国家ListView

 public AndroidDriver androidDriver;
 ...
 androidDriver = new AndroidDriver(serverAddress, capabilities);
 androidDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
 driverWait = new WebDriverWait(androidDriver, 30);
 // at this moment everything is initialized and working properly,
 // Appium server is up and running
 driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("com.###.debug:id/countries_list_view")));
 WebElement countriesList = driver.findElement(By.id("com.###.debug:id/countries_list_view"));
 List<WebElement> countries = countriesList.findElements(By.id("com.###.debug:id/list_item_container"));
 WebElement country = countries.get(0);
 // country isn't null, and it corresponds to a real ListView row
 driverWait.until(ExpectedConditions.elementToBeClickable(country));
 Thread.sleep(1000); // <---- country isn't clicked without this
 country.click();
Run Code Online (Sandbox Code Playgroud)

Calabash/Cucumber测试中存在同样的问题(需要显式等待).

我已经尝试了不同的方法来等待应该点击的元素

  • driverWait.until(ExpectedConditions.visibilityOfElementLocated(By));
  • driverWait.until(ExpectedConditions.visibilityOf(WebElement));
  • driverWait.until(ExpectedConditions.elementToBeClickable(By));
  • driverWait.until(ExpectedConditions.presenceOfElementLocated(By));

没有人在工作.当我尝试点击第ListView一个项目时,ListView存在并且所有列表元素都在屏幕上.

我试图找到ListView通过获取列表中排第1行XPath使用Appium Inspector.结果是相同的 - 没有点击视图Thread.sleep.

Thread.sleep在测试中使用是非常糟糕的做法,使我的测试不稳定.在这种情况下,我不能依赖测试结果,因为即使应用程序正常工作,它们也可能会失败.在Selenium测试中有一篇关于"等待"和"睡眠"用法的文章(Selenium WebDriver等).

  1. 如何在测试中修复此类问题?
  2. Thread.sleep在自动化世界中使用的呼叫频率如何 (我主要是Android开发人员,而不是移动自动化方面的经验).

更新: 我试图不要像JeffC提到的那样混淆隐式和显式等待,但它没有帮助.

这是我的测试:

@Test
public void selectCountryLanguageAndStartApplication() throws Exception {
    countryLanguagePage.loaded();
    countryLanguagePage.selectFirstCountry();
    countryLanguagePage.pleaseSelectCountryTextIsHidden();
    countryLanguagePage.startClick();
}
...
/**
 * Verify the page has loaded
 */
public static void loaded() {
    driver.findElement(By.id("com.###.debug:id/countries_list_view"));
}
Run Code Online (Sandbox Code Playgroud)

我正在验证每个测试中是否加载了页面.如果我只使用隐式等待 - 测试会不时失败; 如果我只使用显式等待 - 它是相同的,测试会不时失败.

我在发现Appium教程,他们使用隐含连同明确的人1,2.根据文档,它看起来很奇怪.

工作解决方案:我修改了一点loaded方法

public static void loaded() {
   driver.findElement(By.id("com.###.debug:id/countries_list_view"));
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

让睡眠带来"稳定性"进行测试,我可以找到元素并按明确等待或没有它们按下它们.

这是否意味着,我应该在新Activity推出时添加"睡眠" (对我来说唯一可行的解​​决方案)?或者我正在以错误的方式等待Activity初始化?

Lia*_*ris 0

你可以试试这个:

  WebDriverWait wait = new WebDriverWait(driver, 30); 
  wait.until(ExpectedConditions.elementToBeClickable(By));
Run Code Online (Sandbox Code Playgroud)

或者

while(!driver.findElement(By).isDisplayed())
{
  //Thread.sleep(10);
}
Run Code Online (Sandbox Code Playgroud)

我认为Thread.sleep调用很好用(如果您的测试涉及计时,则几乎是必要的),但在大多数情况下,有更好的方法来处理它们将用于的大多数事情。

希望这可以帮助,

利亚姆