持續(xù)集成
歡迎閱讀WebDriver持續(xù)集成講義。本篇講義將會重點介紹Selenium WebDriver API的在持續(xù)集成中的使用方法,以及使用Jenkins持續(xù)集成工具進行自動化測試的設計。
持續(xù)集成的概念
持續(xù)集成的定義
持續(xù)集成,Continuous integration ,簡稱CI。
隨著軟件開發(fā)復雜度的不斷提高,團隊開發(fā)成員間如何更好地協同工作以確保軟件開發(fā)的質量已經慢慢成為開發(fā)過程中不可回避的問題。尤其是近些年來,敏捷(Agile) 在軟件工程領域越來越紅火,如何能再不斷變化的需求中快速適應和保證軟件的質量也顯得尤其的重要。
持續(xù)集成正是針對這一類問題的一種軟件開發(fā)實踐。首先我們看一下,敏捷教父 Martin Fowler
對持續(xù)集成的定義:
Martin Fowler:*Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. *
具體定義:持續(xù)集成式一種軟件開發(fā)實踐。它倡導團隊的成員必須經常的集成他們的工作,通常至少每天一次甚至更多次集成。每次集成都需要通過自動化的構建(包括編譯代碼、構建應用、部署程序以及自動化測試)來驗證,從而盡早盡快的發(fā)現集成中的錯誤。大量的團隊利用這樣的方式來更快的開發(fā)內聚的軟件。大大減少此過程中的集成問題。
具體的流程圖如下:
持續(xù)集成強調開發(fā)人員提交了新代碼之后,立刻進行構建、(單元、自動化)測試。根據測試結果,我們可以確定新代碼和原有代碼能否正確地集成在一起。
首先,解釋下集成。我們所有項目的代碼都是托管在SVN服務器上。每個項目都要有若干個單元測試,并有一個所謂集成測試。所謂集成測試就是把所有的單元測試跑一遍以及其它一些能自動完成的測試。只有在本地電腦上通過了集成測試的代碼才能上傳到SVN服務器上,保證上傳的代碼沒有問題。所以,集成指集成測試。
再說持續(xù)。不言而喻,就是指長期的對項目代碼進行集成測試。既然是長期,那肯定是自動執(zhí)行的,否則,人工執(zhí)行則沒有保證,而且耗人力。對此,我們有一臺服務器,它會定期的從SVN中檢出代碼,并編譯,然后跑集成測試。每次集成測試結果都會記錄在案。完成這方面工作的就是下面要介紹的Jenkins軟件。當然,它的功能遠不止這些。在我們的項目中,執(zhí)行這個工作的周期是1天。也就是,服務器每1天都會準時地對SVN服務器上的最新代碼自動進行一次集成測試。
持續(xù)集成的特點
- 它是一個自動化的周期性的集成測試過程,從檢出代碼、編譯構建、運行測試、結果記錄、測試統計等都是自動完成的,無需人工干預;
- 需要有專門的集成服務器來執(zhí)行集成構建;
- 需要有代碼托管工具支持;
持續(xù)集成的作用
- 代碼庫存越是積壓,就越得不到生產檢驗,積壓越多,代碼間交叉感染的概率越大,下個發(fā)布(release)的復雜度和風險越高,持續(xù)集成可以保證團隊開發(fā)人員提交代碼的質量,減輕了軟件發(fā)布時的壓力;
- 持續(xù)集成中的任何一個環(huán)節(jié)都是自動完成的,無需太多的人工干預,有利于減少重復過程以節(jié)省時間、費用和工作量;
- 及早的發(fā)現代碼中的問題,及早解決,代碼越早推送(PUSH)出去,用戶能越早用到,快就是商業(yè)價值;
舉個例子,你家裝修廚房,其中一項是鋪地磚,邊角地磚要切割大小。如果一次全切割完再鋪上去,發(fā)現尺寸有誤的話浪費和返工時間就大了,不如切一塊鋪一塊。裝修廚房有很多部分,每個部分都有檢測手段,如地磚鋪完了要測試漏水與否,線路鋪完了要通電測試電路通順,水管裝好了也要測試冷水熱水。如果全部裝完了再測,出現問題可能會互相影響,比如電路不行可能要把地磚給挖開……。全部裝修完了,你去驗收,發(fā)現地磚顏色不合意,水池太小,灶臺位置不對,返工嗎?所以不如沒完成一部分,你就去用一下試用驗收……這就是持續(xù)集成。在敏捷的思想里面,不光強調上面的過程,還需要強調自動化這個過程。過技術手段自動化這三個工作。加快交付速度,自動化測試是一個重要的組成部分。
Jenkins
Jenkins介紹
Jenkins,原名Hudson,2011年改為現在的名字,它 是一個開源的實現持續(xù)集成的軟件工具。官方網站:http://jenkins-ci.org/。
Hudson是在2004年的夏天由Sun公司開發(fā)的(就是開發(fā)Java的那家),2005年2月開源并發(fā)布了第一個版本。Hudson發(fā)布的時候CruiseControl是CI界的老大哥,但是很快,在大約2007年的時候Hudson已經超越CruiseControl。2008年5月的JavaOne大會上,Hudson獲得了開發(fā)解決方案類的Duke's Choice獎項。從此,小弟翻身做大哥,Hudson成為CI的代名詞。
2009年6月,Oracle收購Sun。2010年9月,Oracle注冊了Hudson的商標,然后就沒有然后了。
mv -f Hudson Jenkins
Jenkins 能實施監(jiān)控集成中存在的錯誤,提供詳細的日志文件和提醒功能,還能用圖表的形式形象地展示項目構建的趨勢和穩(wěn)定性。
Jenkins特點
- 易安裝:僅僅一個
java -jar jenkins.war
,從官網下載該文件后,直接運行,無需額外的安裝,更無需安裝數據庫; - 易配置:提供友好的GUI配置界面;
- 變更支持:Jenkins能從代碼倉庫(git/Subversion/CVS)中獲取并產生代碼更新列表并輸出到編譯輸出信息中;
- 支持永久鏈接:用戶是通過web來訪問Jenkins的,而這些web頁面的鏈接地址都是永久鏈接地址,因此,你可以在各種文檔中直接使用該鏈接;
- 集成E-Mail/RSS/IM:當完成一次集成時,可通過這些工具實時告訴你集成結果(據我所知,構建一次集成需要花費一定時間,有了這個功能,你就可以在等待結果過程中,干別的事情);
- JUnit/TestNG測試報告:也就是用以圖表等形式提供詳細的測試報表功能;
- 支持分布式構建:Jenkins可以把集成構建等工作分發(fā)到多臺計算機中完成;
- 文件日志信息:Jenkins會保存哪次集成構建產生了哪些jars文件,哪一次集成構建使用了哪個版本的jars文件等構建記錄;
- 支持第三方插件:使得 Jenkins 變得越來越強大;
Jenkins的安裝
需要從官網下載Jenkins的文件,在本地安裝Java(jdk)的環(huán)境以后,直接執(zhí)行以下語句進行安裝:
java -jar jenkins.war
注意上述操作,一定是在Java環(huán)境已經配置好的情況下進行。輸出如下:
Microsoft Windows [Version 10.0.10532]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Users\erha>java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
C:\Users\erha>java -jar d:\Jenkins\jenkins.war
Running from: D:\Jenkins\jenkins.war
webroot: $user.home/.jenkins
Jun 19, 2016 12:52:18 AM winstone.Logger logInternal
INFO: Beginning extraction from war file
Jun 19, 2016 12:52:29 AM org.eclipse.jetty.util.log.JavaUtilLog info
INFO: jetty-winstone-2.9
Jun 19, 2016 12:52:33 AM org.eclipse.jetty.util.log.JavaUtilLog info
INFO: NO JSP Support for , did not find org.apache.jasper.servlet.JspServlet
Jenkins home directory: C:\Users\erha\.jenkins found at: $user.home/.jenkins
Jun 19, 2016 12:52:35 AM org.eclipse.jetty.util.log.JavaUtilLog info
INFO: Started SelectChannelConnector@0.0.0.0:8080
Jun 19, 2016 12:52:35 AM winstone.Logger logInternal
INFO: Winstone Servlet Engine v2.0 running: controlPort=disabled
Jun 19, 2016 12:52:36 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started initialization
Jun 19, 2016 12:53:11 AM jenkins.InitReactorRunner$1 onAttained
INFO: Listed all plugins
Jun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttained
INFO: Prepared all plugins
Jun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started all plugins
Jun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttained
INFO: Augmented all extensions
Jun 19, 2016 12:53:15 AM jenkins.InitReactorRunner$1 onAttained
INFO: Loaded all jobs
Jun 19, 2016 12:53:25 AM hudson.model.AsyncPeriodicWork$1 run
INFO: Started Download metadata
Jun 19, 2016 12:53:26 AM org.jenkinsci.main.modules.sshd.SSHD start
INFO: Started SSHD at port 10556
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Completed initialization
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started initialization
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Listed all plugins
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Prepared all plugins
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started all plugins
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Augmented all extensions
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Loaded all jobs
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Completed initialization
Jun 19, 2016 12:53:26 AM hudson.WebAppMain$3 run
INFO: Jenkins is fully up and running
Jun 19, 2016 12:53:32 AM hudson.model.UpdateSite updateData
INFO: Obtained the latest update center data file for UpdateSource default
Jun 19, 2016 12:53:33 AM hudson.model.DownloadService$Downloadable load
INFO: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller
Jun 19, 2016 12:53:34 AM hudson.model.DownloadService$Downloadable load
INFO: Obtained the updated data file for hudson.tasks.Ant.AntInstaller
Jun 19, 2016 12:53:37 AM hudson.model.DownloadService$Downloadable load
INFO: Obtained the updated data file for hudson.tools.JDKInstaller
Jun 19, 2016 12:53:37 AM hudson.model.AsyncPeriodicWork$1 run
INFO: Finished Download metadata. 12,471 ms
隨后訪問http://localhost:8080即可
最后,將Jenkins安裝成Windows服務啟動
在Jenkins的主頁中選擇 Manager Jenkins
[圖片上傳失敗...(image-223b63-1516464936475)]
接下來選擇 Install as Windows Service
[圖片上傳失敗...(image-7398af-1516464936476)]
在Installation Directory中選擇jenkin的安裝路徑。這里會默認產生,直接點擊Install就可以了。
[圖片上傳失敗...(image-7beb5b-1516464936476)]
隨后我們點擊Yes,然后可以看到Windows服務中添加了Jenkins的服務,并已經設置為自動和啟動狀態(tài)。
[圖片上傳失敗...(image-c7aaac-1516464936476)]
持續(xù)集成的實踐
創(chuàng)建Jenkins Job
Jenkins提供了四種類型的Job:
- 構建一個自由風格的軟件項目:這個是Jenkins的主要功能,可以構建一個你自己需要的項目。
- 構建一個maven項目:這是基于maven構建的項目,整個過程將會基于你的.pom文件進行構建,大大減輕構建的配置
- 構建一個多配置項目:這種項目適用多配置的項目,比如多個平臺定制的構建,多個測試環(huán)境的部署構建等。
- 監(jiān)控一個外部的任務:這種事允許你記錄和執(zhí)行不在Jenkins中的Job,這些Job可以運行在遠程的主機上,Jenkins通過遠程自動構建,作為一個控制面板而存在。
運行Jenkins Job
運行Job只需要在頁面的左側選中已經列出的項目,進行操作就可以了。選擇立即構建,便可以進行自動構建的工作了。
定時構建 Job
目前有一個每日構建的概念。
Daily Build,每日構建。需要Jenkins在每日固定的時間進行代碼自動構建、集成和測試的工作。那么需要定制執(zhí)行時間。Jenkins的自動構建定制時間是遵循cron語法的。具體來說,每一行包括了5個用白空格或者Tab隔開的字段,分別是:MINUTE HOUR DOM MONTH DOW
。具體的格式我們參考下圖
字段 | 說明 | 示例 |
---|---|---|
MINUTE | Minutes within the hour (0–59) | 30 |
HOUR | The hour of the day (0–23) | 17 |
DOM | The day of the month (1–31) | 1 |
MONTH | The month (1–12) | 5 |
DOW | The day of the week (0–7) where 0 and 7 are Sunday. | 5 |
然后每個格式,都可以由*
,-
,/
和,
4種字符組成:
-
*
代表所有可能的值 -
-
代表整數之間的范圍 -
/
代表指定的時間的間隔頻率 -
,
代表指定的列表范圍
命令的格式參考和示例
分鐘 | 小時 | 天 | 月份 | 星期 | 執(zhí)行的命令 | |
---|---|---|---|---|---|---|
* | 16 | 1,10,20 | * | * | python xxx | 每個月的1,10,20日的16:00執(zhí)行 python xxx 命令格式:* 16 1,10,20 * *
|
* | 16 | * | * | 1-5 | python yyy | 每個周的周一到周五的16:00執(zhí)行 python yyy 命令格式:* 16 * * 1-5
|
30 | 17 | * | * | 1,5 | python zzz | 每個周的周一和周五的17:30執(zhí)行 python zzz 命令格式:30 17 * * 1,5
|
ps: 注意時間是倫敦時間
至此,我們將會對Jenkins有一個非常范和初步的了解過程。
示例:
1. 創(chuàng)建SVN倉庫
https://172.31.95.168/svn/DemoRepo/
ciuser / ciuser
2. 從SVN倉庫簽出文件到CI Server
3. 構建 build
4. 部署
4.1 備份目標文件夾
若有ranzhi_bak 需要先刪除
rd /s /q c:\xampp\htdocs\ranzhi_bak
把 htdoc的ranzhi改成 ranzhi_bak
xcopy c:\xampp\htdocs\ranzhi c:\xampp\htdocs\ranzhi_bak\ /s /e /y
rd /s /q c:\xampp\htdocs\ranzhi
4.2 復制構建的版本到目標文件夾
把workspace的 ranzhi 復制到 htdocs下面
xcopy "%WORKSPACE%\ranzhi" c:\xampp\htdocs\ranzhi\ /s /e /y
4.3 恢復配置文件
復制 ranzhi_bak\config\my.php 到 ranzhi\config\my.php
xcopy c:\xampp\htdocs\ranzhi_bak\config\my.php c:\xampp\htdocs\ranzhi\config\ /e
5. 自動化測試
python D:\Git\Coding\BWFTraining\3.03_Selenium\codes\weekend2demo\ranzhi_test_runner.py