Configure the automatic launch of UI tests Android applications through TeamCity

Sooner or later any tester developing the practice of self-testing faces the problem of autonomous execution of its tests. And, if the expert is experienced, then he tries to face this as early as possible. So I, after the first successful run of the autotest locally, decided to immediately configure the launch in TeamCity.
I note that we do not have any expertise in remote testing of Android tests, so we had to assiduously google, but I did not find deployed guides either. Therefore, I decided to burn this manual.
android sdk tools (Command line tools only) and unpack it into the desired directory. Create a directory for storing future AVD images (the space should be enough). For me, admins connected the main store to the directory /var, there and I will add everything. Next, we change the owner of the files to our user and the subsequent actions are better done under it.

    sudo chown tc_agent -R /var /opt /android-sdk
sudo mkdir /var/opt/.android
sudo chown tc_agent /var/opt/.android

We add environment variables. We open the file for editing. /home/tc_agent/.bash_profile and prescribe:

    export ANDROID_HOME = /var /opt /android-sdk
export ANDROID_AVD_HOME = /var /opt /.android /avd
export PATH = $ ANDROID_HOME /platform-tools: $ PATH
export PATH = $ ANDROID_HOME /tools: $ PATH

Reboot and check that the variables are correctly displayed in the web interface teamcity on the tab Agent Parameters .

Try to run sdkmanager: the command $ ANDROID_HOME /tools /bin /sdkmanager --list should list the installed and available packages. If you get an error of the form Exception in thread "main" java.lang.NoClassDefFoundError , then try this solution is .

We install the necessary Tula and image (s) of the virtual machines.

    $ ANDROID_HOME /tools /bin /sdkmanager emulator platform-tools tools
$ ANDROID_HOME /tools /bin /sdkmanager 'system-images; android-25; google_apis; x86'


Creating and running AVD

So, you downloaded the image 'system-images; android-25; google_apis; x86' (Android ???), we will create a virtual device based on it. I will not go into the details of all the possible parameters of the avdmanager utility, I will show on the minimum possible amount:

    $ ANDROID_HOME /tools /bin /avdmanager create avd -n avd_name -k "system-images; android-25; google_apis; x86"    

We pass the name and the source image (must be downloaded beforehand via sdkmanager). If the error returned, add the flag -v to view the text.

Let's move on to the emulator. First, check for the emulator, platforms, platform-tools, system-images folders in the SDK directory. platforms I created with my hands, the rest were created when installing packages through sdkmanager. Next, let's check the hardware acceleration. There must be such an answer.

    $ ANDROID_HOME /emulator /emulator -accel-check
KVM (version 12) is installed and usable.

If there is an access error to /dev /kvm , then we add the rights:

    addgroup kvm
usermod -a -G kvm tc_agent
chown root: kvm /dev /kvm

Plus, I still needed to install QEMU: sudo apt-get install qemu-kvm
We make a relog and check the emulator again.

If everything is OK, then try to start. To see the eyes, connect to the server by vnc. And run the emulator:

    $ ANDROID_HOME /emulator /emulator @avd_name    

This window should appear:

Configure the automatic launch of UI tests Android applications through TeamCity

During run tests we will run without graphics, so add the parameter -no-window .


Configure build in TeamCity

We pass to the final stage - setting up an autonomous launch of our tests. I got a build of 4 steps.

1. Starting the emulator

    nohup /var /opt /android-sdk /emulator /emulator @avd_name -no-snapshot-save -no-boot-anim -no-window -snapshot clean_snap_1> start_emulator.log 2> & 1 &    

Since the emulator "locks" the terminal, you need to untie the process using the utility nohup (you can and in another way - it's up to you). Just in case, we save the emulator log to the file start_emulator.log . To run the tests, I created a clean snapshot (how to do this, read here ) And added the key -no-snapshot-save so that it does not overwrite.

2. Waiting for the device to load.

    adb wait-for-device shell 'while[[-z $(getprop sys.boot_completed) ]]; do sleep 1; done; '    

First we wait for the status wait-for-device , then in the loop wait when the variable sys.boot_completed will return 1.

3. Running the tests. Here everything is individual, here is my example:

    ./gradlew clean connectedAndroidTest    

4. Close the emulator. Here, for the time being, a simple termination of the process has been made.

    kill -s 2 `pgrep qemu-system`  
But it is better, of course, to remember the process ID when creating the emulator. This will be necessary when we start running tests in several threads, which is not accidentally "killing" the wrong process.
That's all, thank you for reading it. If there are comments from more experienced colleagues, then with pleasure, make corrections to the manual.
+ 0 -

Add comment