Unit 2: Appium Project

CSE379 — Mobile Automated Testing 9 min read

I. Appium Project Foundations

Appium is an open-source automation framework for testing native, hybrid, and mobile-web applications. It uses the W3C WebDriver protocol: test code sends standardized commands to an Appium server, which delegates them to a platform-specific driver such as UiAutomator2 for Android.

  • Client-server model: A Java client creates HTTP WebDriver requests; the Appium server receives them, and the installed Android driver performs actions on the device.
  • Session-based execution: Every test begins by creating a session containing configuration values such as the platform, device, application, and automation engine.
  • Platform driver: Android automation commonly uses appium-uiautomator2-driver, installed separately in Appium 2 with appium driver install uiautomator2.
  • Project dependencies: Maven resolves the Appium Java client and its transitive libraries from repositories defined by Maven, normally Maven Central.
  • Android target: Tests can run on a physical device or an Android Virtual Device (AVD); Android Debug Bridge (adb) provides device and application information.
  • W3C compliance: Standard capabilities use names such as platformName, while Appium-specific capabilities use the appium: namespace.
  • Lifecycle convention: A test creates the driver, interacts with the application, and calls quit() to close the session and release server-side resources.

II. Desired Capabilities — Session Configuration

A. What are Desired Capabilities?

Desired capabilities are key-value settings sent during session creation to describe the required automation environment and application under test.

  • Purpose: Capabilities tell the server what to launch and how to automate it; examples include platformName=Android, appium:automationName=UiAutomator2, and appium:deviceName=Pixel_7_API_34.
  • Handshake: The client sends capabilities in the W3C new session request, normally to an Appium server URL such as http://127.0.0.1:4723.
  • Standard capability: platformName is defined by WebDriver and therefore has no Appium prefix.
  • Extension capabilities:
    • appium:app: Absolute path or URL of an installable application package.
    • appium:appPackage: Android package identifier, such as com.example.notes.
    • appium:appActivity: Launchable Android activity, such as .MainActivity.
    • appium:noReset: When true, Appium avoids its usual application reset behavior.
  • Data types: Values must have correct JSON-compatible types; noReset is Boolean true, not the string "true".
  • Modern terminology: “Desired capabilities” remains common language, but W3C WebDriver represents requested capabilities through alwaysMatch and firstMatch; Appium Java code should normally use typed options classes.
  • Limitation: Capabilities are fixed when the session starts. Changing a Java options object afterward does not reconfigure an existing driver session.
JSON
{
  "platformName": "Android",
  "appium:automationName": "UiAutomator2",
  "appium:deviceName": "Pixel_7_API_34",
  "appium:appPackage": "com.example.notes",
  "appium:appActivity": ".MainActivity"
}

III. Capability Namespaces — W3C Extension Safety

A. What is a vendor prefix and why Appium is using it?

A vendor prefix is a namespace attached to a non-standard WebDriver capability so that browser or automation vendors can add features without colliding with standard capability names.

  • W3C rule: Extension capability names contain a colon; Appium uses the registered-style prefix appium:, producing names such as appium:automationName.
  • Collision prevention: platformName has one standardized meaning, while appium:appPackage clearly belongs to Appium rather than Selenium, a browser vendor, or another WebDriver implementation.
  • Protocol validation: A W3C-compliant remote end may reject an unknown, unprefixed capability. Prefixing identifies it as an intentional extension rather than a misspelled standard field.
  • Division of ownership:
    1. Standard: platformName, browserName, and acceptInsecureCerts do not receive a vendor prefix.
    2. Appium-specific: appium:deviceName, appium:udid, and appium:autoGrantPermissions require the Appium namespace in raw capability payloads.
  • Java convenience: UiAutomator2Options#setDeviceName("emulator-5554") lets the client library serialize the setting correctly; users generally do not type the prefix themselves when using a typed setter.
  • Grouped form: Appium also supports placing extension settings in an appium:options object, reducing repeated prefixes in raw JSON while preserving W3C namespacing.

IV. Maven Setup — Reproducible Java Build

A. Create a Java Project using Maven

A Maven project gives the Appium test code a standard directory layout, declarative dependencies, and repeatable compilation.

  • Prerequisites: Install a JDK, Maven, Node.js, Appium 2, Android SDK tools, and the UiAutomator2 driver; verify them with java -version, mvn -version, appium -v, and adb version.
  • Project layout: Put production helpers under src/main/java or test classes under src/test/java; Maven configuration belongs in the root pom.xml.
  • Coordinates: groupId identifies the organization, artifactId identifies the project, and version identifies the build, for example com.example, appium-demo, and 1.0-SNAPSHOT.
  • Dependency: The artifact io.appium:java-client supplies AndroidDriver, options classes, element APIs, and WebDriver protocol integration.
  • Compiler level: Declaring the Java release prevents Maven from silently compiling for an unsuitable default language level.
XML
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>appium-demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>
  <dependencies>
    <dependency>
      <groupId>io.appium</groupId>
      <artifactId>java-client</artifactId>
      <version>9.2.3</version>
    </dependency>
  </dependencies>
</project>
  • Resolution: Running mvn test downloads the declared client and compatible transitive dependencies, compiles test sources, and executes tests recognized by the configured test framework.

V. Driver Creation — Opening an Android Session

A. Start Driver Session from the Java Program

