Front-End Web & Mobile

Test iOS apps on AWS Device Farm using Appium – Part 1: Prerequisities, Environment Set Up, and Test Creation

With AWS Device Farm, you can quickly get started testing your Android, iOS, and FireOS apps on real devices in the AWS cloud. Simply upload your app, choose your test framework and the devices you want to test your app on, and start your test run. AWS Device Farm will provide the results of your tests including pass / fail status, logs, performance metrics, and screenshots.

The objective of this three-part series is to walk through step-by-step how to get started testing an iOS app with AWS Device Farm. The test automation framework we will be using is Appium and we will write our test cases using the TestNG framework. We will not be building an iOS app as part of this walkthrough. However, to follow along with this post, a sample iOS app is available for download here.

At the end of this series, you will have the knowledge required to test an iOS app with AWS Device using Appium and TestNG.

Prerequisites

For this example, the tools and versions listed below were used. It is assumed you have these tools installed on your machine beforehand and that you have an AWS Account.

  • Java 8
  • Eclipse IDE Mars was used for this tutorial.
  • m2e Maven Integration for Eclipse
  • Xcode 7.0 We will use a sample, unsigned iOS app called “ToDoList.ipa” that you can download here.
  • Appium 1.4.8 If you have not worked with Appium before, please review the Appium documentation before moving ahead.  We will be using the Appium GUI for this tutorial.  Please install the latest version of the Appium GUI.
  • Apache Maven 3.3.3 Or the latest version of Maven
  • AWS Account and IAM User creation Follow steps under the Setting Up section of the AWS Device Farm documentation.

A preamble on Appium

Appium is a test automation framework that executes your test suite across both iOS and Android apps without you having to further modify your app or create separate test suites for the same app. Appium is able to provide this capability by utilizing Selenium WebDriver, which follows a client-server protocol. Appium uses Selenium WebDriver to be able to receive commands from a client running your tests and respond to those commands with a response over HTTP. This follows a request / response paradigm in which requests are the commands being sent to the Appium server and responses are being received by the client via WebDriver.

Appium executes your tests as described below:

  1. Tests for an iOS or Android app are written in a WebDriver-supported programming language. Appium provides client-side libraries for many languages.
  2. An Appium server is launched after installation and configuration on the test machine.
  3. The tests are initiated on a client machine.
  4. Appium will begin receiving commands from the client (the machine running your tests) and execute those commands (your test emulating user actions with your app) on an emulator or real device.

Now that we have walked through the prerequisites and an overview of Appium, let’s get started building out our test cases for the sample iOS app you have downloaded.

Create a Java project in Eclipse

Launch Eclipse and create a new Java project to begin writing your test cases by selecting File -> New -> Java Project.

Create two source folders: src/main/java and src/test/java. Within each source folder, create a package in which you will eventually create your TestNG test class. Your project structure should look similar to the below.

Configure the build path for each source folder by right clicking the source folder and selecting ‘Configure Build Path.’ Ensure you have selected the Java Build Path option from the left hand menu and you are on the Source tab. Check the ‘Allow output folders for source folders’ option.

  1. For src/main/java -> the output folder is target/classes.
  2. For src/test/java -> the output folder is target/test-classes.

The build paths for your source folders should look similar to the folders in the image below.

Add external libraries for Selenium WebDriver, TestNG, and Appium Java Client

Selenium

Download the Selenium Client & WebDriver Language Bindings for the language of your choice. For this tutorial, we will be using Java.  Downloads are available at: http://docs.seleniumhq.org/download/.

  1. Once you have saved and unzipped the Selenium dependencies to your machine, right-click the Java project created in Step 1 and go to Properties.
  2. Select Java Build Path in the left-hand menu and ensure you are on the Libraries tab. Select ‘Add External JARS’ and navigate to the location of your Selenium jar files.
  3. Select the 2 Selenium jar files and the jar files in the folder ‘libs’ and click ‘Apply.’

TestNG

To install TestNG in Eclipse, go to Help -> Eclipse Marketplace -> Search for TestNG and Install.

