Appium is an automated test harness for both Android and iOS devices. It runs as a standalone server that takes commands to run an emulator/device and execute commands for web, web app, hybrid or native applications.
The setup is rather robust, and as things change this document may fall out of sync. You can find a good resource in the following videos: Video 1 and Video 2 by “Edureka!”
Downloads for Android Testing
Go to Appium’s download section and get the Java library [link].
Go to Selenium’s download section and make sure you have the latest Java download [link].
If not yet installed, download Android Studio [link].
(OS X Users): On OS X, you’ll need to install adb, which allows for quick device inspection on the command line. The easiest way to get this (as of this writing) is to use home-brew:
brew cask install android-platform-tools
After installing adb, in a new terminal window, type: adb devices and hit RETURN. You should get a response, even if no devices appear we know that adb is working.
Setting Up an Android Project
Open Android Studio and create a new Project. Follow the defaults and give it a name, “automatedTests” etc. Whatever you want.
In the new Android Studio project, open out the app folder, so that you see the libs folder under it:

Your libs won’t yet have anything inside it. So let’s drag over the files we downloaded…
Find the downloaded Appium jar file (Java-client-*****.jar) and drag it to the libs folder in the Android Studio project’s app/libs folder (seen above).
Next, uncompress the selenium download. In the expanded files, there will be a library folder. Open it up and drag those files (byte-body-****.jar, commons-exec-****.jar and so on) over the Android Studio project’s app/libs folder.
Adding to Library
Once you have the files (the Appium file, and the Selenium Java libraries) in the app / libs folder, build the project. This is handled through the Android Studio menu: Build / Rebuild project.
(Error) In my case, I hit an error: “Cannot fit requested classes in a single dex file….” To understand this error, it is stating that too many methods are being referenced (over 65k methods)! Due to adding these libraries we breached that threshold. The solution to this is to do the following updates to the build.gradle file within the app folder:


In the above screenshots I added the following lines… in the dependancies block, I added “implementation ‘com.android.support:multidex:1.0.3” and in the defaultConfig block I added “multiDexEnabled true”. Information on what to add can be found in the Android docs for this issue [link].
Once this is done, rebuild the project (Build / Rebuild) and it should build successfully.
Adding Virtual Devices (Emulators)
Within Android Studio, click Tools > AVD Manager

That will load a window like this one:

Click “+ Create Virtual Device…”

Accept the License Agreement (above).

In the “Your Virtual Devices” (which is probably empty) go to the bottom of the window and click “+ Create Virtual Device…” (seen above).

Your screen may skip to the above image (if you have no devices). Find a device you want to add, and select it. Click NEXT to add it. This will send you to the System Image window:

We need to select an Operating System Release. In the System Image window chose an OS Version and download it (the blue hyperlinked names will auto download).

Once the system image is downloaded, select it and click NEXT. You will now be sent to the verification screen:

The above verification screen allows you to add a few more updates before finalizing (default startup orientation, etc.) When ready, click FINISH.

Your devices will now appear in the “Your Virtual Devices” Window. In the far right column “Actions” we can hit the play button to see the emulator load, we can also edit or delete the image. Note the size of each emulator… they can get pretty big.
Linking Emulators with Appium
Run Appium.
Once it loads, click to start server (using the defaults).
In the top right of the Appium application, there are 3 buttons. Click the one that has a magnifying glass (“Start Inspector Session”).

That will load this window:

We need to add desired capabilities… this lets Appium know what devices it can test with. We added those device(s) in the previous step (in Android Studio), now we need to link it to Appium.
To start with, we need to know the name of emulator. In a command prompt / terminal window, type adb devices. That will list each device with its unique identifier:
adb devices
List of devices attached
emulator-5554 device
emulator-5562 offline
Now that we know the name(s) of our device(s), we can script out an automation citing this as the device:
caps = {}
caps["deviceName"] = "emulator-5554"
caps["platformName"] = "android"
caps["browserName"] = "Chrome"
caps["chromedriverExecutable"] = "/Users/bwarner/webdrivers/chromedriver83"
# caps["appPackage"] = "com.android.examplePackage"
# caps["appActivity"] = "com.google.android.apps.example.App"
caps["noReset"] = True
If you’re automating a web browser, you can use the above syntax, and for me I had to pass in the path to the chrome driver itself.
If, however, you are automating an app, you would use the appPackage and appActivity.
Gotchas
Wow, This app is so poorly designed. Sure it does a job, but it’s rather like old school development from the 90’s where everyone’s a cowboy, writing crazy code that is incredibly brittle.
JAVA_HOME not found
Appium is sadly a poorly designed application. There are dozens of gotchas… such as the app not finding “JAVA_HOME” – of all my development I’ve never had a problem with this, to get Appium to find the JAVA install, I had to actually reinstall java and restart.
Can’t find Chromedriver
Or how about this… Appium can’t find your chrome driver. How the hell do you solve this one? If you install with the installer, you won’t see the problem under the hood. If you install via npm, you’ll get a message about Appium not having permission to create a chrome driver in:
Error installing Chromedriver: EACCES: permission denied, mkdir ‘/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/2020617-10229-1yg79iv.mfqe’
[13:41:49] Error: EACCES: permission denied, mkdir ‘/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/2020617-10229-1yg79iv.mfqe’
[13:41:49] Downloading Chromedriver can be skipped by using the ‘–chromedriver-skip-install’ flag or setting the ‘APPIUM_SKIP_CHROMEDRIVER_INSTALL’ environment variable.
My god this is bad design. Even using sudo I can’t get past this. This is a WTF moment, that came after a dozen prior.
Googling around you’ll see this is a common problem, reported to the Appium team who pretty much just shirked it:
https://github.com/appium/appium/issues/10020
Make sure your user has write permissions under /usr/local/lib. Closed as non Appium-related issue |
The above is an example of lazy development. Of course it’s an Appium problem, it’s a design flaw. Why TF are you attempting to write a chrome driver to /usr/local/lib? Come on guys, get with it. You can install the chrome driver either into a folder maintained by Appium or into the user’s folder, and cast it to the file path. This is basic programming.
The work around for THAT issue is to dick around with this crazy install syntax:
sudo npm install -g appium --unsafe-perm=true --allow-root
Check that shit out. I have to specify an unsafe operation, to work around yet another design flaw of this electron app crap. Basically, any sucker who downloads the app installer (the most common way it’s installed) will not be able to run chrome! F T S.
Although you are allowed to specify a path to your Appium chrome driver… guess what? It won’t work. no matter where you put it, you’ll get “EACCESS” errors. More WTF.
At that point, after running the unsafe permission flag, I was able to get the Appium desktop app to load without errors. But now I can’t get my scripts to pass through. THEY are now throwing the same error “can’t find chrome driver.”
After getting it to work, it began to fail for me AGAIN. I started getting “can’t find a chrome driver…” I had to actually remove Appium, close all sessions, reinstall it clean.
At the time of this writing, the latest chrome driver is at version 83. The latest chrome driver from Appium? Well it’s at 80!!! This is most likely the problem I’m having in testing modern emulation. So much for their autodownloader.
Possible solution to missing Chromedriver
After attempting the unsafe install I had this working… then it stopped working after switching to the CLI. I came across this YT video:
His solution seems legit. He runs this command to start Appium, yet another insecure call:
Appium --allow-insecure chromedriver_autodownload
However, after running it, I started getting “Appium can’t find JAVA_HOME”. OMFG. This is like software dev from the 80’s. It’s complete shit software. Appium needs to hang their head in shame. This is complete shit.
Appium CLI Can’t find JAVA_HOME
Look at the case below:
[debug] [W3C] Encountered internal error running command: Error: JAVA_HOME is not set currently. Please set JAVA_HOME.
[debug] [W3C] at getJavaHome (/usr/local/lib/node_modules/appium/node_modules/appium-adb/lib/helpers.js:141:9)
[debug] [W3C] at /usr/local/lib/node_modules/appium/node_modules/appium-adb/lib/helpers.js:125:23
[debug] [W3C] at memoized (/usr/local/lib/node_modules/appium/node_modules/lodash/lodash.js:10552:27)
[debug] [W3C] at ADB.signWithDefaultCert (/usr/local/lib/node_modules/appium/node_modules/appium-adb/lib/tools/apk-signing.js:76:22)
[debug] [W3C] Destroying socket connection
[HTTP] <-- POST /wd/hub/session 500 613 ms - 603
[HTTP]
^C[Appium] Received SIGINT - shutting down
[debug] [Appium] There are no active sessions for cleanup
C02ZF2FRLVDR:mac bwarner$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_221.jdk/Contents/Home
As you can see in my output, JAVA_HOME is defined and accessible. Out of all my apps that depend on the JDK, Appium is the only stunted application that can’t figure out where JAVA_HOME is.
So what do I do now?
Another fix for “can’t find chrome driver”
This fix was the one that finally did it for me… I found the fix from the following YT Video… but it basically amounts to specifying the chrome executable as part of the desired capabilities:
caps["chromedriverExecutable"] = "/Users/me/webdrivers/chromedriver83"
Apple Issues
On my Mac, apple will complain that chrome driver isn’t a signed dev and refused to use it… I had to do this:
xattr -d com.apple.quarantine chromedriver
No responses yet