Sooner or later, any tester who develops autotesting practices faces the problem of performing their tests autonomously. Moreover, if an expert is experienced, he tries to face it as soon as possible. So, after the first successful AutoTest run locally, I decided to immediately set up a launch in TeamCity.
I note that in our company there is practically no expertise in the remote launch of instrumental tests for Android, so we had to google hard, but I didn’t find any deployed guides. Therefore, and decided to gash this instruction.
At the entrance we have:
- test (s) running locally successfully
- running TeamCity server
- debian server with KVM and X
Immediately a disclaimer about the server where the launch will take place: the configuration of the OS, hardware virtualization and the graphical shell is not the subject of this article and will be omitted.Install and configure the TeamCity agent
Let's start with java. The main thing is to choose the right version. I had 3 dependencies: the tests themselves, android tools and the teamcity agent. I stopped at version 8 to use the same JVM for everyone. If you are less fortunate, and there will be conflicts, you will have to configure the use of multiple versions of Java on the same machine. Another note: if you have debian, then you first need to add webupd8team repositories (it is googling very quickly).
sudo apt-get install oracle-java8-installer sudo apt-get install oracle-java8-set-default
Next, create a user under which the agent will run and, accordingly, everything else. Do not forget to set a password.
sudo useradd -d /home/tc_agent -s /bin/bash -m tc_agent sudo passwd tc_agent
Agent distribution can be obtained in the web interface of your teamcity. To do this, go to the
Agents section and click on the
Install Build Agents link in the upper right. Download and unpack to the correct folder on the server (I recommend our user's home folder -
/home/tc_agent
). Next, add launch rights to all scripts:
sudo chmod +x /home/tc_agent/BuildAgent/bin/*
If your version of teamcity supports Agent Push, it’s still easier. Just open the corresponding tab in the web interface, click the
Install Agent button
... and follow the instructions.
Configuring the config. If you have used a remote installation, then it has already been created and in it you only need to set the name of the agent. If not, create:
cd /home/tc_agent/BuildAgent/conf cp buildAgent.dist.properties buildAgent.properties nano buildAgent.properties
serverUrl=
web interface address of the server, and
name=
unique name of the agent. If you have several agents or the default port (9090) is busy, then set your own using the parameter
ownPort=
.
We
/home/tc_agent/BuildAgent/bin/agent.sh start
command
/home/tc_agent/BuildAgent/bin/agent.sh start
. If everything is configured correctly, then we will see our agent on the
Unauthorized tab. Authorize and can use.
To automatically start the agent, create the
/etc/init.d/teamcity_agent
script with the following contents:
Add the right to run
sudo chmod +x /etc/init.d/teamcity_agent
and add the line
/etc/init.d/teamcity_agent start
to the
/etc/rc.local
file.
Control reset, the agent has risen, we go further.
Install Android SDK and emulator
Download
android sdk tools (Command line tools only) and unpack it in the correct directory. Create a directory to store future images of AVD (space should be enough). For me, the admins have connected the main repository to the
/var,
directory
/var,
and there I will add everything. Next, we change the owner of the files to our user and the next steps are best done under him.
sudo chown tc_agent -R /var/opt/android-sdk sudo mkdir /var/opt/.android sudo chown tc_agent /var/opt/.android
Add environment variables. Open the file
/home/tc_agent/.bash_profile
and edit it:
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 verify that the variables are correctly displayed in the teamcity web interface on the
Agent Parameters tab.
Trying to run sdkmanager: the
$ANDROID_HOME/tools/bin/sdkmanager --list
list
$ANDROID_HOME/tools/bin/sdkmanager --list
should list the installed and available packages. If you get an error like
Exception in thread "main" java.lang.NoClassDefFoundError
, then try
this solution .
Install the necessary tula and virtualok image (s).
$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, download the image
'system-images;android-25;google_apis;x86'
(Android 7.1.1), let's create a virtual device based on it. I will not go into the details of all possible parameters of the avdmanager utility, I will show it in the smallest possible quantity:
$ANDROID_HOME/tools/bin/avdmanager create avd -n avd_name -k "system-images;android-25;google_apis;x86"
We transfer the name and the original image (must be downloaded in advance via sdkmanager). If the error returned, add the
-v
flag to view the text.
Go to the emulator. First, check for the presence of emulator, platforms, platform-tools, system-images folders in the SDK directory. I created the platforms with my hands, the rest were created when installing packages via sdkmanager. Next, check the hardware acceleration. There must be such an answer.
$ANDROID_HOME/emulator/emulator -accel-check accel: 0 KVM (version 12) is installed and usable. accel
If there is an error accessing
/dev/kvm
, then add the rights:
addgroup kvm usermod -a -G kvm tc_agent chown root:kvm /dev/kvm
Plus, I also needed to install QEMU:
sudo apt-get install qemu-kvm
We make relogon and check the emulator again.
If everything is ok, then we try to run it. To see with our eyes, connect to the server via vnc. And run the emulator:
$ANDROID_HOME/emulator/emulator @avd_name
A window like this should appear:
During the tests we will run without graphics, so add the
-no-window
parameter.
Customize build in TeamCity
We proceed to the final stage - setting up the autonomous launch of our tests. I have a 4 step build.
1. Run 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 with the help of the nohup utility (it’s possible and differently - you decide). Just in case, save the emulator log to the
start_emulator.log
file. To run the tests, I created a clean snapshot (how to do this, read
here ) and added the
-no-snapshot-save
switch to prevent it from being overwritten.
2. Waiting for the device to load.
adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'
First, wait for the status of
wait-for-device
, then wait in the loop when the variable
sys.boot_completed
returns 1.
3. Run tests. Here everything is individual, here is my example:
./gradlew clean connectedAndroidTest
4. Close the emulator. Here, so far, a simple termination process has been made.
kill -s 2 `pgrep qemu-system`
But it is better, of course, to memorize the process ID when creating an emulator. It will be necessary when we start running tests in several threads, which by chance does not “kill” the wrong process.
That's all, thank you for reading. If there are comments from more experienced colleagues, I will gladly make changes to the manual.