Tips those may help your Android project from failing test on CircleCI

As you may notice, in my previous blog entry, I mentioned CircleCI, one of many continuous integration services allowing your projects be built and tested automatically on predefined environments.

In this post I will give some tips to increase the chance to run successfully and pass test on CircleCI.

Background

If you are not familiar with CircleCI, you may want to read this. There are something involved:
- CircleCI needs a file named circle.yml put in the root directory of your project, in which you write commands to be executed on CircleCI.
- In common, the process is like: CircleCI first created a virtual machine, then it pulls your code from your repository and sets up the environment, finally it runs the tests. Particularly, CircleCI starts an emulator in the virtual machine they creates (sounds VM in another VM, VM-ception), and uses the Gradle wrapper to run Gradle tasks for testing purpose.
- Remember, the emulator on CircleCI is super-weak.
- Have a quick look (or slow look if you are careful) here and here.

Here are the tips

Build your emulator

An emulator is started before test part is run, so you need to put the command to create it in that part of the circle.yml file

Disable emulator skin and audio

Do you need these features? If the answer is no, then add these options to emulator create command:
-no-audio -no-skin

Start the emulator in background and in parallel

Running the emulator from the terminal is a blocking command. We would have to wait anywhere between 2-7 minutes for the emulator to start and then build the apk...
That’s why we are setting the background: true attribute on the emulator command. This way, we kick off the emulator and can get back to building.
Also, adding parallel: true tells circle that the command should be run in parallel on all test machines

Add network options

To add more confidence to your AVD, add options to emulator create command for networking if your tests have to connect to the world.
-netdelay none -netspeed full

Now the emulator command looks like:
test:
  override:
    - emulator -avd circleci-android22 -netdelay none -netspeed full -no-audio -no-skin:
        background: true
        parallel: true


Disable Predexing

As CircleCI suggests: Add this to your root build.gradle file:

project.ext.preDexLibs = !project.hasProperty('disablePreDex')

  subprojects {
      project.plugins.whenPluginAdded { plugin ->
          if ("com.android.build.gradle.AppPlugin".equals(plugin.class.name)) {
              project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
          } else if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) {
              project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
          }
      }
  }


Then add the option -PdisablePreDex in your command that run tests.
  - ./gradlew test -PdisablePreDex

Set timeouts

Sometimes, you fail test and CircleCI throws a timeout exception. You can fix it by set proper timeouts.

Set timeout to the test command

When you get this error from CircleCI:

  ./gradlew test -PdisablePreDex took more than 10 minutes since last output


Add timeout to the command that run your tests (in seconds):

  - ./gradlew test -PdisablePreDex:
      timeout: 2400

Set timeout to adb install

When you get this error from CircleCI:

com.android.builder.testing.api.TestException: com.android.builder.testing.api.DeviceException: com.android.ddmlib.ShellCommandUnresponsiveException

Set ADB_INSTALL_TIME_OUT to an amount of time (in minutes) that satisfies your need as:

machine:
  environment:
    ADB_INSTALL_TIMEOUT : 20

in your circle.yml file.

If it doesn't work, add this in your build.gradle:

com.android.ddmlib.DdmPreferences.setTimeOut(600000)

If it's still not working, add adbOptions in build.gradle:

android {
    adbOptions {
        timeOutInMs 600000
    }
}


Thanks to this thread from StackOverFlow I found this solution when I was really helpless.

I thinks these tips are very simple and everyone should know when working with CircleCI. If you know some tips I haven't listed here, please share, I would love to know.

To make this post much more beautiful

Comments

Popular posts from this blog

New Admob for Android: Switching from Admob SDK to Google Play Services API

How to wrap a C# library for using in Java, a folk tale about an idiot coding at midnight.