Running Unit Tests Automatically on the Emulator for Multiple Android Versions

It’s natural to write unit tests when developing Android applications, and it’s really convenient to do so in Eclipse by selecting “Run as Android Test”. Faced with testing for multiple Android versions, however, it’s troublesome because we will have to make manual selection of versions. Moreover, on the integrated test server only the command line is used. Obviously, we’ll benefit a lot if we have a script to control the versions automatically.

We first need to define an array loop:

all=(android2.2 android2.3 android3.2 android4.1 android4.2)
for i in "${all[@]}"
do
 .... run testcase and collect result....
done

There is the other issue: after starting the emulator from the command line, sometimes the command “adb” cannot detect it, causing the “adb wait-for-device” command to wait forever.   We wrote a small function to detect it, after starting the simulator, “adb devices” is called every second to scan if the word “offline” exists. If nothing is detected within one minute, then the current simulator is killed for restart.

# wait android emulator boot normally, sometime it looks booted,
# but adb cmd can not detected
function wait_emulator_boot(){
 bootok=0
 wait_time=1
 while [ $bootok -le 0 ]; do
   sleep 1
   # if detected offline status, it is boot ok
   bootok=`adb devices|grep offline|wc -l`
   (( wait_time++ ))
   # wait one minute, because more slower when version higher
   if [[ $wait_time -ge 60 ]]; then
     return
   fi
 done
 return
}

Next comes, without doubt, the emulator control by adb command and collecting test data. But there are some problems with the command adb, which, in particular, does not have return values. For example,

 adb install nobody.nobody.nobody

always returns 0. In other words, the script can’t detect if the installation succeeds or fails, an issue heaped with grumbles in Android forums.

The case with us is that the emulator already starts normally, by appearance at least, immediate executing of package installation would report:“Could not access the package manager, is the system running?”

Such error messages indicate that modules for software management are not ready yet inside the emulator. The higher the emulator version, the more serious the issue.

access_done=0
while [ $access_done -le 0 ]; do
  sleep 1
  access_done=`adb uninstall com.anfengde.epub.test|grep -v "Is the system running?"|wc -l`
done

Similarly, we keep scanning the output of error messages to see if it’s executable.

Full code is listed below so that it may be of use to you. Video clip of the running can be found at: Video Clip

#!/bin/bash
# Wirte by AFD Team, 2013.4.10
# define android version array for loop test
all=(android2.2 android2.3 android3.2 android4.1 android4.2)

# clean and build new version
ant clean
ant release

# wait android emulator boot normally, sometime it looks booted,
# but adb cmd can not detected
function wait_emulator_boot(){
  bootok=0
  wait_time=1
  while [ $bootok -le 0 ]; do
    sleep 1
    # if detected offline status, it is boot ok
    bootok=`adb devices|grep offline|wc -l`
    (( wait_time++ ))
    # wait one minute, because more slower when version higher
    if [[ $wait_time -ge 60 ]]; then
        return
    fi
  done
  return
}

# loop android version array
for i in "${all[@]}"
do
    retry=1
    running=0
    while [ $running -le 0 ]; do
        adb -s emulator-5554 emu kill
        echo "startup emulator:" $i "times:" $retry
        # run emulator in background
        emulator -avd $i &
        wait_emulator_boot

        # recheck emulator status
        running=`adb devices|grep line|wc -l`
        echo "check status:" $running "time:" `date`
    done

    # boot normally, just wait online
    adb wait-for-device

    # check software manager work not
    access_done=0
    while [ $access_done -le 0 ]; do
        sleep 1
        access_done=`adb uninstall com.anfengde.epub.test|grep -v "Is the system running?"|wc -l`
    done

    adb uninstall com.anfengde.epub.test > /dev/null
    adb install ./bin/EPUB_SDKTest.apk

    # run testcase
    adb shell am instrument -w com.anfengde.epub.test/android.test.InstrumentationTestRunner
    adb -s emulator-5554 emu kill
done