Android Continuous Integration,androidcontinuous
隨著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. 構建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/trusty64A `Vagrantfile` has been placed in this directory. You are nowready to `vagrant up` your first virtual environment! Please readthe comments in the Vagrantfile as well as documentation on`vagrantup.com` for more information on using Vagrant.XiaoMing:ci minggong$ vagrant upBringing 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] -- /vagrantXiaoMing:ci minggong$ vagrant sshWelcome 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 updatevagrant@ubuntu-14:~$ sudo apt-get install openjdk-7-jdk -yvagrant@ubuntu-14:~$ java -versionjava 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 updatesudo apt-get install jenkins -y
安裝完Jenkins後,首先驗證下Jenkins是否安裝完畢, curl http://localhost:8080
, 如果發現能夠輸出一堆HTML標籤,那麼證明Jenkins已經安裝成功並已經啟動了。Jenkins常見的使用命令如下,預設啟動在8080連接埠:
vagrant@ubuntu-14:~$ sudo /etc/init.d/jenkins -helpUsage: /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
- Android SDK官網找到最新的SDK安裝包地址:http://dl.google.com/android/android-sdk_r24.1.2-linux.tgz, 下載並解壓:
$ 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
$ 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
, 使檔案生效。
最簡單粗暴的方法是下載所有的SDK及相關的一系列工具,當然也可以挨個下載,具體參考上面提到的這篇文章。我採用直接更新全部的方法:
android update sdk --no-ui
經過漫長的等待,下載完畢之後這部分的工作也基本完成。(這一步一般留在半夜自行下載)
2.4 安裝Git
為了使Jenkins能夠直接從Git Repository上下載代碼,需要在Ubuntu中安裝Git:
sudo apt-get updatesudo 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 jenkinsEnter new UNIX password:Retype new UNIX password:passwd: password updated successfullyvagrant@ubuntu-14:/var/lib/jenkins$ su jenkinsPassword:jenkins@ubuntu-14:~$
使用權限設定成功後,再次運行測試,提示Android Build Tools沒有安裝成功:
+ ./gradlew clean buildFAILURE: 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 FAILEDFAILURE: 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 -icd /etc/apt/sources.list.decho "deb http://old-releases.ubuntu.com/ubuntu/ raring main restricted universe multiverse" >ia32-libs-raring.listapt-get updateapt-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中。歡迎查看我的部落格。