{"id":24503685,"url":"https://github.com/dzooli/appium-testing","last_synced_at":"2026-05-17T02:08:44.458Z","repository":{"id":185625640,"uuid":"672710168","full_name":"dzooli/appium-testing","owner":"dzooli","description":"POC for emulated Android usage for testing.","archived":false,"fork":false,"pushed_at":"2024-11-21T01:08:40.000Z","size":6213,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-21T23:17:57.245Z","etag":null,"topics":["android","emulator","mobile","python","test-automation","testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dzooli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-31T01:39:45.000Z","updated_at":"2024-09-07T13:54:35.000Z","dependencies_parsed_at":"2024-03-16T18:01:11.828Z","dependency_job_id":"09c589a5-45b8-4ec2-9bc8-742985268b6a","html_url":"https://github.com/dzooli/appium-testing","commit_stats":null,"previous_names":["dzooli/appium-testing"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzooli%2Fappium-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzooli%2Fappium-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzooli%2Fappium-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dzooli%2Fappium-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dzooli","download_url":"https://codeload.github.com/dzooli/appium-testing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243703986,"owners_count":20334087,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","emulator","mobile","python","test-automation","testing"],"created_at":"2025-01-21T23:18:11.841Z","updated_at":"2026-05-17T02:08:44.388Z","avatar_url":"https://github.com/dzooli.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Motivation\n\nI'd like to eliminate external dependencies for running Android test suites or use Android cloud testing\nservices just for some tools like \"Duo Mobile\" to test MFA authentication. Externally managed services \nare hard to maintain and could be expensive.\n\nSecondary goal is to use only CLI tools and run the test in a CI pipeline.\n\n# Idea\n\nUsing an **emulated Android** device for the required tasks.\n\n## Requirements\n\nThis process has been tested on Windows 10, for Linux we need to investigate the possibilities later.\n\n- JDK\n- NodeJs\n- Android cmdline tools\n- Android SDK (partially)\n- Android emulator\n- a running Android Virtual Device\n- Appium\n- Appium-Inspector (optional, from [this GitHub repo](https://github.com/appium/appium-inspector/releases))\n- Test framework\n  - unittest\n  - appium-python-client\n\n## Setup\n\n### Android Emulator\n\n#### Android SDK\n\n```shell\n# Download JDK\ncurl --output jdk-20.exe https://download.oracle.com/java/20/latest/jdk-20_windows-x64_bin.exe\n\n# Install JDK before continue\n# and set JAVA_HOME\nexport JAVA_HOME=/d/programs/Java/jdk-20  # example path, use your own\n\n# Install Android SDK\nmkdir -p install/asdk\ncd install/asdk\ncurl --output asdk-cmdline.zip https://dl.google.com/android/repository/commandlinetools-win-9477386_latest.zip\nunzip asdk-cmdline.zip\n\n# Move the tools to its standard directory\nmv cmdline-tools latest\nmkdir cmdline-tools\nmv latest cmdline-tools\n```\n\n#### Android SDK packages\n\n```shell\nexport ANDROID_HOME=$(pwd)\nexport ANDROID_SDK_ROOT=$ANDROID_HOME\n./cmdline-tools/latest/bin/sdkmanager.bat --licenses\n./cmdline-tools/latest/bin/sdkmanager.bat \"system-images;android-30;google_apis;x86_64\" \"platforms;android-30\" \"emulator\" \"platform-tools\" \"build-tools;33.0.2\"\n```\n\n#### AVD (Android Virtual Device) creation\n\nWe are going to use Android v11 since this version is the most popular nowadays.\n\n```shell\n./cmdline-tools/latest/bin/avdmanager.bat create avd -k \"system-images;android-30;google_apis;x86_64\" --name Android4Testing_001 -c 512M -d pixel_xl\n# verify\n./cmdline-tools/latest/bin/avdmanager.bat list avd\n```\n\n#### Start the emulator\n\n```shell\n./emulator/emulator.exe -avd Android4Testing_001 -detect-image-hang\n```\n\n#### Install your \"App under test\"\n\nThis is an optional step since Appium is able to install APKs for you programmatically.\n\nUse another terminal because the emulator is running.\n\n```shell\n./platform-tools/adb.exe install -g -r \u003cMyApp.apk\u003e\n```\n\n### Appium Server\n\n#### Install\n\n```shell\ncd ..\nmkdir src\ncd src\nnpm init\nnpm install appium\n# Drivers and plugins\nnpx appium driver install uiautomator2\nnpx appium plugin install execute-driver\nnpx appium plugin install --source=npm appium-device-farm\nnpx appium plugin install --source=npm appium-dashboard\n```\n\n#### Configure\n\nThe configuration below is suitable for well protected servers since some insecure features are enabled.\n\nCreate your Appium server configuration file ```appium-server-config.json``` like this:\n\n```json\n{\n  \"server\": {\n    \"address\": \"127.0.0.1\",\n    \"keep-alive-timeout\": 800,\n    \"base-path\": \"/wd/hub\",\n    \"allow-insecure\": [\n      \"adb_shell\",\n      \"execute_driver_script\"\n    ],\n    \"use-plugins\": [\n      \"appium-dashboard\",\n      \"device-farm\",\n      \"execute-driver\"\n    ],\n    \"plugin\": {\n      \"device-farm\": {\n        \"platform\": \"android\",\n        \"skipChromeDownload\": true,\n        \"androidDeviceType\": \"simulated\",\n        \"iosDeviceType\": \"simulated\",\n        \"maxSessions\": 3\n      }\n    }\n  }\n}\n```\n\n_More configuration options available from the Appium documentation._\n\n#### Start the server\n\n```shell\n# Use your own sdk root !!!\nnpx appium server --config appium-server-config.json\n```\n\nIf everything is fine at this point you can access **your Appium and the detected emulated device** on [http://localhost:4723/device-farm/](http://localhost:4723/device-farm/)\n\n## Start testing\n\n### Requirements\n\nUse a new terminal since the Appium server is running on the last used.\n\n- Create and activate a Python virtualenv\n- Install ```appium-python-client``` with pip\n\n### Write tests\n\n#### Example test\n\n```python\nimport unittest\nfrom appium.webdriver import webdriver\n\n\ndriver: webdriver.Remote = None\n\n\nclass TestAnAppWithAppium(unittest.TestCase):\n    def setUp(self) -\u003e None:\n        global driver\n        self.apkPath = \"YOUR_PATH_TO_APK\"\n        self.appPackage = \"com.yourdomain.yourpackage\"\n        caps = {\n            \"platformName\": \"Android\",\n            \"appium:automationName\": \"UiAutomator2\",\n            \"appium:app\": str(self.apkPath),\n            \"appium:ensureWebviewsHavePages\": True,\n            \"appium:nativeWebScreenshot\": True,\n            \"appium:newCommandTimeout\": 3600,\n            \"appium:connectHardwareKeyboard\": True,\n            \"appium:noReset\": True\n        }\n        driver = webdriver.Remote(\"http://127.0.0.1:4723/wd/hub\", caps)\n        driver.execute_script(\"mobile: shell\", {\n            \"command\": \"pm\",\n            \"args\": [\"grant\", self.appPackage, \"android.permission.CAMERA\"]  # Example programmatic permission grant\n        })\n        if driver.is_app_installed(self.appPackage):\n            driver.activate_app(self.appPackage)\n        else:\n            self.fail(\"App is not installed!\")\n\n    def tearDown(self) -\u003e None:\n        driver.quit()\n\n    def test_one_function(self):\n        driver.find_element(value=\"aButton\")  # Default: Find by ID\n\n\nif __name__ == '__main__':\n    try:\n        unittest.main()\n    except:\n        driver.quit()\n```\n\n### Run tests\n\n```shell\npython -m unittest\n```\n\n## Epilog\n\n### Conclusions\n\nThe concept is working, by using emulated mobile devices external mobile testing service is no longer\nneeded. The setup is relative easy and could run in a CI pipeline with little modifications\n(like ```sdkmanager --licenses``` automatic acceptance).\n\nThe solution is suitable when no mass of automated mobile testing is necessary and scalable by\nconnecting more emulated devices to an Appium server and connecting multiple Appium servers to a\nSelenium Grid.\n\n### Useful tricks\n\n#### Grant App permissions\n\nFrom the host:\n```shell\ncd $ANDROID_SDK_ROOT\n./platform-tools/adb.exe shell pm grant \"com.your.package\" android.permission.your_permission\n```\n\nFrom the test _(needs execute-script plugin for Appium)_:\n\n```python\ndriver.execute_script(\"mobile: shell\", {\n    \"command\": \"pm\",\n    \"args\": [\"grant\", self.app_package, \"android.permission.CAMERA\"]\n})\n\n```\n\n#### Activity and package info\n\nList 3rd-party packages:\n```shell\ncd $ANDROID_SDK_ROOT\n./platform-tools/adb.exe shell pm list packages -3\n```\n\nGet the launchable activities:\n```shell\ncd $ANDROID_SDK_ROOT\n./build-tools/33.0.2/aapt d --values badging \u003cpath-to-apk-name\u003e\n```\n\nDump running activities:\n```shell\ncd $ANDROID_SDK_ROOT\n./platform-tools/adb.exe shell dumpsys window windows | grep Activity\n```\n\n#### Appium selectors (By.*)\n\n- XPATH\n- ID\n- CLASS_NAME\n- ACCESSIBILITY_ID\n- CSS_SELECTOR\n- ANDROID_UIAUTOMATOR\n\n### Further readings\n\n- [Android in Docker](https://github.com/budtmo/docker-android)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdzooli%2Fappium-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdzooli%2Fappium-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdzooli%2Fappium-testing/lists"}