Android Continuous Integration

隨着Android平臺的逐漸成熟,伴隨着一系列針對Android測試框架的推出,開發人員終於可以如願以償的在移動端的開發上進行單元測試,集成測試以及功能測試。在敏捷流程中從開發,到測試,到驗收最終成爲面向用戶的Release版本,經歷的是Story一個完整的生命週期。CI(Continuous Integration, 持續交付)在敏捷實踐中也因此扮演了非常重要的角色。

如果說Web的持續集成,以及各類測試框架有一定的歷史積澱了。那麼Android的持續集成可以說是新鮮事物,大部分IT公司知道如何對服務器端或者Web端進行一系列自動化測試,保證其功能的正確性。而對於移動端的產品比較多的則是由測試人員組成的人肉測試。移動端的這種人工測試,無論是對測試人員,還是要經常打包並且來修復各種Bug的開發人員來說,其代價是巨大的。

從Android 2.3.3 版本就開始,我就成爲了Android的開發者。從開發者的角度見證了Android的步步升級,也從普通用戶的角度見證了Android在中低端市場上的統治權。雖然我對Apple的產品也很滿意,但是我對Android的感情卻也是無法割捨的。我慶幸自己終於能夠在Android上也見證測試驅動開發的實踐,也慶幸自己有機會去親身實踐,從零開始學習並瞭解Android的持續集成。

前言

本文主要是從零開始,以學習者的角色來探索如何構建可用的Android CI環境。最後的目標是,在Jenkins上從build單元測試,到功能測試的運行,最後通過一鍵部署編譯出可供QA測試的QA版本,可供Release的Release版本,並藉助HockeyApp,生成可下載的鏈接。

  1. 構建出一個含有單元測試和集成測試簡單的App原型。
  2. 通過vagrant在本地運行Ubuntu虛擬機,並安裝Jenkins服務器,在Ubuntu上安裝配置Android運行環境。
  3. 在Jenkins中創建Android Pipeline, Android Build -> Android Functional Test -> Android Deploy Hockey App。
  4. 在Android工程中創建不同的環境變量,使得構建時能夠選擇不同的構建變量,編譯生成QA和Release等不同環境下的App。

1. 構建Android基礎工程,本地運行測試

這裏的基礎工程主要指的是能夠運行測試的基礎功能,我選擇使用Robolectric做單元測試,使用espresso做繼承測試(後面的文章也會探討使用)。基礎工程主要參考了robolectric/decard-gradle, 通過一些gradlew的配置,使我們的工程能夠直接運行單元測試和集成測試。

運行單元測試:

./gradlew test

運行espresso測試:

./gradlew connectedAndroidTest

一旦你這個實例運行成功,說明這一步其實已經完成。後面我們只需要通過jenkins來跑這幾條命令,然後展示結果即可。

2. 在虛擬機中安裝Jenkins和Android環境

爲了從零開始,我選擇了一臺乾淨的Ubuntu/trusty機器,爲了使構建從零開始,可以更好的模擬我們在EC2機器真實的情
形。從測試的角度來說,我選擇使用Vagrant來啓動虛擬機。

XiaoMing:ci minggong$ vagrant init ubuntu/trusty64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
XiaoMing:ci minggong$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'ubuntu/trusty64'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Fixed port collision for 22 => 2222. Now on port 2200.
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2200 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Mounting shared folders...
[default] -- /vagrant
XiaoMing:ci minggong$ vagrant ssh
Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.13.0-24-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
Last login: Tue Apr 22 19:47:09 2014 from 10.0.2.2

如果在Vagrantfile中已經設置了靜態IP,則可以直接通過IP登陸。vagrant默認用戶名爲 vagrant, 密碼爲vagrant

使用 vagrant ssh 登錄虛擬機之後,則開始安裝各種環境:

  • Java
  • Jenkins
  • Android Environment

2.1 安裝Java

apt-get直接安裝jdk1.7:

vagrant@ubuntu-14:~$ sudo apt-get update
vagrant@ubuntu-14:~$ sudo apt-get install openjdk-7-jdk -y
vagrant@ubuntu-14:~$ java -version
java version "1.7.0_75"
OpenJDK Runtime Environment (IcedTea 2.5.4) (7u75-2.5.4-1~trusty1)
OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)

2.2 安裝Jenkins

參考Jenkins官方教程:

wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins -y

安裝完Jenkins後,首先驗證下Jenkins是否安裝完畢, curl http://localhost:8080, 如果發現能夠輸出一堆HTML標籤,那麼證明Jenkins已經安裝成功並已經啓動了。Jenkins常見的使用命令如下,默認啓動在8080端口:

vagrant@ubuntu-14:~$ sudo /etc/init.d/jenkins -help
Usage: /etc/init.d/jenkins {start|stop|status|restart|force-reload}

Jenkins默認de配置文件爲/etc/default/jenkins, 可以看到Jenkins_home定義的路徑:

 #jenkins home location
 JENKINS_HOME=/var/lib/jenkins

如果需要更改默認的Jenkins home 路徑,需要更改 /etc/default/jenkins地址,然後重新啓動jenkins即可生效。

2.3 安裝Android運行環境

最後一步我們需要安裝Android運行環境,這樣我們的Jenkins才能夠運行Android的相關測試。主要參考文章 How to Build Apps with Jenkins