Once you have installed TestNG in Eclipse, proceed below:

  1. Right click on the project created in Step 1 and go to Properties.
  2. Select Java Build Path in the left-hand menu and ensure you are on the Libraries tab. Select the ‘Add Library’ button on the right.
  3. Select TestNG -> Next -> Finish.
  4. Select ‘Apply’ and then click OK.

Appium client for Java

Download the Appium client library for Java and add the jar file to the project you created in Step 1. Follow steps as performed when adding the Selenium jar files.

Once all referenced libraries have been added to your Java project, your project structure should look similar to the image below.

Create the TestNG test suite

Create a Java class called “SampleAppiumTestNGTest” under src/test/java for creating your TestNG test code. Paste the below sample TestNG code:

package com.aws.devicefarm.example.appiumiostest;

import org.testng.annotations.Test;
import java.io.File;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

public class SampleAppiumTestNGTest 
{
	private static RemoteWebDriver driver = null;
	
	public boolean takeScreenshot(final String name) {
		String screenshotDirectory = System.getProperty("appium.screenshots.dir", System.getProperty("java.io.tmpdir", ""));
		File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE)
		return screenshot.renameTo(new File(screenshotDirectory, String.format("%s.png", name)));
	}
  
	
	@BeforeMethod
	public void setUp() throws Exception {
		DesiredCapabilities capabilities = new DesiredCapabilities();
       		URL url = new URL("http://localhost:4723/wd/hub");
        	driver = new RemoteWebDriver(url, capabilities);
	}
	
	
	@Test
	public void test01() throws InterruptedException {
		driver.findElement(By.name("Add")).click();
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATextField[1]")).sendKeys("Complete Taxes");
		driver.findElement(By.name("Save")).click();
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[4]")).click();
		String screenshot1 = null;
		takeScreenshot(screenshot1);
	}
	
	
	@Test
	public void test02() throws InterruptedException {
		driver.findElement(By.name("Add")).click();
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATextField[1]")).sendKeys("Book tickets for vacation");
		driver.findElement(By.name("Save")).click();
		String screenshot2 = null;
		takeScreenshot(screenshot2);
	}
	

	@Test
	public void test03() throws InterruptedException {
		driver.findElement(By.name("Add")).click();
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIANavigationBar[1]/UIAButton[1]")).click();
	}
	

	@Test
	public void test04() throws InterruptedException {
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[1]")).click();
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[1]")).click();
		driver.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[1]")).click();
	}

	
	@AfterMethod
	public static void tearDownClass() {
        		if (driver != null) {
            		driver.quit();
        		}
    	}
}

To capture the user interface elements and interactions in the TestNG test suite, Appium Inspector was used. To do this yourself, you can launch the Appium GUI and select the iOS Settings.

  1. For the App Path, navigate to the location of your .app file.
  2. Ensure you check the Force Device option and choose a device.
  3. Ensure a Platform Version is selected.
  4. Click the Launch button.
  5. Click the icon with the magnifying glass to launch the Appium Inspector.
  6. Begin recording your tests.

NOTE:  Appium versions 1.4.11 and later support Xcode 7 with iOS 9 simulators. To use the Appium Inspector for capturing elements in this case, you will need to point the Appium client GUI to the latest Appium version. To do this:

  1. Clone the Appium git to your local git clone (https://github.com/appium/appium.git)
  2. Once the download is complete, Run reset.sh
  3. Open the Appium client (GUI)
  4. Select “Developer settings” and enable it
  5. Select Use External NodeJS Binary to “Your local node bin folder path”
  6. Select Use External Appium Package to “Your Appium Local clone folder path”
  7. Launch the Appium Server

Summary

You should now have your environment set up, a sample iOS app that you downloaded, and an Eclipse project with your TestNG tests.  With this you can run your test suite locally with Appium and validate your tests. Join us in Part 2 where we will walk through how to prepare your TestNG test suite for uploading to AWS Device Farm. Finally, in Part 3 we will run the tests we’ve created in the AWS Cloud with AWS Device Farm. We are always interested in your feedback, comments, and questions so please reach out to us in the comments section below or in our developer forum.