DevOps入門教程——Jenkins持續集成篇

DevOps入門教程——Jenkins持續集成篇

持續集成

歡迎閱讀WebDriver持續集成講義。本篇講義將會重點介紹Selenium WebDriver API的在持續集成中的使用方法,以及使用Jenkins持續集成工具進行自動化測試的設計。

持續集成的概念

持續集成的定義

持續集成,Continuous integration ,簡稱CI。

隨著軟體開發複雜度的不斷提高,團隊開發成員間如何更好地協同工作以確保軟體開發的質量已經慢慢成為開發過程中不可迴避的問題。尤其是近些年來,敏捷(Agile) 在軟體工程領域越來越紅火,如何能再不斷變化的需求中快速適應和保證軟體的質量也顯得尤其的重要。

持續集成正是針對這一類問題的一種軟體開發實踐。首先我們看一下,敏捷教父 Martin Fowler 對持續集成的定義:

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. *

具體定義:持續集成式一種軟體開發實踐。它倡導團隊的成員必須經常的集成他們的工作,通常至少每天一次甚至更多次集成。每次集成都需要通過自動化的構建(包括編譯代碼、構建應用、部署程序以及自動化測試)來驗證,從而儘早儘快的發現集成中的錯誤。大量的團隊利用這樣的方式來更快的開發內聚的軟體。大大減少此過程中的集成問題。

具體的流程圖如下:

Paste_Image.png

持續集成強調開發人員提交了新代碼之後,立刻進行構建、(單元、自動化)測試。根據測試結果,我們可以確定新代碼和原有代碼能否正確地集成在一起。

首先,解釋下集成。我們所有項目的代碼都是託管在SVN伺服器上。每個項目都要有若干個單元測試,並有一個所謂集成測試。所謂集成測試就是把所有的單元測試跑一遍以及其它一些能自動完成的測試。只有在本地電腦上通過了集成測試的代碼才能上傳到SVN伺服器上,保證上傳的代碼沒有問題。所以,集成指集成測試。

再說持續。不言而喻,就是指長期的對項目代碼進行集成測試。既然是長期,那肯定是自動執行的,否則,人工執行則沒有保證,而且耗人力。對此,我們有一台伺服器,它會定期的從SVN中檢出代碼,並編譯,然後跑集成測試。每次集成測試結果都會記錄在案。完成這方面工作的就是下面要介紹的Jenkins軟體。當然,它的功能遠不止這些。在我們的項目中,執行這個工作的周期是1天。也就是,伺服器每1天都會準時地對SVN伺服器上的最新代碼自動進行一次集成測試。

Paste_Image.png

持續集成的特點

  • 它是一個自動化的周期性的集成測試過程,從檢出代碼、編譯構建、運行測試、結果記錄、測試統計等都是自動完成的,無需人工干預;
  • 需要有專門的集成伺服器來執行集成構建;
  • 需要有代碼託管工具支持;

持續集成的作用

  • 代碼庫存越是積壓,就越得不到生產檢驗,積壓越多,代碼間交叉感染的概率越大,下個發布(release)的複雜度和風險越高,持續集成可以保證團隊開發人員提交代碼的質量,減輕了軟體發布時的壓力;
  • 持續集成中的任何一個環節都是自動完成的,無需太多的人工干預,有利於減少重複過程以節省時間、費用和工作量;
  • 及早的發現代碼中的問題,及早解決,代碼越早推送(PUSH)出去,用戶能越早用到,快就是商業價值;

舉個例子,你家裝修廚房,其中一項是鋪地磚,邊角地磚要切割大小。如果一次全切割完再鋪上去,發現尺寸有誤的話浪費和返工時間就大了,不如切一塊鋪一塊。裝修廚房有很多部分,每個部分都有檢測手段,如地磚鋪完了要測試漏水與否,線路鋪完了要通電測試電路通順,水管裝好了也要測試冷水熱水。如果全部裝完了再測,出現問題可能會互相影響,比如電路不行可能要把地磚給挖開……。全部裝修完了,你去驗收,發現地磚顏色不合意,水池太小,灶台位置不對,返工嗎?所以不如沒完成一部分,你就去用一下試用驗收……這就是持續集成。在敏捷的思想裡面,不光強調上面的過程,還需要強調自動化這個過程。過技術手段自動化這三個工作。加快交付速度,自動化測試是一個重要的組成部分。

Jenkins

Jenkins介紹

Jenkins,原名Hudson,2011年改為現在的名字,它 是一個開源的實現持續集成的軟體工具。官方網站:http://jenkins-ci.org/。

Hudson是在2004年的夏天由Sun公司開發的(就是開發Java的那家),2005年2月開源並發布了第一個版本。Hudson發布的時候CruiseControl是CI界的老大哥,但是很快,在大約2007年的時候Hudson已經超越CruiseControl。2008年5月的JavaOne大會上,Hudson獲得了開發解決方案類的Dukes Choice獎項。從此,小弟翻身做大哥,Hudson成為CI的代名詞。

