Skip to content

BrianGator/Appium-Mobile-Automation-Java-Guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

84 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Appium Mobile Automation with Java

A practical mobile automation project using Appium, Java, Selenium WebDriver, TestNG, and Maven. This repository demonstrates Android mobile automation, parallel mobile execution, Appium server/session configuration, Android emulators, UiAutomator2 capabilities, Appium locators, scrolling, native app activation, TestNG lifecycle annotations, Maven dependency management, and mobile test framework design concepts.

Written by Brian McCarthy


Table of Contents


Project Overview

This project is a Java-based Appium mobile automation repository focused on Android automation and parallel execution. It includes examples that run multiple Android sessions in two different ways:

  1. Separate Appium server instances for separate devices

    • Test1 connects to Appium server port 10000 and uses emulator emulator-5554.
    • Test2 connects to Appium server port 10001 and uses emulator emulator-5556.
  2. Single Appium server instance with different systemPort values

    • Test3 connects to one Appium server on port 4723, uses emulator emulator-5554, and sets systemPort to 8231.
    • Test4 connects to one Appium server on port 4723, uses emulator emulator-5556, and sets systemPort to 8230.

The project demonstrates how a mobile automation engineer can configure Android devices/emulators, start Appium sessions, activate native apps, locate mobile elements, automate scrolling, handle parallel sessions, and clean up drivers after execution.


Languages Used

Language Purpose
Java Main automation language for Appium test classes, driver setup, TestNG lifecycle methods, and mobile actions
XML Maven pom.xml dependency management and TestNG testng.xml suite configuration
Gherkin / Cucumber Concepts Cucumber dependencies are included for behavior-driven test framework expansion
JSON JSON libraries are included for future data handling, API payloads, or test data parsing
Shell / Command Line Used to start Appium servers, emulators, Maven tests, and Android tooling

Technologies and Frameworks Used

Technology / Framework Purpose
Appium Java Client Mobile automation client library for Android/iOS automation
Appium Server Receives WebDriver commands and executes them on mobile devices/emulators
AndroidDriver Appium driver used for Android app automation
UiAutomator2 Android automation engine used by Appium for modern Android testing
Selenium Java WebDriver foundation used by Appium Java Client
TestNG Test runner, setup/teardown lifecycle, and parallel suite execution
Maven Dependency management and test execution
Cucumber Java / Cucumber TestNG / Cucumber JUnit BDD framework dependencies included for future feature-file based automation
Extent Reports Cucumber Adapter Reporting dependency for Cucumber-based report generation
Log4j Logging framework dependency
Apache POI Excel/data-driven framework support dependency
JSON / json-simple JSON test data or payload handling support
Android Emulator Android virtual devices used as test execution targets
Appium Inspector Recommended locator inspection tool for mobile apps

Methodologies Used

1. Native Android Mobile Automation

The tests automate native Android apps by creating AndroidDriver sessions and interacting with Android UI elements through Appium locators.

2. TestNG Lifecycle Management

Each test class uses TestNG annotations:

  • @BeforeTest for driver setup
  • @Test for executable mobile test steps
  • @AfterTest for driver cleanup

3. Parallel Mobile Testing

The project demonstrates two parallel execution patterns:

  • Multiple Appium servers with separate ports
  • One Appium server with separate Android systemPort values

4. Capability-Driven Appium Sessions

Each session is configured through UiAutomator2Options, including platform name, automation engine, target emulator UDID, and optional system port.

5. Appium Locator Strategy

The project uses Appium locator methods such as:

  • AppiumBy.id()
  • AppiumBy.accessibilityId()
  • AppiumBy.androidUIAutomator()

6. Native App Activation

The tests use driver.activateApp() to bring a target native Android app package into the foreground.

7. Mobile Scrolling

The API Demos examples use UiScrollable and UiSelector to scroll vertically and horizontally to target mobile UI text.

8. Framework Expansion Readiness

The pom.xml includes dependencies for Cucumber, Extent Reports, Log4j, JSON handling, Apache POI, Selenium, TestNG, and Appium. This supports expansion into a larger data-driven or BDD mobile automation framework.


File Structure

Appium-Mobile-Automation/
├── pom.xml                              # Maven project dependencies and Surefire configuration
├── testng.xml                           # TestNG suite running Test3 and Test4 in parallel
├── README.md                            # Project documentation
└── src/
    └── test/
        └── java/
            └── demo1/
                ├── Test1.java          # Parallel test using Appium server port 10000 and emulator-5554
                ├── Test2.java          # Parallel test using Appium server port 10001 and emulator-5556
                ├── Test3.java          # Single Appium server, emulator-5554, systemPort 8231
                └── Test4.java          # Single Appium server, emulator-5556, systemPort 8230

