<commit_before><!--

title: Test Android applications
short_title: Android
last_updated: Oct 17, 2014

-->

<!--

title: Test Android applications
last_updated: Oct 17, 2014

-->

CircleCI supports testing Android applications. The SDK is
already installed on the VM at `/usr/local/android-sdk-linux`

To save space, we don't download every android version, so you'll need to specify the versions
you use:

```
dependencies:
  pre:
    - echo y | android update sdk --no-ui --filter "android-18"
```

Note that if you need extended SDK components, such as build-tools, you'll
also need to install those separately. For example:

```
dependencies:
  pre:
    - echo y | android update sdk --no-ui --all --filter "build-tools-21.0.0"
```

<h3 id="caching">Caching Android SDK components</h3>

Installing SDK components can be expensive if you do it every time, so to speed
up your builds, it is wise to copy
the Android SDK to your home directory and add it to the set of cached directories.
Also, we want to have `ANDROID_HOME` point to this new location.

To accomplish this, put something like the following in your `circle.yml`:

```
machine:
  environment:
    ANDROID_HOME: /home/ubuntu/android
dependencies:
  cache_directories:
    - ~/.android
    - ~/android
  override:
    - ./install-dependencies.sh
```

This references the `install-dependencies.sh`
script. This is a script that you should write that installs
any Android dependencies, creates any test AVDs that you'll need, etc.
It should only do this once, so it should have a check to see
if the cached directories already have all of your dependencies.

For example, here is a basic `install-dependencies.sh`
that installs `android-18`
and some common tools. It also installs the x86 emulator image
and builds an AVD called `testing`.
(Note that if you ever change this file, you should clear your CircleCI
cache.)

```
#!/bin/bash

# Fix the CircleCI path
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH"

DEPS="$ANDROID_HOME/installed-dependencies"

if [ ! -e $DEPS ]; then
  cp -r /usr/local/android-sdk-linux $ANDROID_HOME &&
  echo y | android update sdk -u -a -t android-18 &&
  echo y | android update sdk -u -a -t platform-tools &&
  echo y | android update sdk -u -a -t build-tools-21.0.0 &&
  echo y | android update sdk -u -a -t sys-img-x86-android-18 &&
  echo y | android update sdk -u -a -t addon-google_apis-google-18 &&
  echo n | android create avd -n testing -f -t android-18 &&
  touch $DEPS
fi
```

<h3 id="emulator">Starting the Android emulator</h3>

For your actual tests, the first thing you should do is start up
the emulator, as this usually takes several minutes, sadly.

It's best if you can separate your actual build from installing it and
running tests on the emulator. If at all possible, start the build, and
then you MUST wait for the emulator to finish booting before
installing the APK and running your tests.

To wait for the emulator to boot, you need to wait for the
`init.svc.bootanim` property to be set to `stopped`.

Here's an example script for that, `wait.sh`:

```
#!/bin/bash

export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH"

while true; do
  BOOTUP=$(adb shell getprop init.svc.bootanim | grep -oe '[a-z]\+')
  if [[ "$BOOTUP" = "stopped" ]]; then
    break
  fi

  echo "Got: '$BOOTUP', waiting for 'stopped'"
  sleep 5
done
```

Then, you need to boot up your emulator (in the background), start your build, wait for your
emulator to finish booting, and then run your tests.
In your `circle.yml` file, it will look something like

```
test:
  override:
  - $ANDROID_HOME/tools/emulator -avd testing -no-window -no-boot-anim -no-audio:
      background: true
      parallel: true
  - # start your build here
  - ./wait.sh:
      parallel: true
  - # install your APK
  - # run your tests
```

### Running your tests

The standard way to run tests in the Android emulator is with something like

