Speed Up Android Appium Test Automation

android-automation

      There are three special capabilities available in Appium for speeding up Android test initialization (available in the latest Appium version). Also using the appPackage and appActivity desired capabilities instead of the app capability helps for speeding up Android test automation.

  1. skipDeviceInitialization
  2. skipServerInstallation
  3. ignoreUnimportantViews

     skipDeviceInitialization is available for all Android platforms, this desired capability can be passed with the boolean value true to skip installing the io.appium.settings app on the device. This special app is installed by the Appium Android Driver at the beginning of each test and is used to manage specific settings on the device, such as:

  • Wifi/data settings
  • Disabling animation
  • Setting a locale
  • IME settings

Without the io.appium.settings app, the Appium Android driver cannot automate these functions, but if the device previously had this app installed by Appium, it doesn’t need to install it again. If you know that your device is already in the proper state then you can set skipDeviceInitialization to true and skip the time it takes to reinstall it. Appium already checks if the settings app is already installed on the device, but with this capability enabled it even skips the check to see if the app is installed.

     skipServerInstallation desired capability only applies when using the UiAutomator2 automation method. The way the UIAutomator2 driver works, it installs a special server onto the device, which listens to test commands from Appium and executes them. By default, Appium installs this server onto the device at the beginning of every test session. If the value of skipServerInstallation is set to true, you can skip the time it takes to install this server. Of course, without the server on the device Appium can’t automate it, but if you know that the server was installed during a previous test run you can safely skip this step.

   ignoreUnimportantViews desired capability is not new, but it deserves to be mentioned as another way to potentially speed up Android automation tests, especially if your tests focus on finding many elements using XPath locators. Set this to true to speed up Appium’s ability to find elements in Android apps.

     Another major time-saver when it comes to Android tests is using the appPackage and appActivity desired capabilities instead of the app capability. We need to tell Appium which app to test. Usually we use the app capability, which can be a path to a .apk, .apks, or .zip file stored on your computer’s filesystem or stored on a public website. If the app under test is known to already be installed on the device (most likely from a previous test run), the app package name and main activity can be passed instead (using appPackage and appActivity desired capabilities). Skipping the time to download a large file or install it on the Android operating system leads to big savings.

Below is the sample code which explain how can we use it in your automation script:

DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability(“platformName”, “Android”);
caps.setCapability(“deviceName”, “Android Emulator”);
caps.setCapability(“automationName”, “UiAutomator2”);
// App is already installed on device, so can be launched by Package name and Activity
caps.setCapability(“appPackage”, “io.cloudgrey.the_app”);
caps.setCapability(“appActivity”, “io.cloudgrey.the_app.MainActivity”);
// Skip the installation of io.appium.settings app and the UIAutomator 2 server.
caps.setCapability(“skipDeviceInitialization”, true);
caps.setCapability(“skipServerInstallation”, true);
caps.setCapability(“ignoreUnimportantViews”, true);
driver = new AppiumDriver(new URL(“http://localhost:4723/wd/hub”), caps);

Try to practice the above mentioned methods in your Android Automation and feel the difference in execution speed.

Reference: Appium Pro

make it perfect !

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.