Running Tests on Two Emulators using Travis CI

Recently, I faced an issue where I was depending on some Android APIs which were added only in API level 16 (Jelly Bean). I had my tests running on API level 21 and everything seemed OK. But then I realized that the code I was testing was run on API 21 every time but the minSdkVersion of the project was 11. So I had to test my project on earlier versions of Android. And here I faced an issue where I needed my tests to be run on two emulators: one would be API level < 16 and the other would be API level >= 16.

As I was using Travis, I already had an emulator working for me but I haven’t found any documentation on how to run multiple emulators on Travis. So here are a few steps on how to get your multiple emulators working:

Step 1

sudo: required

Include this in your .travis.yml file in order to get more RAM. If you don’t, you’ll get container-based infrastructure which has only 4 GB. This can be somewhat risky because there should be enough space for your gradle build and two emulators.

- Standard Container-based
Boot Time 20-52s 1-6s
Memory 7.5 GB 4 GB max
Cores ~2, bursted 2

Information is taken from Travis CI official website.

Step 2

android:
  components:
    - tools
    - tools # This is not a typo. Needed for SDK update.
    - platform-tools
    - android-24 
    - build-tools-24.0.1
    - extra-android-m2repository
    - sys-img-armeabi-v7a-android-15
    - sys-img-armeabi-v7a-android-21

Configure the Travis for it to download and update system images of android-15 and android-21. BTW, if you want to use android-24 as the target SDK, be aware of this issue.

Step 3

script:
    # Create two emulator avds.
  - echo no | android create avd --force -n test1 -t android-21 --abi armeabi-v7a
  - echo no | android create avd --force -n test2 -t android-15 --abi armeabi-v7a
  
    # Start the first emulator.
  - emulator -avd test1 -no-skin -no-audio -no-window &
    # Wait for the first emulator to start.
  - sh scripts/wait-for-first-emulator.sh

    # Start the second emulator.
  - emulator -avd test2 -no-skin -no-audio -no-window &
    # Wait for the second emulator to start.
  - sh scripts/wait-for-second-emulator.sh

    # Unlock the devices.
  - adb -s emulator-5554 shell input keyevent 82 &
  - adb -s emulator-5556 shell input keyevent 82 &

    # Run the script.
  - sh scripts/script.sh

scripts/wait-for-first-emulator.sh is below (all credits to the script go here):

WAIT_CMD="adb -s emulator-5554 wait-for-device shell getprop init.svc.bootanim"

until $WAIT_CMD | grep -m 1 stopped; do
  echo "Waiting for first emulator..."
  sleep 1
done

The only difference between scripts/wait-for-first-emulator.sh and scripts/wait-for-second-emulator.sh is emulator-5554 and emulator-5556.

And the scripts/script.sh is also simple:

./gradlew clean build connectedAndroidTest -PdisablePreDex --stacktrace

In this way you can launch two emulators and execute your test suite on two devices simultaneously.

Thanks for reading! The sample repo is here.

comments powered by Disqus