```<commit_msg>Fix the worst parts of the android doc.<commit_after><!--

title: Test Android applications
short_title: Android
last_updated: Oct 17, 2014

-->

<!--

title: Test Android applications
last_updated: Oct 17, 2014

-->

CircleCI supports testing Android applications. The SDK is
already installed on the VM at `/usr/local/android-sdk-linux`

To save space, we don't download every android version, so you'll need to specify the versions
you use:

```
dependencies:
  pre:
    - echo y | android update sdk --no-ui --filter "android-18"
```

Note that if you need extended SDK components, such as build-tools, you'll
also need to install those separately. For example:

```
dependencies:
  pre:
    - echo y | android update sdk --no-ui --all --filter "build-tools-21.0.0"
```

<h3 id="caching">Caching Android SDK components</h3>

Installing SDK components can be expensive if you do it every time, so to speed
up your builds, it is wise to copy
the Android SDK to your home directory and add it to the set of cached directories.
Also, we want to have `ANDROID_HOME` point to this new location.

To accomplish this, put something like the following in your `circle.yml`:

```
machine:
  environment:
    ANDROID_HOME: /home/ubuntu/android

dependencies:
  cache_directories:
    - ~/.android
    - ~/android
  override:
    - ./install-dependencies.sh
```

This references the `install-dependencies.sh`
script. This is a script that you should write that installs
any Android dependencies, creates any test AVDs that you'll need, etc.
It should only do this once, so it should have a check to see
if the cached directories already have all of your dependencies.

For example, here is a basic `install-dependencies.sh`
that installs `android-18`
and some common tools. It also installs the x86 emulator image
and builds an AVD called `testing`.
(Note that if you ever change this file, you should clear your CircleCI
cache.)

```
#!/bin/bash

# Fix the CircleCI path
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH"

DEPS="$ANDROID_HOME/installed-dependencies"

if [ ! -e $DEPS ]; then
  cp -r /usr/local/android-sdk-linux $ANDROID_HOME &&
  echo y | android update sdk -u -a -t android-18 &&
  echo y | android update sdk -u -a -t platform-tools &&
  echo y | android update sdk -u -a -t build-tools-21.0.0 &&
  echo y | android update sdk -u -a -t sys-img-x86-android-18 &&
  echo y | android update sdk -u -a -t addon-google_apis-google-18 &&
  echo n | android create avd -n testing -f -t android-18 &&
  touch $DEPS
fi
```

<h3 id="emulator">Starting the Android emulator</h3>

For your actual tests, the first thing you should do is start up
the emulator, as this usually takes several minutes, sadly.

It's best if you can separate your actual build from installing it and
running tests on the emulator. If at all possible, start the build, and
then you MUST wait for the emulator to finish booting before
installing the APK and running your tests.

To wait for the emulator to boot, you need to wait for the
`init.svc.bootanim` property to be set to `stopped`.

Here's an example script for that, `wait.sh`:

```
#!/bin/bash

export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH"

while true; do
  BOOTUP=$(adb shell getprop init.svc.bootanim | grep -oe '[a-z]\+')
  if [[ "$BOOTUP" = "stopped" ]]; then
    break
  fi

  echo "Got: '$BOOTUP', waiting for 'stopped'"
  sleep 5
done
```

Then, you need to boot up your emulator (in the background), start your build, wait for your
emulator to finish booting, and then run your tests.
In your `circle.yml` file, it will look something like

```
machine:
  environment:
    ANDROID_HOME: /home/ubuntu/android

test:
  override:
    - $ANDROID_HOME/tools/emulator -avd testing -no-window -no-audio:
        background: true
        parallel: true
    # start your build here
    - ./wait.sh:
        parallel: true
    # install your APK
    # run your tests
```

### Running your tests

The standard way to run tests in the Android emulator is with something like

```
{'fraction_non_alphanumeric': 0.09784369936432756, 'fraction_numerical': 0.010220615729776892, 'mean_word_length': 3.5642775881683733, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3930188', 'n_tokens_mistral': 2600, 'n_tokens_neox': 2435, 'n_words': 1084}