1. 程式人生 > >淺談持續集成的理解以及實現持續集成,需要做什麽?

淺談持續集成的理解以及實現持續集成,需要做什麽?

我們 相關 模塊 檢查 gradle 最新版 https 動效 提高

一、持續集成是什麽?

持續集成是一種軟件開發的實踐,即團隊開發成員經常集成他們的工作,通常每個成員每天至少集成一次,也就意味著每天可能會發生多次集成。每次集成都通過自動化的構建(包括編譯,發布,自動化測試)來驗證,從而盡快地發現集成錯誤。許多團隊發現這個過程可以大大減少集成的問題,讓團隊能夠更快的開發內聚的軟件。

持續集成指的是,頻繁地(一天多次)將代碼集成到主幹,通過持續集成流程的進行自動化方式的構建,編譯和測試,提供可以部署發布的單元包

持續集成的目的,就是讓產品可以快速叠代,同時還能保持高質量。

它的核心措施是,代碼集成到主幹之前,必須通過自動化測試。

只要有一個測試用例失敗,就不能集成。

Martin Fowler說過,"持續集成並不能消除Bug,而是讓它們非常容易發現和改正。與持續集成相關的,還有兩個概念,分別是持續交付和持續部署。

二 持續集成的價值是什麽?

1、降低風險,由於持續集成不斷去構建,編譯和測試,可以很早期發現問題,所以修復的代價就少;

2、對系統健康持續檢查,減少發布風險帶來的問題;

3、減少重復性工作;

4、持續部署,提供可部署單元包;

5、持續交付可供使用的版本;

6、增強團隊信心;

三、持續集成流程

  持續集成一般的做法: 通過svn或其他工具拉取代碼->自動化構建->自動化編譯->自動化測試->自動化部署->自動化發布->郵件發送通知;

四、持續交付

  持續交付(Continuous delivery)指的是,頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審。如果評審通過,代碼就進入生產階段。

  持續交付可以看作持續集成的下一步。它強調的是,不管怎麽更新,軟件是隨時隨地可以交付的。

五、持續部署

  持續部署(continuous deployment)是持續交付的下一步,指的是代碼通過評審以後,自動部署到生產環境。

  持續部署的目標是,代碼在任何時刻都是可部署的,可以進入生產階段。

  持續部署的前提是能自動化完成測試、構建、部署等步驟。

測試是持續集成流程中重要的一環,也是區別去傳統的軟件開發流程中的一個重要的標誌。為什麽要有持續集成測試呢?

1、可以早點發現bug,這就是fix bug代價比較小

2、可以平滑產品,提高產品質量

3、可以讓團隊的每個人了解產品的質量狀態

4、每天都有持續集成測試的報告發布

5、開發者對自己提交的代碼測試情況有比較清晰的了解

6、可以有效地解決在QA人手不足的情況

7、盡可能地把測試自動化,讓持續集成測試系統去執行這些自動化測試的case


以前團隊工作方式

1、打包,等待maven編譯打包
2、發布測試環境,手動重啟服務
3、通知測試組測試(郵件、用嘴巴喊等等方式...)
4、一頓grep查Exception,修復BUG,然後重復1、2、3、4
5、到達特殊的日子時,配合運維部署團隊到測試環境手動copy最新版WAR包到生產環境,23點的一瞬間執行一個腳本,時刻盯住腳本運行結果,最後驗證
技術分享圖片

我們可以發現很多問題:
1,編譯打包的過程浪費開發資源,一次測試部署正常10到20分鐘,那出現問題的情況...

2,測試長時間怠工,資源利用不充分,處於一人幹活多人旁觀低績效狀態

3,研發與測試的溝通方式高成本低效率

4,BUG反饋方式低效

5,生產環境得不到有效的管控以及安全保障,人工浪費如果產品或者銷售想要給客戶演示測試環境,得到的結果可能是測試暫時不可用或者稍微等15到20分鐘,是否能計算出他們的心理陰影面積?

DevOps的中心思想在於提高產品各個階段的產出效率減少或者避開團隊間的溝通障礙,推動產品的快速叠代,“快速失敗”,從而實現持續交付、持續部署。而持續集成只是DevOps中的一個環節,下圖清晰描述了CI各個周期活動。
技術分享圖片
我們可以發現較多優點:
1、流程全自動化,減少重復性的手工操作
2、持續發布測試,時刻保持可發布的產品
3、團隊、高層對項目、產品的進展清晰可見,把控風險
4、資源效率有效利用,流動效率更快

因此,我們要做到持續集成,我們需要:

1、一套持續集成工具,大體可分為雲集成與本地化集成系統,雲集成比如Travis CI、cloudbees的雲集成等,本地化集成主要是開源Jenkins的搭建,如果需要大規模部署Jenkins且有預算可使用Jenkins商業版