2009年6月,Oracle收購Sun。2010年9月,Oracle註冊了Hudson的商標,然後就沒有然後了。

mv -f Hudson Jenkins

Jenkins 能實施監控集成中存在的錯誤,提供詳細的日誌文件和提醒功能,還能用圖表的形式形象地展示項目構建的趨勢和穩定性。

Jenkins特點

  • 易安裝:僅僅一個 java -jar jenkins.war,從官網下載該文件後,直接運行,無需額外的安裝,更無需安裝資料庫;
  • 易配置:提供友好的GUI配置界面;
  • 變更支持:Jenkins能從代碼倉庫(git/Subversion/CVS)中獲取併產生代碼更新列表並輸出到編譯輸出信息中;
  • 支持永久鏈接:用戶是通過web來訪問Jenkins的,而這些web頁面的鏈接地址都是永久鏈接地址,因此,你可以在各種文檔中直接使用該鏈接;
  • 集成E-Mail/RSS/IM:當完成一次集成時,可通過這些工具實時告訴你集成結果(據我所知,構建一次集成需要花費一定時間,有了這個功能,你就可以在等待結果過程中,干別的事情);
  • JUnit/TestNG測試報告:也就是用以圖表等形式提供詳細的測試報表功能;
  • 支持分散式構建:Jenkins可以把集成構建等工作分發到多台計算機中完成;
  • 文件日誌信息:Jenkins會保存哪次集成構建產生了哪些jars文件,哪一次集成構建使用了哪個版本的jars文件等構建記錄;
  • 支持第三方插件:使得 Jenkins 變得越來越強大;

Jenkins的安裝

需要從官網下載Jenkins的文件,在本地安裝Java(jdk)的環境以後,直接執行以下語句進行安裝:

java -jar jenkins.war

注意上述操作,一定是在Java環境已經配置好的情況下進行。輸出如下:

Microsoft Windows [Version 10.0.10532](c) 2015 Microsoft Corporation. All rights reserved. C:Userserha>java -versionjava 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:Userserha>java -jar d:Jenkinsjenkins.warRunning from: D:Jenkinsjenkins.warwebroot: $user.home/.jenkinsJun 19, 2016 12:52:18 AM winstone.Logger logInternalINFO: Beginning extraction from war fileJun 19, 2016 12:52:29 AM org.eclipse.jetty.util.log.JavaUtilLog infoINFO: jetty-winstone-2.9Jun 19, 2016 12:52:33 AM org.eclipse.jetty.util.log.JavaUtilLog infoINFO: NO JSP Support for , did not find org.apache.jasper.servlet.JspServletJenkins home directory: C:Userserha.jenkins found at: $user.home/.jenkinsJun 19, 2016 12:52:35 AM org.eclipse.jetty.util.log.JavaUtilLog infoINFO: Started SelectChannelConnector@0.0.0.0:8080Jun 19, 2016 12:52:35 AM winstone.Logger logInternalINFO: Winstone Servlet Engine v2.0 running: controlPort=disabledJun 19, 2016 12:52:36 AM jenkins.InitReactorRunner$1 onAttainedINFO: Started initializationJun 19, 2016 12:53:11 AM jenkins.InitReactorRunner$1 onAttainedINFO: Listed all pluginsJun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttainedINFO: Prepared all pluginsJun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttainedINFO: Started all pluginsJun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttainedINFO: Augmented all extensionsJun 19, 2016 12:53:15 AM jenkins.InitReactorRunner$1 onAttainedINFO: Loaded all jobsJun 19, 2016 12:53:25 AM hudson.model.AsyncPeriodicWork$1 runINFO: Started Download metadataJun 19, 2016 12:53:26 AM org.jenkinsci.main.modules.sshd.SSHD startINFO: Started SSHD at port 10556Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Completed initializationJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Started initializationJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Listed all pluginsJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Prepared all pluginsJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Started all pluginsJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Augmented all extensionsJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Loaded all jobsJun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttainedINFO: Completed initializationJun 19, 2016 12:53:26 AM hudson.WebAppMain$3 runINFO: Jenkins is fully up and runningJun 19, 2016 12:53:32 AM hudson.model.UpdateSite updateDataINFO: Obtained the latest update center data file for UpdateSource defaultJun 19, 2016 12:53:33 AM hudson.model.DownloadService$Downloadable loadINFO: Obtained the updated data file for hudson.tasks.Maven.MavenInstallerJun 19, 2016 12:53:34 AM hudson.model.DownloadService$Downloadable loadINFO: Obtained the updated data file for hudson.tasks.Ant.AntInstallerJun 19, 2016 12:53:37 AM hudson.model.DownloadService$Downloadable loadINFO: Obtained the updated data file for hudson.tools.JDKInstallerJun 19, 2016 12:53:37 AM hudson.model.AsyncPeriodicWork$1 runINFO: Finished Download metadata. 12,471 ms

