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

Goals of Upcoming Work

We are very grateful to the developers around the world for their recommendations and functional requirements. We ourselves also found that there are inadequacies in our work. We’ve focused on the development of functional features, neglecting the documentation part.

Two important things to do:
1, To provide a commercial AnReader program, fully open source, on which our customers can make changes to achieve their own reading software. This application will be available in Apple’s AppStore and Google Play.
2, To perfect documentation by adding implementation documents to facilitate the developers with references so as to make up for the inconvenience in concealing the core code.
After the completion of this stage, we will consider the DRM aspects of the work. As a matter of fact, the publishing industry can not just stare at contents such as novels and magazines. There are a lot of data with economic value, e.g., stock market analysis, training materials. It is entirely reasonable that respective customers set confidentiality requirement for fresh contents. As for tools for compiling EPUB books, we do not intend to develop an editor now. Rather, we will make use of existing open source tools, or provide this functionality by writing plug-ins for Office software.

Thank you, programmers, very much for your support. Please contact us when you have any questions.