Project File Links

Main Files

Java Test Classes


How the Framework Works

At a high level, the framework works like this:

  1. Maven loads dependencies from pom.xml, including Appium Java Client, Selenium, TestNG, Cucumber, Extent Reports adapter, Log4j, JSON libraries, and Apache POI.
  2. TestNG reads testng.xml to determine which classes to run and how to parallelize execution.
  3. Each test class creates its own AndroidDriver in a @BeforeTest setup method.
  4. UiAutomator2Options defines the Appium session capabilities, including Android platform, UiAutomator2 automation engine, emulator UDID, and system port when needed.
  5. The test method activates a target app with driver.activateApp().
  6. Appium locators find mobile elements by accessibility ID, resource ID, or Android UiAutomator selector.
  7. The test performs mobile actions such as click, sendKeys, scroll, and tap.
  8. The teardown method quits the driver to close the Appium session and free the device/emulator.

Maven Dependency Summary

The pom.xml identifies the project as:

<groupId>com.appiumguide.demo</groupId>
<artifactId>Appium-Guide</artifactId>
<version>0.0.1-SNAPSHOT</version>

Important dependencies include:

Dependency Purpose
io.appium:java-client:10.1.1 Appium Java client for mobile automation
org.seleniumhq.selenium:selenium-java:4.43.0 Selenium WebDriver APIs used by Appium
org.testng:testng:7.10.2 Test framework and parallel execution support
io.cucumber:cucumber-java Cucumber step definition support
io.cucumber:cucumber-testng Cucumber + TestNG integration
io.cucumber:cucumber-junit Cucumber + JUnit support
tech.grasshopper:extentreports-cucumber7-adapter Cucumber Extent Reports integration
org.apache.logging.log4j:log4j-api/core Logging support
org.apache.poi:poi and poi-ooxml Excel data-driven test support
org.json:json and json-simple JSON data handling

The Maven Surefire plugin is configured for class-level parallel execution with a thread count of 5.


TestNG Suite Summary

The current testng.xml suite runs Test3 and Test4 in parallel by class:

<suite parallel="classes" name="Suite">
  <test thread-count="5" parallel="classes" name="Test">
    <classes>
      <class name="demo1.Test3"/>
      <class name="demo1.Test4"/>
    </classes>
  </test>
</suite>

This means Test3 and Test4 can run at the same time. Because both use the same Appium server URL, each class must use a different Android systemPort value to prevent UiAutomator2 session conflicts.


Core Appium Functions and Concepts

Function / Concept Purpose
UiAutomator2Options Defines Android Appium session capabilities
setPlatformName("android") Specifies Android as the target platform
setAutomationName("uiautomator2") Uses UiAutomator2 as the Android automation engine
setUdid("emulator-5554") Targets a specific emulator/device
setSystemPort(8231) Allocates a unique UiAutomator2 port for parallel sessions
new AndroidDriver(new URL(...), cap) Starts a new Android Appium session
driver.manage().timeouts().implicitlyWait() Applies implicit wait timing for element lookup
driver.activateApp(packageName) Launches or brings an installed app to the foreground
AppiumBy.id() Finds elements by Android resource ID
AppiumBy.accessibilityId() Finds elements by accessibility ID/content description
AppiumBy.androidUIAutomator() Finds elements using Android UiAutomator selector strings
UiScrollable Scrolls vertically or horizontally to find off-screen elements
sendKeys() Types text into mobile input fields
click() Taps/clicks mobile elements
driver.quit() Ends the Appium session

Code Methodology Summary

The repository uses a direct Appium + TestNG style. Each test class owns its driver setup, test flow, and teardown. This makes the examples easy to understand and useful for learning how Appium sessions work.

The most important code methodologies are:

  • Session setup per class: each test creates its own AndroidDriver.
  • Device targeting by UDID: each test targets a specific emulator using setUdid().
  • Parallel safety: parallel tests use either separate Appium server ports or separate systemPort values.
  • Native Android locators: tests use AppiumBy.id, accessibilityId, and androidUIAutomator.
  • App activation: tests launch installed apps through package names instead of installing APKs in the code.
  • Scroll automation: tests use UiScrollable for vertical and horizontal scrolling.
  • TestNG lifecycle: setup, execution, and teardown are clearly separated.