隨後訪問http://localhost:8080即可

最後,將Jenkins安裝成Windows服務啟動

在Jenkins的主頁中選擇 Manager Jenkins

接下來選擇 Install as Windows Servic

在Installation Directory中選擇jenkin的安裝路徑。這裡會默認產生,直接點擊Install就可以了。

隨後我們點擊Yes,然後可以看到Windows服務中添加了Jenkins的服務,並已經設置為自動和啟動狀態。

持續集成的實踐

創建Jenkins Job

Jenkins提供了四種類型的Job:

  1. 構建一個自由風格的軟體項目:這個是Jenkins的主要功能,可以構建一個你自己需要的項目。
  2. 構建一個maven項目:這是基於maven構建的項目,整個過程將會基於你的.pom文件進行構建,大大減輕構建的配置
  3. 構建一個多配置項目:這種項目適用多配置的項目,比如多個平台定製的構建,多個測試環境的部署構建等。
  4. 監控一個外部的任務:這種事允許你記錄和執行不在Jenkins中的Job,這些Job可以運行在遠程的主機上,Jenkins通過遠程自動構建,作為一個控制面板而存在。

運行Jenkins Job

運行Job只需要在頁面的左側選中已經列出的項目,進行操作就可以了。選擇立即構建,便可以進行自動構建的工作了。

定時構建 Job

目前有一個每日構建的概念。

Daily Build,每日構建。需要Jenkins在每日固定的時間進行代碼自動構建、集成和測試的工作。那麼需要定製執行時間。Jenkins的自動構建定製時間是遵循cron語法的。具體來說,每一行包括了5個用白空格或者Tab隔開的欄位,分別是:MINUTE HOUR DOM MONTH DOW。具體的格式我們參考下圖

欄位說明示例MINUTEMinutes within the hour (0–59)30HOURThe hour of the day (0–23)17DOMThe day of the month (1–31)1MONTHThe month (1–12)5DOWThe day of the week (0–7) where 0 and 7 are Sunday.5

然後每個格式,都可以由*-/,4種字元組成:

  • *代表所有可能的值
  • -代表整數之間的範圍
  • /代表指定的時間的間隔頻率
  • ,代表指定的列表範圍

命令的格式參考和示例

分鐘小時天月份星期執行的命令*161,10,20**python xxx每個月的1,10,20日的16:00執行 python xxx 命令格式:* 16 1,10,20 * **16**1-5python yyy每個周的周一到周五的16:00執行 python yyy 命令格式:* 16 * * 1-53017**1,5python zzz每個周的周一和周五的17:30執行 python zzz 命令格式:30 17 * * 1,5

ps: 注意時間是倫敦時間

至此,我們將會對Jenkins有一個非常范和初步的了解過程。

DevOps

1. 創建SVN倉庫 https://172.31.95.168/svn/DemoRepo/ ciuser / ciuser2. 從SVN倉庫簽出文件到CI Server3. 構建 build4. 部署 4.1 備份目標文件夾 若有ranzhi_bak 需要先刪除 rd /s /q c:xampphtdocs
anzhi_bak 把 htdoc的ranzhi改成 ranzhi_bak xcopy c:xampphtdocs
anzhi c:xampphtdocs
anzhi_bak /s /e /y rd /s /q c:xampphtdocs
anzhi 4.2 複製構建的版本到目標文件夾 把workspace的 ranzhi 複製到 htdocs下面 xcopy "%WORKSPACE%
anzhi" c:xampphtdocs
anzhi /s /e /y 4.3 恢復配置文件 複製 ranzhi_bakconfigmy.php 到 ranzhiconfigmy.php xcopy c:xampphtdocs
anzhi_bakconfigmy.php c:xampphtdocs
anzhiconfig /e5. 自動化測試 python D:GitCodingBWFTraining3.03_Seleniumcodesweekend2demo
anzhi_test_runner.py

最後

最後跟大家推薦一個學習資料分享群:672899761,

裡面大牛已經為我們整理好了許多的學習資料,有自動化,介面,性能等等的學習資料!

人生是一個逆水行舟的過程,不進則退,咱們一起加油吧!


推薦閱讀:

工具應用:使用LoadRunner實現Agileone的介面測試
第八篇:【自動化測試框架】| 斷言
如何從手工測試轉變為自動測試?
Selenium Page Object 自動化測試框架-script測試腳本設計
使用UI Automator實現Android UI的自動化測試

TAG:自動化測試 | DevOps | 持續集成CI |