A Java program starts a session by constructing an AndroidDriver with the Appium server URL and the required capabilities.

  • Server requirement: Start Appium with appium; the default base URL in Appium 2 is http://127.0.0.1:4723/, without the older /wd/hub path unless explicitly configured.
  • Device requirement: adb devices must list the emulator or physical device as device, not offline or unauthorized.
  • Capability construction: MutableCapabilities can represent the raw W3C names and values, although platform-specific options are preferred for new code.
  • Session result: Successful construction returns a driver with a session ID and launches or activates the requested application.
  • Cleanup: quit() belongs in finally so a failed assertion or element lookup does not leave the session running.
JAVA
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.MutableCapabilities;
import java.net.URI;

public class StartSession {
    public static void main(String[] args) throws Exception {
        MutableCapabilities caps = new MutableCapabilities();
        caps.setCapability("platformName", "Android");
        caps.setCapability("appium:automationName", "UiAutomator2");
        caps.setCapability("appium:deviceName", "emulator-5554");
        caps.setCapability("appium:appPackage", "com.example.notes");
        caps.setCapability("appium:appActivity", ".MainActivity");

        AndroidDriver driver = null;
        try {
            driver = new AndroidDriver(
                URI.create("http://127.0.0.1:4723/").toURL(), caps);
            System.out.println(driver.getSessionId());
        } finally {
            if (driver != null) driver.quit();
        }
    }
}

VI. Typed Configuration — UiAutomator2 Options

A. Create Driver Session using Options Class

The UiAutomator2Options class provides Android-specific, typed methods and is clearer and less error-prone than assembling raw capability strings.

  • Type safety: Methods such as setNoReset(boolean) accept the intended Java type, reducing malformed capability values.
  • Discoverability: IDE completion exposes supported settings including setApp, setAppPackage, setAppActivity, setUdid, and setAvd.
  • Automatic namespacing: The Java client serializes Appium extension options using the required appium: prefix.
  • Driver construction: The options object implements the capabilities contract, so it can be passed directly to AndroidDriver.
JAVA
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import java.net.URI;

UiAutomator2Options options = new UiAutomator2Options()
    .setDeviceName("Pixel_7_API_34")
    .setAppPackage("com.example.notes")
    .setAppActivity(".MainActivity")
    .setNoReset(true);

AndroidDriver driver = new AndroidDriver(
    URI.create("http://127.0.0.1:4723/").toURL(), options);
try {
    System.out.println(driver.getCurrentPackage());
} finally {
    driver.quit();
}
  • Application alternative: For an APK file, use setApp("/absolute/path/notes.apk"); Appium can install it and often infer package/activity metadata.
  • Target selection: On multiple connected devices, set a unique udid; deviceName alone does not reliably select a particular Android device.

VII. Android Application Identity — Package and Activity

A. Android: How to Get appPackage and appActivity?

appPackage identifies the Android application, while appActivity identifies the activity Appium should start or wait for when opening that application.

  • Package source: With the app open, run adb shell dumpsys window and inspect the current focused application, or list installed package IDs with adb shell pm list packages.
  • Current activity: A practical command is:
BASH
adb shell dumpsys window | grep -E "mCurrentFocus|mFocusedApp"
  • Interpreting output: A component such as com.example.notes/.MainActivity splits into appPackage=com.example.notes and appActivity=.MainActivity; the leading dot means the activity name is relative to the package.
  • APK inspection: For an uninstalled APK, Android SDK Build Tools can report launch metadata:
BASH
aapt dump badging /path/to/app.apk
  • Concrete fields: Read the package: name='...' value for the package and the launchable-activity: name='...' value for the launch activity.
  • Multiple devices: Add -s emulator-5554 after adb when more than one target is connected, for example adb -s emulator-5554 shell dumpsys window.
  • Dynamic launches: Splash, login, or redirect activities may differ from the final focused activity; appWaitActivity can accept the activity Appium must wait for after launch.

VIII. Emulator Startup — Automatic AVD Launch

A. Android: Launch Emulator Automatically

Appium can start a configured Android Virtual Device automatically when a session specifies the AVD name and no matching emulator is already available.

  • AVD discovery: Run emulator -list-avds; use the exact output, such as Pixel_7_API_34, as the avd capability.
  • Required environment: The Android SDK emulator executable must be reachable through PATH, commonly from $ANDROID_HOME/emulator, and the selected AVD must already exist.
  • Options configuration: setAvd() requests startup, while timeout settings allow slower machines enough time to boot and become ready.
JAVA
UiAutomator2Options options = new UiAutomator2Options()
    .setAvd("Pixel_7_API_34")
    .setAvdLaunchTimeout(java.time.Duration.ofMinutes(3))
    .setAvdReadyTimeout(java.time.Duration.ofMinutes(3))
    .setAppPackage("com.example.notes")
    .setAppActivity(".MainActivity");

AndroidDriver driver = new AndroidDriver(
    URI.create("http://127.0.0.1:4723/").toURL(), options);
  • Launch sequence: Appium invokes the emulator, waits for Android to report boot readiness, installs required UiAutomator2 components, and then opens the application.
  • Startup arguments: avdArgs can pass emulator flags, for example -no-window in a headless environment, but graphics acceleration and CI host support must be configured separately.
  • Timeout distinction: Launch timeout covers starting the emulator process; ready timeout covers waiting for the operating system to finish booting.
  • Operational limitation: Automatic launch does not create an AVD or install its system image. Those resources must be provisioned beforehand through Android Studio or avdmanager.
  • Reliable cleanup: driver.quit() ends the Appium session but emulator shutdown behavior depends on configuration; CI pipelines should explicitly manage emulator processes when isolation is required.