Test-by-Test Explanation with Code Samples

Test1: Parallel Android Session on Separate Appium Server Port

File: src/test/java/demo1/Test1.java

Purpose: Automates the com.fastaguser Android app on emulator emulator-5554 by connecting to a dedicated Appium server running on port 10000.

@BeforeTest
public void stepup1() throws MalformedURLException {
    UiAutomator2Options cap = new UiAutomator2Options();
    cap.setPlatformName("android");
    cap.setAutomationName("uiautomator2");
    cap.setUdid("emulator-5554");

    driver = new AndroidDriver(new URL("http://127.0.0.1:10000"), cap);
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

@Test
public void sessionidsample() throws InterruptedException {
    Thread.sleep(5000);
    driver.activateApp(app_package);
    Thread.sleep(5000);
    driver.findElement(AppiumBy.androidUIAutomator("new UiSelector().className(\"android.widget.ImageView\").instance(3)")).click();
    driver.findElement(AppiumBy.androidUIAutomator("new UiSelector().className(\"android.widget.LinearLayout\").instance(6)")).click();
    driver.findElement(AppiumBy.id("com.fastaguser:id/vehicle_id_txt")).sendKeys("1234");
    driver.findElement(AppiumBy.id("com.fastaguser:id/btn_submit")).click();
}

How it works: connects to port 10000, targets emulator-5554, activates com.fastaguser, clicks image/layout elements, enters vehicle ID 1234, and submits the form.


Test2: API Demos Scrollable Tabs on Separate Appium Server Port

File: src/test/java/demo1/Test2.java

Purpose: Automates the Android API Demos app on emulator emulator-5556 by connecting to a separate Appium server running on port 10001.

@BeforeTest
public void setup2() throws MalformedURLException {
    UiAutomator2Options cap = new UiAutomator2Options();
    cap.setPlatformName("android");
    cap.setAutomationName("uiautomator2");
    cap.setUdid("emulator-5556");

    driver = new AndroidDriver(new URL("http://127.0.0.1:10001"), cap);
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

@Test
public void test1() throws InterruptedException {
    driver.activateApp("io.appium.android.apis");
    driver.findElement(AppiumBy.accessibilityId("Views")).click();
    driver.findElement(AppiumBy.androidUIAutomator("new UiScrollable(new UiSelector().scrollable(true))" +
            ".scrollIntoView(new UiSelector().text(\"Tabs\"))"));
    driver.findElement(AppiumBy.accessibilityId("Tabs")).click();
    driver.findElement(AppiumBy.accessibilityId("5. Scrollable")).click();
    driver.findElement(AppiumBy.androidUIAutomator(
            "new UiScrollable(new UiSelector().scrollable(true)).setAsHorizontalList().setMaxSearchSwipes(10)" +
            ".scrollIntoView(new UiSelector().text(\"TAB 30\"))"));
    driver.findElement(AppiumBy.androidUIAutomator("new UiSelector().text(\"TAB 30\")")).click();
}

How it works: opens API Demos, taps Views, scrolls vertically to Tabs, opens scrollable tabs, horizontally scrolls to TAB 30, and taps it.


Test3: Parallel Android Session on One Appium Server with systemPort

File: src/test/java/demo1/Test3.java

Purpose: Automates the com.fastaguser Android app on emulator emulator-5554 through one shared Appium server at http://127.0.0.1:4723, using unique systemPort value 8231.

@BeforeTest
public void stepup1() throws MalformedURLException {
    UiAutomator2Options cap = new UiAutomator2Options();
    cap.setPlatformName("android");
    cap.setAutomationName("uiautomator2");
    cap.setUdid("emulator-5554");
    cap.setSystemPort(8231);

    driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), cap);
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

How it works: uses one Appium server and a unique UiAutomator2 systemPort to avoid conflicts during parallel Android execution.


Test4: API Demos Scrollable Tabs on One Appium Server with systemPort

File: src/test/java/demo1/Test4.java

Purpose: Automates the API Demos app on emulator emulator-5556 through the same Appium server at http://127.0.0.1:4723, using systemPort value 8230.

@BeforeTest
public void setup2() throws MalformedURLException {
    UiAutomator2Options cap = new UiAutomator2Options();
    cap.setPlatformName("android");
    cap.setAutomationName("uiautomator2");
    cap.setUdid("emulator-5556");
    cap.setSystemPort(8230);

    driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), cap);
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

