This project demonstrates a Page Object Model (POM) structure with Robot Framework and Appium for testing the openly available Android ApiDemos app.
resources/common/— App-level keywords and capabilitiesresources/pages/— Page Object keywords for screensresources/procedures/— High-level flows combining pagestests/— Smoke and functional test suitesapps/— Place theApiDemos-debug.apkhere
- Python 3.10+ and pip
- Node.js 18+ (for Appium)
- Java JDK 11+
- Android SDK + Platform Tools (ADB)
- ANDROID_HOME and JAVA_HOME environment variables configured
npm install -g appium
appium driver install uiautomator2Start Appium server:
./scripts/start-appium.ps1Download the ApiDemos APK from the Appium GitHub releases and place it in apps/:
- https://github.com/appium/android-apidemos/releases (use
ApiDemos-debug.apk)
Resulting path should be apps/ApiDemos-debug.apk.
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txtIf you installed Android Studio, the SDK is typically at %LOCALAPPDATA%\Android\Sdk. Set the required variables and ensure platform-tools is on your PATH:
./scripts/configure-android-env.ps1
adb devicesIf adb devices shows any offline emulators, stabilize ADB to avoid Appium proxy errors:
./scripts/adb-stabilize.ps1If no devices appear, start an emulator from Android Studio or connect a real device (USB debugging enabled).
- Emulator: create an Android Virtual Device (AVD) in Android Studio and start it.
- Real device: enable USB debugging and ensure
adb devicesshows your device.
In one terminal, keep Appium running. In another, run Robot:
robot -d reports testsCommon targeted runs:
robot -d reports tests\smoke\test_navigation.robot
robot -d reports tests\functional\test_controls.robotTarget a specific real device when multiple devices are present:
# Replace R58M510SP7A with your device's UDID
robot --variable UDID:R58M510SP7A -d reports tests\smoke\test_navigation.robotScripted runs with optional UDID:
# Start Appium (keep this terminal open, it restarts ADB and frees port 4723)
./scripts/start-appium.ps1
# Smoke tests
# Replace R58M510SP7A with your device's UDID
robot --variable UDID:R58M510SP7A -d reports tests\smoke\test_navigation.robot
# Or via script with UDID param
./scripts/run-smoke.ps1 -Udid R58M510SP7A
# Functional tests
robot -d reports tests\functional\test_controls.robot
# Or via script with UDID param
./scripts/run-functional.ps1 -Udid R58M510SP7AIf you see "Second signal will force exit" or Appium logs "socket hang up", keep Appium in its own terminal and avoid interrupts while tests run. Use ./scripts/adb-stabilize.ps1 to kill offline emulators and restart ADB.
- For Appium v2, the default base path is
/. The project useshttp://127.0.0.1:4723inresources/common/app.robot. - If using a real device, you may need to add
udid=<device_udid>toOpen Applicationcapabilities inapp.robot.
- "socket hang up" or screenshot warnings: keep Appium in its own terminal and start it via
./scripts/start-appium.ps1(it restarts ADB and frees port 4723). Ifadb devicesshowsofflineorunauthorized, run./scripts/adb-stabilize.ps1and accept the RSA prompt on the device. - Avoid opening multiple Appium sessions per test. Use either
Suite SetuporTest Setupto open the app, not both. - If navigation clicks intermittently fail, increase waits or use
Wait Until Element Is VisiblebeforeClick Element. Default waits are set inOpen App. - When multiple devices are connected, pass
--variable UDID:<device_udid>torobotor use-Udidwith the helper scripts.