Espresso vs UiAutomator2 in Appium

maxresdefault

     Espresso is an Android test automation library maintained by Google. It has a number of advantages, for example built-in view synchronization that ensures element finding happens during idle periods in your app. Most people assume Espresso is an alternative to Appium; you’d pick either Appium or Espresso, not both. From this perspective, there’s nothing odd about creating an Appium Espresso driver. And that is exactly what we’ve done. For some time we’ve been working on a very rough beta (really alpha) version of an Appium driver that runs Espresso under the hood. This means the same kind of Appium script you’re used to writing, but running on Google’s top-tier automation technology.

     In essence, it’s pretty simple: we just change the automationName capability to Espresso (instead of, say, UiAutomator2 if you’re using the current standard Android driver for Appium). By designating this automation name, Appium will know to start an Espresso session instead of something else.

     You will get the Espresso driver in Appium by installing the new version of Appium (npm install -g appium@beta).

     The best way to show off what you can currently do with the Espresso beta is with a comparison. The code for this article is therefore the same test (of a basic login flow) run on both UiAutomator2 and Espresso drivers. Let’s take a look at the code for the standard UiAutomator2 driver first:

@Test
public void testLogin_UiAutomator2() throws MalformedURLException {
    AndroidDriver driver = getDriver(“UiAutomator2“);
    WebDriverWait wait = new WebDriverWait(driver, 10);
    ExpectedCondition loginScreenReady =
    ExpectedConditions.presenceOfElementLocated(loginScreen);
    ExpectedCondition usernameReady =
    ExpectedConditions.presenceOfElementLocated(username);
    ExpectedCondition verificationReady =
    ExpectedConditions.presenceOfElementLocated(verificationTextUiAuto2);
 
    try {
        wait.until(loginScreenReady).click();
        wait.until(usernameReady).sendKeys(“sanoj”);
        driver.findElement(password).sendKeys(“mypassword”);
        driver.findElement(loginBtn).click();
        wait.until(verificationReady);
    } finally {
        driver.quit();
    }
}

     The first thing to observe about this snippet is that we have a helper method, getDriver, which simply takes the automation name and gets us an instance of AndroidDriver. This is so we can reduce code duplication when we do the same thing for the Espresso version of the test (and to show that all the capabilities are the same, other than automationName). Next, we set up 3 expected conditions for user later on in the test. Finally, our test flow itself is 5 steps long, utilizing pre-defined locator fields like password. The steps includes: (1) get to the login prompt, (2) enter the username, (3) enter the password, (4) tap the log in button, and (5) verify that an element with the correct logged-in text is present.

So far, so good! Now let’s take a look at the same test, but written for the Espresso driver:

@Test
public void testLogin_Espresso() throws MalformedURLException {
    AndroidDriver driver = getDriver(“Espresso“);
    WebDriverWait wait = new WebDriverWait(driver, 10);
    ExpectedCondition loginScreenReady =
    ExpectedConditions.presenceOfElementLocated(loginScreen);
 
    try {
        wait.until(loginScreenReady).click();
        driver.findElement(username).sendKeys(“sanoj”);
        driver.findElement(password).sendKeys(“mypassword”);
        driver.findElement(loginBtn).click();
        driver.findElement(verificationTextEspresso);
    } finally {
        driver.quit();
    }
}

Can you spot the differences? There are just two:

1. We only need 1 explicit wait instead of 3.

2. We have a different verification element we’re looking for in the last step.

     Otherwise, the test code is exactly the same! This is great, because it means that, for the most part, changes were not required to migrate this particular test to the Espresso driver. Now, why do we only need 1 explicit wait instead of 3 as before? We needed them in the UiAutomator2 example because any time we try to find an element after a view transition, we have no guarantees about the timing of when the new view will show up, and we have to hedge our bets with an explicit wait. One of the benefits of Espresso, however, is synchronization, which as I explained before means that Espresso itself will hold off on finding any elements until it believes the app is in an idle state. What this means is that, for the most part, we don’t need to worry about waits in Espresso! (We do still need the first wait because synchronization is not in effect until the app itself is fully loaded and instrumented by Espresso, and Appium doesn’t know exactly when that happens).

Try to use the Espresso in your Android Automation and enjoy.

make it perfect !

Reference: Appium Pro.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s