$ cd /opt
$ sudo wget http://dl.google.com/android/android-sdk_r24.1.2-linux.tgz
$ sudo tar zxvf android-sdk_r24.1.2-linux.tgz
$ sudo rm android-sdk_r24.1.2-linux.tgz
  • 設置Android環境變量:
$ vi /etc/profile.d/android.sh

Add the following to android.sh file

export ANDROID_HOME="/opt/android-sdk-linux"
export PATH="$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH"

然後 source /etc/profile, 使文件生效。

  • 配置 Android SDK

最簡單粗暴的方法是下載所有的SDK及相關的一系列工具,當然也可以挨個下載,具體參考上面提到的這篇文章。我採用直接更新全部的方法:

android update sdk --no-ui

經過漫長的等待,下載完畢之後這部分的工作也基本完成。(這一步一般留在半夜自行下載)

2.4 安裝Git

爲了使Jenkins能夠直接從Git Repository上下載代碼,需要在Ubuntu中安裝Git:

sudo apt-get update
sudo apt-get install git -y

2.5 配置Jenkins

Jenkins啓動後,首先註冊登錄用戶,然後創建新的Build Project。構建就基本完成了。當然你也可以在前一篇博客 Set up Jenkins for Android integration using Docker中找到一些插件,通過這些插件能夠更好的實現Android的持續集成,包括通過Hockey App 持續的發佈新的版本。

具體安裝細節,可以參考Setup Android CI using Docker

粗略說來,安裝插件: Git plugin, Android emulator plugin, Copy artifact plugin, Android lint plugin, Hockey app plugin, Build monitor plugin

運行時發現jenkins用戶對jenkins-home目錄沒有操作權限,需要通過chmod增加權限。在當前vagrant用戶下,su jenkins 能夠切換到jenkins目錄下,但是需要提供密碼。所以可以自行修改密碼:

vagrant@ubuntu-14:/var/lib/jenkins$ sudo passwd jenkins
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
vagrant@ubuntu-14:/var/lib/jenkins$ su jenkins
Password:
jenkins@ubuntu-14:~$

權限設置成功後,再次運行測試,提示Android Build Tools沒有安裝成功:

+ ./gradlew clean build

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> failed to find Build Tools revision 21.1.2

Android Build Tools的版本號是我們在app/build.gradle中指定的21.1.2。通過 android list sdk --all能夠查看所有可以下載的sdk列表。

Packages available for installation or update: 138
   1- Android SDK Tools, revision 24.1.2
   2- Android SDK Platform-tools, revision 22
   3- Android SDK Build-tools, revision 22.0.1
   4- Android SDK Build-tools, revision 22 (Obsolete)
   5- Android SDK Build-tools, revision 21.1.2
   6- Android SDK Build-tools, revision 21.1.1 (Obsolete)
   7- Android SDK Build-tools, revision 21.1 (Obsolete)
   8- Android SDK Build-tools, revision 21.0.2 (Obsolete)
   9- Android SDK Build-tools, revision 21.0.1 (Obsolete)

可以看到21.1.2的索引值是5,所以可以使用 android update sdk -u --all --filter <number>更新,發現出現權限問題。

Installing Archives:
  Preparing to install archives
  Downloading Android SDK Build-tools, revision 21.1.2
  URL not found: /opt/android-sdk-linux/temp/build-tools_r21.1.2-linux.zip (Permission denied)
  Done. Nothing was installed.

可以直接在當前用戶下給/opt/android-sdk-linux以及其子文件夾增加777權限。

sudo chmod -R 777 /opt/android-sdk-linux

然後安裝Android build tools 21.1.2, android update sdk -u --all --filter 5。安裝完成後還可能會出現錯誤:

:app:mergeDevDebugResources FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDevDebugResources'.
> Error: org.gradle.process.internal.ExecException: A problem occurred starting process 'command '/opt/android-sdk-linux/build-tools/22.0.1/aapt''

Google了一番,才發現是Android在64爲Linux機器上運行而產生的問題,需要安裝ia32-libs, 但是通過apt安裝確被告知ia32-libs不存在,無法安裝。stackoverflow解決辦法如下:

sudo -i
cd /etc/apt/sources.list.d
echo "deb http://old-releases.ubuntu.com/ubuntu/ raring main restricted universe multiverse" >ia32-libs-raring.list
apt-get update
apt-get install ia32-libs

安裝成功後,Android 單元測試即可成功運行。

單元測試之後,我們往往需要運行功能測試,功能測試的時候則需要打開模擬器。也就是 headless android emulator。首先在虛擬機中創建 avd, 然後啓動運行模擬器。

運行之前需要先安裝 API-21對應的 armeabi-v7a, 才能夠創建虛擬機。通過查看android list sdk --all得知其對應的序列號是68,所以可以通過android update安裝:

android update sdk -u --all --filter 68

安裝完成後創建API-21虛擬機:

android create avd -f -a -s 1080x1920 -n Nexus-21 -t android-21 --abi

虛擬機創建成功後需要打開虛擬機:

emulator -avd Nexus-21 -no-skin -no-audio -no-window

順利的話,到這裏功能測試應該也能夠運行了。但是在我的虛擬機裏面卻沒辦法啓動android emulator。看來想構建真正的android功能測試,還是用一臺配有顯示器的Mac mini來運行比較的靠譜。

3.Other

如何在Android中配置不同的Flavor,如何上傳構建好的App到HockeyApp中。歡迎查看我的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章