Guide for continuous deployment of Android builds with appium, saucelabs, jenkins and javascript

Satyajit Malugu
mobile-testing
Published in
3 min readAug 2, 2015

Running appium mobile UI tests as part of your build pipeline has always been a pipe dream of mine.. until this week. With the help of almighty google, my android dev and sauce labs dev, we were not only able to achieve this workflow but suprass with continuous deployment of alpha apks’ to play store.

  1. Code pushed to master in Android repo
  2. Gradle build kicked off through github webhook
  3. Unit tests ran on emulators on Jenkins box and coverage reports run through gradle tasks.
  4. Apk generated for different environments — TEST, DEV, PROD
  5. Appium tests kicked off with the latest APK on saucelabs
  6. Results updated on sauce cloud and embedded inside the Jenkins job.
  7. Finally kick off the alpha build in google play store

To achieve this we need customizations in all components — Jenkins, Gradle, Appium sciripts, Google play store. Lets examine these at a high level

Jenkins

We are using an open stack instance of Jenkins on centos 7, where we have complete access to the box. Not only we can install plugins at will, we can ssh into the box for digging deep.

The plugins we installed for this setup

  1. Gradle — this is useful for building, spinning up emulators and running unit tests on emulators
  2. Saucelabs — This allows us to create tunnels to access internal networks, setup environment variables, setup cloud emulators and most importantly view the test results from inside Jenkins job, instead of going to saucelabs.com
  3. Multiple SCM — Our Android code and test automation code live in seperate repos but Jenkins default setup don’t play well with seperate repos, it clears of the workspaces for each git download. This plugin solves a major limitation of Jenkins workspace by allowing us download 2 repos and to a specific path in workspace.

The way we tied the workflow is through 3 execute shell commands

  1. First execute shell triggers android builds. This generate the apk
  2. Second execute shell is a simple curl request to upload the apk to saucelabs.
  3. Third is the trigger for appium tests. biggest gotcha here is they have 2 env variables with very similar names SAUCE_USER_NAME and SAUCE_USERNAME, SAUCE_ACCESS_KEY and SAUCE_API_KEY and you need set both hence my trigger command looks ugly like this
  • SAUCE_USERNAME=$SAUCE_USER_NAME SAUCE_ACCESS_KEY=$SAUCE_API_KEY JENKINS=1 mocha

Appium scripts

I started with appium’s sample code and didn’t make too many changes. Majority of my customizations are to add a switch for Jenkins. In addition to SAUCE env variable, I also added a JENKINS env variable, this enabled me to add a build number to the Apk file

if (process.env.SAUCE) {
desired.app = require("./helpers/apps").sauceUploadedApk;
}
else if (process.env.JENKINS) {
desired.app = 'sauce-storage:investor-' + process.env.BUILD_NUMBER +'.apk'
}

In the capabilities hash, instead of hardcoding the platformname, version etc in the caps hash, I get them through the env variables that are setup by sauce labs plugin

exports.jenkins = {
platformName: process.env.SELENIUM_DEVICE || 'Android',
'appium-version': '1.4.7',
platformVersion: process.env.SELENIUM_VERSION || '5.1',
deviceName: process.env.SELENIUM_DEVICE || 'Android Emulator',
orientation: process.env.SELENIUM_ORIENTATION || 'portrait'
};

And finally we generate the xml test reports and output the session id and job name in console for these to be picked up by saucelabs plugin and show in job results.

console.log("SauceOnDemandSessionID="+ driver.sessionID + " job-name=" + this.currentTest.title);

Gradle

My Android dev already did a lot of setup where in once the build is triggered, it will run the unit tests, generate apk in all environments with and without signed versions.

Google play store integration

With all the above we still only have continuous integration not continuous deployment. Granted we don’t want to deploy to customers everytime there is a code push to master/alpha but we want our alpha testers to receive those builds. This is where staged rollouts to alpha comes in very handy. After this step, we achieve nirvana — where a code push will trigger unit tests, UI tests and goes all the way to alpha testers

Stretch goals

  1. Run appium tests on multiple emulators
  2. Run appium tests in parallel making use of concurrent VM’s.
  3. Do a similar setup for iOS
  4. Make the execute shells conditionals, so that a failure in step blocks the rest of the pipeline.

--

--