How it works: uses the same Appium server as Test3, but targets a different emulator and uses a different systemPort, making parallel execution stable.


Additional Appium Java Code Examples

UiAutomator2Options options = new UiAutomator2Options();
options.setPlatformName("android");
options.setAutomationName("uiautomator2");
options.setUdid("emulator-5554");
AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), options);
driver.activateApp("io.appium.android.apis");
driver.findElement(AppiumBy.accessibilityId("Views")).click();
driver.findElement(AppiumBy.id("com.fastaguser:id/vehicle_id_txt")).sendKeys("1234");
driver.findElement(AppiumBy.androidUIAutomator(
    "new UiScrollable(new UiSelector().scrollable(true))" +
    ".scrollIntoView(new UiSelector().text(\"Tabs\"))"
));

Tutorial: Appium Mobile Automation in Java

  1. Install Java JDK and Maven.
  2. Install Node.js and npm.
  3. Install Appium: npm install -g appium.
  4. Install UiAutomator2 driver: appium driver install uiautomator2.
  5. Install Android Studio and configure Android SDK variables.
  6. Start Android emulators and verify them with adb devices.
  7. Start Appium with appium -p 4723 or run separate servers on 10000 and 10001.
  8. Run tests with mvn test or mvn test -DsuiteXmlFile=testng.xml.

Guide: Building a Scalable Appium Java Framework

Recommended future framework layers:

src/main/java/framework/
├── base/BaseTest.java
├── config/ConfigReader.java
├── drivers/DriverFactory.java
├── pages/ApiDemosHomePage.java
├── pages/FastagHomePage.java
├── utils/WaitUtils.java
├── utils/ScreenshotUtils.java
└── reporting/ExtentReportManager.java

A reusable driver factory can centralize Appium session creation:

public AndroidDriver createDriver(String udid, int systemPort) throws MalformedURLException {
    UiAutomator2Options options = new UiAutomator2Options();
    options.setPlatformName("android");
    options.setAutomationName("uiautomator2");
    options.setUdid(udid);
    options.setSystemPort(systemPort);
    return new AndroidDriver(new URL("http://127.0.0.1:4723"), options);
}

Parallel Execution Guide

Separate Appium Servers

appium -p 10000
appium -p 10001

Used by Test1.java and Test2.java.

Single Appium Server with Unique systemPort Values

appium -p 4723

Used by Test3.java and Test4.java.

Every parallel Android UiAutomator2 session needs a unique systemPort.


Best Practices and Tips

  • Prefer AppiumBy.accessibilityId() when available.
  • Use AppiumBy.id() for stable Android resource IDs.
  • Avoid brittle className().instance() locators when better IDs exist.
  • Replace Thread.sleep() with explicit waits.
  • Always call driver.quit() in teardown.
  • Keep device UDIDs and ports in config files or TestNG parameters.
  • Use unique systemPort values for parallel Android sessions.
  • Use Appium Inspector to verify locators.
  • Capture screenshots on failures.
  • Move repeated workflows into page objects.

Troubleshooting

Appium Server Not Running

Start Appium:

appium -p 4723

Emulator Not Found

adb devices

Confirm the UDID in code matches the connected emulator.

Parallel Tests Conflict

Give each Android session a unique systemPort.

App Package Not Installed

adb shell pm list packages | grep fastag
adb install path/to/app.apk

Element Not Found

Check whether the element is off-screen, inside a different app screen, or has a changed locator.


Suggested Improvements

  1. Add reusable base classes and page objects.
  2. Add explicit waits instead of Thread.sleep().
  3. Add screenshot-on-failure support.
  4. Add Log4j configuration and Extent Reports output examples.
  5. Add .apk setup instructions for tested apps.
  6. Add Cucumber feature files if BDD is intended.
  7. Add Jenkins or GitHub Actions CI instructions.
  8. Add config files for Appium server URLs, UDIDs, app packages, and ports.
  9. Add .gitignore for reports, screenshots, logs, APKs, and local device files.
  10. Add separate TestNG suites for separate-server and single-server parallel strategies.

Author

Written by Brian McCarthy

This repository demonstrates Appium mobile automation in Java with AndroidDriver, UiAutomator2Options, Appium locators, TestNG lifecycle methods, Maven dependency management, native app activation, mobile scrolling, and parallel Android execution strategies.

About

Appium-Mobile-Automation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors