I hate using "sleepers" (Thread.sleep(millis) ) in tests, but without sleepers some tests fail.
I have a ListView in my Android application and I want to use the first item in the list (SAUDI ARABIA in our case).

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();
The same problem exists in Calabash/Cucumber tests (an explicit wait is required).
I tried different ways of waiting for the item to click
driverWait.until(ExpectedConditions.visibilityOfElementLocated(By));driverWait.until(ExpectedConditions.visibilityOf(WebElement));driverWait.until(ExpectedConditions.elementToBeClickable(By));driverWait.until(ExpectedConditions.presenceOfElementLocated(By));
and no one works. At the moment when I try to click on the 1st item in the ListView , the ListView exists and all the list items are on the screen.
I tried to find ListView 1st row by getting an XPath list row using the Appium Inspector . The result is the same - the view is not clicked without Thread.sleep .
Using Thread.sleep in tests is really bad practice and makes my tests unstable. In this case, I canβt rely on the test results, as they can fail even if the application works correctly. There's an article about using "wait" and "sleep" in Selenium tests ( Selenium WebDriver is waiting ).
- How to fix such problems in tests?
- How often are
Thread.sleep calls used in the automation world? (I'm mainly an Android developer, not one that has mobile automation experience).
UPDATE: I tried not to mix implicit and explicit expectations, as mentioned by JeffC , and that didn't help.
Here is my test:
@Test public void selectCountryLanguageAndStartApplication() throws Exception { countryLanguagePage.loaded(); countryLanguagePage.selectFirstCountry(); countryLanguagePage.pleaseSelectCountryTextIsHidden(); countryLanguagePage.startClick(); } ... public static void loaded() { driver.findElement(By.id("com.###.debug:id/countries_list_view")); }
I check if the page is loaded in each test. If I use only implicit expectations, the test fails from time to time; if I use only explicit expectations - this is the same, the test fails from time to time.
I found in the Appium tutorial that they use implicit in combination with explicit 1 , 2 . It looks weird according to the docs .
Working solution: I slightly modified the loaded method
public static void loaded() { driver.findElement(By.id("com.###.debug:id/countries_list_view")); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }
Having this dream brings βstabilityβ to test, and I can find the elements and click on them with or without explicit expectation.
Does this mean I have to add "sleep" when a new Activity running (the only working solution for me)? Or am I waiting for activity initialization to go wrong?