2、自動化測試工具、良好的測試用例編寫

3、版本控制系統,git、gerrit推薦

4、構建、測試失敗反饋機制,郵件、自動化運維(AI...)、日誌收集分析系統

5、一套需求、產品、開發、測試、部署、運維共同使用的敏捷研發管理系統,市場上有阿裏雲效、騰訊的TAPD等


流程(A)

根據持續集成的設計,代碼從提交到生產,整個過程有以下幾步。

1 提交

流程的第一步,是開發者向代碼倉庫提交代碼。所有後面的步驟都始於本地代碼的一次提交(commit)。

2 測試(第一輪)

代碼倉庫對 commit 操作配置了鉤子(hook),只要提交代碼或者合並進主幹,就會跑自動化測試。

測試有好幾種。

單元測試:針對函數或模塊的測試
集成測試:針對整體產品的某個功能的測試,又稱功能測試
端對端測試:從用戶界面直達數據庫的全鏈路測試
第一輪至少要跑單元測試。

3 構建

通過第一輪測試,代碼就可以合並進主幹,就算可以交付了。

交付後,就先進行構建(build),再進入第二輪測試。所謂構建,指的是將源碼轉換為可以運行的實際代碼,比如安裝依賴,配置各種資源(樣式表、JS 腳本、圖片)等等。

常用的構建工具如下。

Jenkins
Travis
Codeship
Strider
Jenkins 和 Strider 是開源軟件,Travis 和 Codeship 對於開源項目可以免費使用。它們都會將構建和測試,在一次運行中執行完成。

4 測試(第二輪)

構建完成,就要進行第二輪測試。如果第一輪已經涵蓋了所有測試內容,第二輪可以省略,當然,這時構建步驟也要移到第一輪測試前面。

第二輪是全面測試,單元測試和集成測試都會跑,有條件的話,也要做端對端測試。所有測試以自動化為主,少數無法自動化的測試用例,就要人工跑。

需要強調的是,新版本的每一個更新點都必須測試到。如果測試的覆蓋率不高,進入後面的部署階段後,很可能會出現嚴重的問題。

5 部署

通過了第二輪測試,當前代碼就是一個可以直接部署的版本(artifact)。將這個版本的所有文件打包( tar filename.tar * )存檔,發到生產服務器。

生產服務器將打包文件,解包成本地的一個目錄,再將運行路徑的符號鏈接(symlink)指向這個目錄,然後重新啟動應用。這方面的部署工具有 Ansible,Chef,Puppet等。

6 回滾

一旦當前版本發生問題,就要回滾到上一個版本的構建結果。最簡單的做法就是修改一下符號鏈接,指向上一個版本的目錄。


流程(B)

實現持續集成,一般需要以下內容:

1. 具有版本控制功能的代碼庫

例如:SVN, Git。相信現在的項目沒有不對代碼進行版本管理的,所以這方面內容大家也應該非常熟悉。在這裏不再詳述。

2. 構建工具

在持續集成的過程中,需要對已存在的或者新提交的代碼進行編譯、打包等操作。這樣,就需要構建工具幫助構建一個編譯環境,並對代碼進行編譯、集成、打包等操作。而構建的方式越簡單越好,最好是一句命令就可以啟動構建。現在,各種語言都有自己的構建工具,例如Java中的Maven、Gradle、Ant,前端中的Grunt、Gulp等等,好好利用這些工具,就能幫你完成這部分工作。

3. 測試

測試是持續集成中重要的一環。代碼提交前,需要在本地運行單元測試,通過測試後再提交代碼。構建完成後,需要運行全部測試(單元測試,功能測試,端到端測試)以確保產品質量。如果有一個測試沒有通過,那麽這次提交的代碼不能進入主幹;或者這次構建的產物是一個失敗的構建品,不能用於發布。另外,由於持續集成依賴於這些測試去保證產品質量,所以測試的覆蓋率要盡可能高。測試覆蓋率不夠高(包含代碼覆蓋率和功能覆蓋率),就無法充分反映代碼的變動是否對系統帶來影響。而低覆蓋率的測試,壓根就無法保證產品質量。當上線的時候才發現問題就太遲了。

4. CI工具

CI工具的作用是將整個CI過程管理起來並自動化,結果可視化。部分工具還結合了CD(持續交付)的功能。現在已經有很多CI工具去滿足你不同的需求,例如Jenkins,專為Github開源項目提供的Travis,.Net用的CruiseControl.Net。他們各有特色,根據自己的需求選擇適合自己的工具即可。

好了,當集齊以上內容後。我們用一個例子來介紹一下一個典型流程是怎樣的。

例子背景描述

假設我們現在有一個產品P,以war包形式發布,由三個模塊module A, module B, module C構建而成。三個模塊的關系為:A和B為獨立模塊提供不同功能。C依賴A和B,然後構成產品P。我們使用了Git作為我們代碼庫的版本管理工具,用Java進行開發,maven作為我們的構建工具。在每個模塊裏,有我們基於JUnit寫的單元測試代碼。獨立於三個模塊外,有一塊代碼,也是基於JUnit寫的,作為我們的功能測試代碼(集成測試)。

集成代碼

當我們完成開發工作,需要提交代碼到代碼庫前,我們至少需要在本地跑一次單元測試,在保證全部測試通過後,才可以將代碼提交至我們的代碼庫Git上面去。例如,在我們上面描術的項目中,我對module A的代碼進行了修改,那我最起碼得在本地運行一次mvn test(執行Maven命令,test代表將會執行到maven default生命周期中從validate到test階段), 執行成功後,我才會將代碼commit and push到遠程Git庫上去。要做到這樣效果的話,就需要保證單元測試代碼也同步完成。而在極限編程中(XP),人們比較傾向於測試驅動開發(TDD, Test-driven Development)的實踐,通過提前寫好自動化的單元測試,保證好每一步功能開發的質量。

自動構建

通過CI工具,可以設置一個勾子,當代碼提交後觸發相應構建。例如,我們提交了module A的代碼時,Jenkins會掃描到我們這次提交,勾子觸發module A的構建。這個過程會做如下操作:

1,Jenkins調用Git插件,從Git庫上下載最新代碼;

2,Jenkins調用Maven插件,執行Maven命令(一般為mvn install,如果需要上傳至遠端Maven庫,也可以執行mvn deploy)對該模塊進行構建。經過編譯、通過單元測試後,便可以打包並安裝到本地Maven庫,以供其它依賴所用。這次構建成功,意味module A在模塊自身的單元測試範圍內是正常的。

3,因為module A是包含在產品P裏面,所以,也需要回歸一產品功能測試。由於module C依賴A,並構建成產品。所以在CI工具裏面,我們需要配置好在module A構建成功後,自動觸發module C的構建,經過類似步驟1、2這樣的構建後,最終會生成產品P的war包。而C的構建成功,只代表著通過了module C自身的單元測試,還不能對生成的war包進行功能測試。然後就要看我們下一步的工作--自動部署了。

自動部署

在功能測試之前,我們需要在CI工具裏配置一項任務,用於將最新構建出來的產品包部署到測試工環境中去。這個任務由產品構建任務成功而被觸發,而部署方式根據不同使用方式及不同的實際情況而多種多樣。例如通過腳本將新構建的war包上傳至指定位置,等待web容器自動掃描及部署。能或者產品有自己的安裝腳本,我們在任務中配置好運行安裝腳本,就可以自動將產品部署到指定的測試環境中去。

功能測試(集成測試)

當部署成功後,真正的功能測試就可以開始了。一般情況下,我們可以獨立出一塊代碼,基於JUnit編寫好我們的功能測試代碼(JUnit是作為測試的入口以及基本測試框架。如果你的需求比較復雜,那你完全可以將其它三方框架與JUnit集成使用)。功能測試過程和構建過程非常相似,均是依賴Git和Maven去完成:

1,Jenkins調用Git插件,從Git庫上下載最新代碼;
2,Jenkins調用Maven插件,執行Maven命令:mvn clean test。

區別在於功能測試階段,Maven只執行到default生成周期的test階段,不會執行後面的package和install。因為它只需要Maven幫忙運行測試代碼即可,它本身沒有什麽可以構建的。

P.S.

如果還需要更復雜的端到端測試的話,可能就需要準備更復雜的部署腳本,或者預先準備好整套端到端測試環境,後面只需要部署好war包即可。但無論怎樣,最終原來理還是相同。

交付

當新提交代碼後構建出來的產品包,通過了各種各樣殘酷的測試後,就說明這個包是穩定的,能達到基本交付條件的(前提是自動化測試的覆蓋率足夠高,當然,有一些極端的情況需要人工測試的另說)。那麽,我們就可以將這個包放到指定目錄作為交付品,供其它測試團隊獲取並進行進一步的測試,甚至供生產環境部署使用。

總結

持續集成作為極限編程中的一個實踐,現在已被很多公司使用。但是,使用持續集成,並不是說你得接受極限編程的全部東西。相反,它可以獨立開來,與其它實踐結合使用。
持續集成是敏捷開發中快速叠代的重要保證。
自動化測試是持續集成中重要一環,要真正用好持續集成,就要盡量提高自動化測試的覆蓋率。


以上兩種流程A,B都是一些公司常用的模式,大同小異,大家僅供參考。

引用

《持續集成是什麽?》- 阮一峰的網絡日誌。 ?

《持續集成是什麽?》- 阮一峰的網絡日誌。 ?

引用鏈接:https://www.jianshu.com/p/f92c4112a125

淺談持續集成的理解以及實現持續集成,需要做什麽?