Home > Blog, Code > Make Android play nice with Selenium Grid on a remote Jenkins server

Make Android play nice with Selenium Grid on a remote Jenkins server

September 3rd, 2013

I spent quite a large amount of time figuring out how to make a Jenkins server kick off a job to run some integration tests on a remotely connected Android device. A LARGE amount. So much time, in fact, I wished someone had written an article such as the one you see below. Connectivity from the server to the remote device connected to a host computer was my largest time sink by far, so I hope to minimize that for you.

There are some pieces of this puzzle I won’t get into, as lots of information already exists about them. They require some basic knowledge I’m going to assume you possess or that you have ready access to tutorials. The information I’m glancing over includes the following points:

  • How to setup a server with Jenkins
  • How to instantiate a new Android Emulator
  • How to install the Homebrew package manager
  • A bit of Java as well as JavaScript experience – not much needed here, but it certainly helps
  • Basic understanding of what JSON is/is capable of doing; how to write/edit a JSON file
  • Basic understanding of networking ports

I’m running on OSX, but you can probably do all of the following with Cygwin. Also, please understand this isn’t a fully-developed solution, but it will give you a jump start. Here is your software grocery list:

  1. Jenkins server + Selenium Plugin (available via automated download/install within the Jenkins Server configuration)
  2. Eclipse/Android Development Toolkit
  3. Android Emulator (New info: please use something like Genymotion! This makes testing much easier/faster.)
  4. FlynnID
  5. Android Server APK 2.21
  6. Socat (install this with Homebrew package manager): $ brew install socat

You might notice that v.2.21 of the Android Server APK is outdated, but at the time of writing, the current version is 2.32, and will not communicate with Selenium Grid 2 without significant workarounds. It’s just easier not to fight it if all you want is to setup the server and your device.

Here are the steps I follow to connect to the Grid:

      1. Setup your Jenkins server and install the Selenium RC plugin from the installation page within Configuration. It will act as your hub.
      2. Start your Android emulator on the host machine. You need to know how to refer to your Android emulator, so run $ ./adb devices, which will output something like the following:
        List of devices attached 
        emulator-5554	device

        In this example, “emulator-5554″ is the (serialId) info we’ll use in our next few commands.

      3. Install the Android-server.apk on the emulator if it isn’t already (NOTE: you only need to do this once. After it’s installed, it stays installed unless you tell it otherwise):
        $ ./adb -s (serialId) -e install -r android-server.apk
      4. Now run the newly installed server app, either via the UI or the following command:
        $ ./adb -s (serialId) shell am start -a android.intent.action.MAIN 
        -n org.openqa.selenium.android.app/.MainActivity
      5. Use adb to forward the host’s TCP port 8080 to the Android emulator’s TCP port 8080. This port is automatically used by the Android server app:
        $ ./adb -s (serialId) forward tcp:8080, tcp:8080
      6. Use socat to fork the host’s externally-facing TCP port 8081 to the internal TCP port 8080. This reroutes all traffic coming in over port 8081 to the already forwarded internal port (via adb):
        $ sudo socat TCP-LISTEN:8081,fork TCP:localhost:8080
      7. Time to exercise our JSON muscle, and create a configuration file. If you haven’t done so already, you need to install FlynnID. It’s easy to connect multiple Android devices to the Grid using FlynnID’s ability to process one of these files. It’s a payload of info transmitted to the grid. I’ve got an example below to get you started. Create this file in the same directory from where you’ll be calling FlynnID (just to keep the command nice and simple):
        // flynnconfig.json example:
        {
            "hub": {
                "host": "gridServerIP", // Be sure to replace this with an 
                "port": 4444            // actual IP address or DNS entry
            },                          // Leave the quotes!
            "nodes": [{
                "host": "androidHostMachineIP", // Replace this as well
                "port": 8081,                   // Leave the quotes!
                "browser": {
                    "name": "android",
                    "version": "4"
                },
                "platform": "ANDROID" 
            }]
        } // Check Dave Hunt's site linked above for more info
      8. Invoke FlynnID, passing it the config file you created above (Python must be installed for FlynnID to function):
        $ flynnid flynnConfig.json

If all went well, your host machine contacted the Selenium Grid and registered “itself” (meaning it told the Grid where to point when an Android device is requested by your testing process). You can now direct your browser to http://(yourIPAddress):8081/wd/hub/static/resource/hub.html to check that the server is running and is externally available. You can programmatically open a new session (using any supported language), or do so manually on the page which appeared. It should look like this:

AndroidSession

 

 

 

The page shown above can actually be checked as soon as you’ve completed step 5 above, using http://localhost:8080/wd/hub/static/resource/hub.html if the need to confirm functionality arises.

That’s that. All that’s left is to setup a Jenkins job to call on the Android device to run some tests you’ve probably already written.

It might be worth your while to note that, unfortunately, with so many components (port forwarding, emulators, possibly external devices, etc.) there are many points of possible failure. It may take a bit of time sussing out your own particular set of details before this all comes together, but this setup works for me. If you do choose to use a physical Android device, ensure it’s on the same network as your Grid server and not just connected to 3G/4G. Don’t ask me how I know this! ;)

Good luck!

Special thanks to the Google Code folks who made this Android Selenium page: https://code.google.com/p/selenium/wiki/AndroidDriver

And to Dave Hunt for creating FlynnID: http://blargon7.com/

Categories: Blog, Code Tags: , , , , ,
Comments are closed.