在軟件開發(fā)的整個過程中掌逛,設計师逸、編碼、測試固然重要豆混,但是也不能忽略了“最后一公里”篓像,即部署和發(fā)布的過程。我們的目標是快速皿伺、可靠地發(fā)布軟件员辩,軟件真正產生價值是在交付給用戶的時候,傳統(tǒng)鸵鸥、手工的部署方式不僅效率低奠滑,而且過程中容易出錯丹皱。持續(xù)交付可以幫我們解決這一問題。持續(xù)交付倡導的是一個自動化的構建宋税、部署摊崭、測試和發(fā)布的流水線,整個過程都需要規(guī)范管理起來杰赛。
1 配置管理
1.1 使用版本控制
1)對所有內容進行版本控制 所有軟件相關的產物都需要進行版本控制呢簸,不僅是源代碼,還應當包括所有測試代碼乏屯、文檔根时、數(shù)據(jù)庫腳本、配置信息等瓶珊,否則啸箫,本書提到的提高軟件交付質效的實踐:持續(xù)集成、自動化測試伞芹、一鍵式部署都是無法實踐的忘苛。
2)頻繁提交代碼到主干 提交地越頻繁,合并的工作量越小唱较,發(fā)生的沖突越容易解決扎唾,越容易進行評估和測試,出錯的風險也越低南缓。
3)使用意義明顯的提交注釋 為了方便對代碼進行回溯胸遇,提高代碼的可讀性,每次提交時都應該有準確的注釋來說明這段代碼是為了新增某個功能或者解決某個問題的汉形。還有一個建議是纸镊,每次提交應該只覆蓋一個功能或者只解決一個問題,通常有的開發(fā)同學在一次提交中包含了兩個以上的功能概疆,但是注釋卻只說明了其中一個的作用逗威,這樣也是不合理的。
1.2 依賴管理 包括外部庫文件和組件
1.3 軟件配置管理 確保配置項在多個應用岔冀、多個組件以及多項技術中的管理保持一致性凯旭。每個人都應該能夠非常容易地看到當前軟件的某個特定版本部署到各種環(huán)境上的具體配置信息,同時使用冒煙測試來診斷依賴于配置項的相關功能是否都能正常工作使套。
1.4 環(huán)境管理 通過一個全自動的過程來創(chuàng)建環(huán)境罐呼,同時,環(huán)境的變更過程也需要進行管理侦高。
2 持續(xù)集成
沒有持續(xù)集成的話嫉柴,直到驗證前,應用程序可能一直都處于無法工作的狀態(tài)奉呛,而有了持續(xù)集成之后差凹,應用程序就應該是時刻處于可工作狀態(tài)的了期奔。持續(xù)集成創(chuàng)建了一個快速的反饋環(huán),使你能盡早地發(fā)現(xiàn)問題危尿,而發(fā)現(xiàn)問題越早,修復成本越低馁痴。從而確保我們作為一個團隊所開發(fā)的軟件是可以正常工作的谊娇。它主要關注于代碼是否可以編譯成功以及是否可以通過單元測試和驗收測試。持續(xù)集成系統(tǒng)的輸出通常作為手工測試流程和后續(xù)發(fā)布流程的輸入罗晕。持續(xù)集成是一種實踐济欢,而不是一個工具。
2.1 準備工作
在開始做持續(xù)集成之前小渊,需要做三件事:版本控制法褥、自動化構建、團隊共識酬屉。
版本控制:與項目相關的所有內容都必須提交到一個版本控制庫中半等,包括產品代碼、測試代碼呐萨、數(shù)據(jù)庫腳本杀饵、構建與部署腳本,以及所有用于創(chuàng)建谬擦、安裝切距、運行和測試該應用程序的東西。
自動化構建:人和計算機都能通過命令行自動執(zhí)行應用的構建惨远、測試以及部署過程谜悟。
團隊共識:團隊成員都接收以小步增量的方式頻繁地將修改后的代碼提交到主干碟摆,并一致認同“修復破壞應用程序的任意修改是最高優(yōu)先級的任務”的準則氓奈。
2.2 前提條件
持續(xù)集成的前提條件:頻繁提交、創(chuàng)建全面的自動化測試套件徐勃、保持較短的構建和測試過程羡儿、管理開發(fā)工作區(qū)礼患。
2.3 使用持續(xù)集成軟件
持續(xù)集成工作流以規(guī)定的時間間隔對版本控制系統(tǒng)進行輪詢,一旦發(fā)現(xiàn)版本庫有任何變化掠归,它就會將項目的一個副本簽出到服務器或構件代理機器的某個目錄中缅叠,然后運行你指定的命令。典型情況下虏冻,這些命令會構件你的應用程序肤粱,并運行相關的自動化測試。最后提供展現(xiàn)這個流程運行結果的視圖厨相,通知你構建和測試成功與否领曼,讓你可以找到測試報告鸥鹉,拿到生成的安裝文件等。
2.4 必不可少的實踐
構建失敗之后不要提交新代碼庶骄、
提交前在本地運行所有的提交測試毁渗,或者讓持續(xù)集成服務器完成此事
等提交測試通過后再繼續(xù)工作
回家之前,構建必須處于成功狀態(tài)
時刻準備著回滾到前一個版本
在回滾之前要規(guī)定一個修復時間
不要將失敗的測試注釋掉
為自己導致的問題負責
測試驅動的開發(fā)
2.5 推薦的實踐
極限編程開發(fā)實踐
若違背架構原則单刁,就讓構建失敗
若測試運行變慢灸异,就讓構建失敗
若有編譯警告或代碼風格的問題,就讓測試失敗
2.6 分布式團隊 使用共享的版本控制系統(tǒng)和持續(xù)集成系統(tǒng)
2.7 分布式版本控制系統(tǒng)
3 測試策略的實現(xiàn)
測試策略的設計主要是識別和評估項目風險的優(yōu)先級羔飞,以及決定采用哪些行動來緩解風險的一個過程肺樟。好的測試策略會帶來很多積極作用。測試會建立我們的信心逻淌,使我們相信軟件可按預期正常運行么伯。也就是說,軟件的缺陷較少卡儒,技術支持所需的成本較低田柔,客戶認可度較高。測試還為開發(fā)流程提供了一種約束機制朋贬,鼓勵團隊采用一些好的開發(fā)實踐凯楔。一個全面的自動化測試套件甚至可以提供最完整和最及時的應用軟件說明文檔,這個文檔不僅是說明系統(tǒng)應該如何運行的需求規(guī)范锦募,還能證明這個軟件系統(tǒng)的確是按照需求來運行的摆屯。
3.1 測試的分類
1)業(yè)務導向且支持開發(fā)過程的測試:功能測試/驗收測試 驗收測試確保用戶故事的驗收條件得到滿足。系統(tǒng)的驗收測試應該運行在類生產環(huán)境中糠亩。自動化驗收測試有很大價值:加快反饋速度虐骑,讓測試人員集中精力做探索測試和高價值的活動,作為回歸測試的一部分赎线。一旦對同一個測試重復做過多次手工操作廷没,并且你確信不會花太多時間來維護這個測試時,就要把它自動化垂寥。需要寫的最重要的自動化測試是那些對Happy Path的測試颠黎。每個需求或用戶故事都應該有對Happy Path的自動化驗收測試,而且應至少有一個滞项。這些測試應該被每位開發(fā)人員當做冒煙測試來使用狭归,從而能夠為“是否破壞了已有的功能”提供快速反饋。當你有時間寫更多的自動化測試時文判,很難在Happy Path和Sad Path之間進行選擇过椎。如果你的應用程序比較穩(wěn)定,那么Alternate Path應該是你的首選戏仓,因為它們是用戶所定義的場景疚宇。如果你的應用有較多的缺陷并且經常崩潰的話亡鼠,那么戰(zhàn)略性地應用對Sad Path的測試會幫助你識別那些問題域并修復它們。而且自動化可以保證應用程序保持在穩(wěn)定狀態(tài)敷待。
2)技術導向且支持開發(fā)過程的測試:單元測試间涵、組件測試和部署測試
3)業(yè)務導向且評價項目的測試:演示、易用性測試讼撒、探索性測試
4)技術導向且評價項目的測試:非功能驗收測試浑厚,包括容量測試、安全性測試等
3.2 顯示中的情況與應對策略
1)新項目 新項目通過建立一些相對簡單的基本規(guī)則根盒,并創(chuàng)建一些相對簡單的測試基礎設施,就可以很順利地開始你的持續(xù)集成之旅物蝙。相對于項目開發(fā)幾個迭代后再寫驗收測試來說炎滞,在項目開始就采用這樣的流程是比較容易的。從一開始就使用了自動化驗收測試的代碼庫一般總是有更好的封裝诬乞、更清晰的表達册赛、更清楚的職責分離和更多的代碼重用。
2)項目進行中 引入自動化測試最好的方式是選擇應用程序中那些最常見震嫉、最重要且高價值的用例為起點森瘪。這就需要與客戶溝通,以便清楚地識別真正的業(yè)務價值是什么票堵,然后使用測試來做回歸扼睬,以防止功能被破壞°彩疲基于這些溝通窗宇,把Happy Path的測試自動化,用于覆蓋高價值的場景特纤。另外军俊,讓這些測試盡可能覆蓋更多的選項也是有用的,即讓測試覆蓋的范圍稍稍寬于通常的用戶故事級別的驗收測試捧存,比如盡可能多填一些字段粪躬,多單擊一些按鈕來滿足測試需求。
3)遺留系統(tǒng) 針對高價值的功能創(chuàng)建自動化測試昔穴,并將這些覆蓋核心功能的測試作為冒煙測試镰官。把自動化測試分成不同的層級。第一級應該是那些非常簡單且運行較快的測試傻咖,第二級是測試某個具體用戶故事的關鍵功能朋魔。針對用戶故事的Alternate Path和異常條件也可以寫驗收測試。
4)集成測試 假如你的應用程序需要通過一系列不同的協(xié)議與各種外部系統(tǒng)進行交互卿操,或者它由很多松散耦合的模塊組成警检,而模塊之間還有很復雜的交互操作的話孙援,集成測試就非常重要了。盡可能模擬異常情況扇雕,并用它們來測試你的應用程序拓售,以便確保應用可以處理這類情況。
3.3 流程
迭代開始時組織相關人員一起編寫驗收條件镶奉,然后再寫代碼讓這些驗收條件變成可執(zhí)行的測試础淤。與開發(fā)完用戶故事之后再溝通相比,這會大大減少開發(fā)人員和測試人員之間的反饋循環(huán)哨苛,有助于減少遺漏功能的幾率鸽凶,并有助于減少缺陷。
4 部署流水線
若從開發(fā)直到在類生產環(huán)境上部署之間需要很長時間建峭,就會導致軟件無法部署玻侥,而若開發(fā)團隊與測試、運維人員之間的反饋周期太長亿蒸,就會使軟件存在很多缺陷〈绽迹現(xiàn)在,我們通常能通過一鍵式方式把軟件的某個版本部署好边锁,甚至可以將其一鍵式部署到生產環(huán)境中姑食,這樣就建立了一個非常有效的反饋環(huán)——由于很容易將應用程序部署到測試環(huán)境中,所以團隊可以同時得到軟件功能和部署流程兩個方面的快速反饋茅坛。
4.1 什么是部署流水線
從某種抽象層次上講音半,部署流水線是指軟件從版本控制庫到用戶手中這一過程的自動化表現(xiàn)形式。流水線的輸入是版本控制中的某個具體版本灰蛙,每次變更都會生成一次構建祟剔,這個構建會經過一系列的測試階段,每個測試階段都從不同的角度評估這個構建版本摩梧,且和持續(xù)集成一樣物延,它的起點是向版本控制庫的每一次提交。隨著某個構建逐步通過每個測試階段仅父,我們對它的信心也在不斷提高叛薯。在每個階段上花在環(huán)境方面的資源也在不斷增加,即越往后的階段笙纤,其環(huán)境與生產環(huán)境越相似耗溜,其目的就是在這個過程中盡早發(fā)現(xiàn)那些不滿足發(fā)布條件的構建版本,并盡快將失敗根源反饋給團隊省容。一般來說抖拴,只要某個構建使無論是這一流程中的哪個階段失敗了,它都不會進入下一個階段。
使用這種模式的話阿宅,有些非常重要的積極影響候衍。首先,它可以有效地阻止那些沒有經過充分測試或不滿足功能需求的版本進入生產環(huán)境洒放,也能避免回歸缺陷蛉鹿,尤其是對于那些需要緊急修復并部署到生產環(huán)境的情況。其次往湿,當部署和產品發(fā)布都被自動化之后妖异,這些活動就變成快速、可重復且可靠的了领追。
最基本的部署流水線 這個流程的起點是開發(fā)人員向版本控制庫提交代碼他膳。第一個階段會編譯代碼,運行單元測試绒窑,執(zhí)行代碼分析矩乐,創(chuàng)建軟件二進制包。第二個階段通常由運行時間較長的自動化驗收測試組成回论。
部署流水線的組成:
提交階段是從技術角度上斷言整個系統(tǒng)是可以工作的。這個階段會進行編譯分歇,運行一套自動化測試(主要是單元級別的測試)傀蓉,并進行代碼分析
自動化驗收測試階段是從功能和非功能角度上斷言整個系統(tǒng)是可以工作的,即從系統(tǒng)行為上看职抡,它滿足用戶的需要并且符合客戶的需求規(guī)范葬燎。
手工測試階段用于斷言系統(tǒng)是可用的,滿足了它的系統(tǒng)要求缚甩,試圖發(fā)現(xiàn)那些自動化測試未能捕獲的缺陷谱净,并驗證系統(tǒng)是否為用戶提供了價值。這一階段通常包括探索性測試擅威、集成環(huán)境上的測試以及用戶驗收測試壕探。
發(fā)布階段旨在將軟件交付給用戶,既可能是以套裝軟件的形式郊丛,也可能是直接將其部署到生產環(huán)境李请,或試運行環(huán)境。
4.2 部署流水線的相關實踐
1)只生成一次二進制包 這一原則的一個必然結果是能夠在任意環(huán)境上部署這些二進制包厉熟,這樣會引導你正確地管理配置信息导盅,促使你使用結構良好的構建系統(tǒng)
2)對不同環(huán)境采用同一部署方式 如果對于不同的環(huán)境,其部署腳本也不相同的話揍瑟,你就無法知道某個測試過的腳本是否在上線部署時還能正常工作白翻。相反,如果使用同一個腳本在所有的環(huán)境上進行部署绢片,那么當在某個環(huán)境上部署失敗時滤馍,就可以確定其原因一定來自以下三個方面:與該環(huán)境相關的配置文件中岛琼,某項配置有問題;基礎設施或應用程序所依賴的某個服務有問題纪蜒;環(huán)境本身的配置有問題
3)對部署進行冒煙測試 如果應用程序不能運行衷恭,這個冒煙測試應該能夠告訴你一些最基本的診斷提示,比如應用程序無法運行是否是因為其依賴的外部服務無法正常工作
4)向生產環(huán)境的副本中部署 為了對系統(tǒng)上線充滿信心纯续,你要盡可能在與生產環(huán)境相似的環(huán)境中進行測試和持續(xù)集成随珠。你要確保:基礎設施是相同的,比如網(wǎng)絡拓撲和防火墻的配置等猬错;操作系統(tǒng)的配置(包括補丁版本)都是相同的窗看;應用程序所用的軟件棧是相同的;應用程序的數(shù)據(jù)處于一個已知且有效的狀態(tài)
5)每次變更都要立即在流水線中傳遞
6)只要有環(huán)節(jié)失敗倦炒,就停止整個流水線 每次提交代碼到版本控制系統(tǒng)中后显沈,都能夠構建成功并通過所有的測試。假如在某個環(huán)境上的某次部署失敗了逢唤,整個團隊就要對這次失敗負責拉讯,應該停下手頭的工作,把它修復后再做其他事情鳖藕。
4.3 提交階段 每次提交都生成部署流水線的一個新實例魔慷。如果提交階段的測試通過了,這個版本就被視為一個候選發(fā)布版本著恩。一般來說院尔,提交階段包含以下步驟:編譯代碼、運行一套提交測試喉誊、為后續(xù)階段創(chuàng)建二進制包邀摆、執(zhí)行代碼分析來檢查代碼的健康狀況、為后續(xù)階段做準備工作伍茄,比如準備一下后續(xù)測試所用的數(shù)據(jù)庫栋盹。如果前面這些任務都成功了,提交階段的最后一步就是生成二進制包幻林,用于后續(xù)階段的部署贞盯。
4.4 自動化驗收測試之門 全面的提交測試套件對于發(fā)現(xiàn)許多種錯誤來說,是非常優(yōu)秀的試金石沪饺。然而躏敢,有很多類型的錯誤是它無法捕獲的。如果沒有在類生產環(huán)境上執(zhí)行驗收測試整葡,我們就根本不知道該應用程序是否符合了客戶規(guī)范件余,也不知道它在現(xiàn)實世界中是否能夠部署并運行。如果想在這些方面得到及時反饋的話,就必須在持續(xù)集成流程中引入更多測試并不斷對系統(tǒng)各方面進行演練啼器。驗收測試階段的目標是斷言應用城促交付了客戶期望的價值旬渠,并滿足了驗收條件。
4.5 后續(xù)的測試階段
1)手工測試 在迭代開發(fā)過程中端壳,驗收測試之后一定會有一些手工的探索性測試告丢、易用性測試和演示。自動化驗收測試使測試人員節(jié)省出更多的時間做那些高價值的活動损谦,而不是測試腳本的人力執(zhí)行器
2)非功能測試 每個系統(tǒng)都有很多非功能需求岖免。比如,幾乎每個系統(tǒng)都有容量和安全性方面的要求照捡,或者必須遵守服務水平協(xié)議等颅湘。通常應該用某些自動化測試衡量應用程序是否滿足這些需求。
4.6 發(fā)布準備 每次向生產環(huán)境發(fā)布時都有業(yè)務風險栗精。緩解這類風險非常簡單闯参,只要把這個發(fā)布環(huán)節(jié)視為部署流水線的一個自然結果就行。
1)讓參與項目交付過程的人共同創(chuàng)建并維護一個發(fā)布計劃
2)自動部署與發(fā)布
3)在類生產環(huán)境中經常做發(fā)布流程演練
4)變更的撤銷
4.7 實現(xiàn)一個部署流水線
1)對價值流進行建模并創(chuàng)建簡單的可工作框架
2)構建和部署過程的自動化
3)自動化單元測試和代碼分析
4)自動化驗收測試
4.8 度量 對軟件交付過程來說悲立,最重要的全局度量指標就是周期時間鹿寨。它指的是從決定要做某個特性開始,直到把這個特性交付給用戶的這段時間薪夕。一定要創(chuàng)建一個聚合所有信息释移,并且人腦可以直接通過其無比的模式匹配能力識別流程或代碼庫中問題的可視化報告。部署流水線可以幫助消除流程中的低效環(huán)節(jié)寥殖,這樣可讓反饋周期更短并更有效。
5 構建與部署的腳本化
5.1 原則與實踐
1)為部署流水線的每個階段創(chuàng)建腳本‘
2)使用恰當?shù)募夹g部署應用程序
3)使用同樣的腳本向所有環(huán)境部署
4)使用操作系統(tǒng)自帶的包管理工具
5)確保部署流程是冪等的
6)部署系統(tǒng)的增量式演進
5.2 部署腳本化
1)多層的部署和測試 底層是操作系統(tǒng)涩蜘,然后是中間件和應用程序所依賴的其他軟件嚼贡。一旦這兩層準備好了,就需要對其進行一些具體配置同诫,為應用程序的部署做準備粤策。只有這些都做完了,我們才能開始部署軟件误窖,這包括可部署的二進制包叮盘、所需要的服務或守護進程,以及其相關配置霹俺。
2)測試環(huán)境配置 任何一個層級的部署出錯柔吼,都可能導致應用程序無法正常運行。所以丙唧,當準備每一層級時愈魏,都要對其進行測試。如果發(fā)現(xiàn)問題,就要讓環(huán)境配置流程快速失敗培漏,而測試結果也應該給出清晰指示溪厘,指出錯誤出現(xiàn)在哪里。
5.3 小貼士
1)總是使用相對路徑
2)消除手工步驟
3)從二進制包到版本控制庫的內建可追溯性
4)不要把二進制包作為構建的一部分放到版本控制庫中
5)test不應該讓構建失敗
6)用集成冒煙測試來限制應用程序
6 提交階段
當某人向版本控制庫的主干上提交了一次變更后牌柄,持續(xù)集成服務器會發(fā)現(xiàn)這次變更畸悬,并將代碼簽出,執(zhí)行一系列的任務珊佣,包括:
編譯(如果需要的話)蹋宦,并在集成后的源代碼上運行提交測試;
創(chuàng)建能部署在所有環(huán)境中的二進制包(如果使用需要編譯的語言彩扔,則包括編譯和組裝)妆档;
執(zhí)行必要的分析,檢查代碼庫的健康狀況虫碉;
創(chuàng)建部署流水線的后續(xù)階段需要使用的其他產物(比如數(shù)據(jù)庫遷移或測試數(shù)據(jù))贾惦。
6.1 提交階段的原則和實踐
1)提供快速有用的反饋
提交測試的失敗通常是由以下三個原因引起的:由于語法錯誤導致編譯失敗、由于語義錯誤導致一個或多個測試失敗敦捧、由于應用程序的配置或環(huán)境方面(包括操作系統(tǒng)本身)的問題引起须板。
引入錯誤后,越早發(fā)現(xiàn)它兢卵,就越容易修復它习瑰。因為引入錯誤的人對其上下文的印象還比較深,而且找到錯誤原因的方法也比較簡單秽荤。
2)何時令提交階段失敗
除了成功和失敗兩種狀態(tài)甜奄,提交階段結束后,應該提供更豐富的信息窃款,比如關于代碼覆蓋率和其它度量項的一些圖表课兄。
3)精心對待提交階段
隨著項目的進行,要不斷努力地改進提交階段腳本的質量晨继、設計和性能烟阐。一個高效、快速紊扬、可靠的提交階段是提高團隊生產效率的關鍵蜒茄,所以只要花點兒時間和精力在這上面,讓它處于良好的工作狀態(tài)餐屎,就會很快收回這些投入成本檀葛。
4)讓開發(fā)人員也擁有所有權
如果必要的話,即使是很普通的變更(比如增加新的庫文件和配置文件等)也都應該由一起工作的開發(fā)人員和運維人員來執(zhí)行腹缩。這類活動不應該由構建專家完成驻谆,除非是在項目初期團隊剛開始建立構建腳本時卵凑。
5)在超大項目團隊中制定一個構建負責人
如果構建失敗,構建負責人要知會當事人并禮貌地(如果時間太長的話胜臊,不禮貌也沒問題)提醒他們?yōu)閳F隊修復失敗的構建勺卢,否則就將他們的修改回滾。這個角色能起作用的另一種情況是象对,當團隊剛開始接觸持續(xù)集成時黑忱。在這樣的團隊中,構建紀律還沒有建立起來勒魔,有個人能不斷提醒大家甫煞,會令事情走向正軌。
6.2 提交階段的結果
1)交付團隊的某個人提交了一次修改
2)持續(xù)集成服務器運行提交階段
3)成功結束后冠绢,二進制包和所有報告和元數(shù)據(jù)都被保存到制品庫中
4)持續(xù)集成服務器從制品庫中獲取提交階段生成的二進制包抚吠,并將其部署到一個類生產測試環(huán)境中
5)持續(xù)集成服務器使用提交階段生成的二進制包執(zhí)行驗收測試
6)成功完成后,該候選發(fā)布版本被標記為“已成功通過驗收測試”
7)測試人員拿到已通過驗收測試的所有構建的列表弟胀,并通過單擊一個按鈕將其部署到手工測試環(huán)境中
8)測試人員執(zhí)行手工測試
9)一旦手工測試也通過了楷力,測試人員會更新這個候選發(fā)布版本的狀態(tài),指示它已經通過手工測試了
10)持續(xù)集成服務器從制品庫中拿到通過驗收測試(根據(jù)部署流水線的配置孵户,也可能是手工測試)的最新候選發(fā)布版本萧朝,將其部署到生產測試環(huán)境
11)對這個候選發(fā)布版本進行容量測試
12)如果成功了,將這個候選版本的狀態(tài)更新為“已通過容量測試”
13)如果部署流水線中還有后續(xù)階段的話夏哭,一直重復這種模式
14)一旦這個候選發(fā)布版本通過了所有相關階段检柬,把它標記為“可以發(fā)布”,并且任何被授權的人都能將其發(fā)布竖配,通常是由質量保證人員和運維人員共同批準
15)一旦發(fā)布以后何址,將其標記為“已發(fā)布”
6.3 提交測試套件的原則與實踐
1)避免用戶界面
2)使用依賴注入
3)避免使用數(shù)據(jù)庫
4)在單元測試中避免異步
5)使用測試替身
6)最少化測試中的狀態(tài)
7)時間的偽裝
8)蠻力
7 自動化驗收測試
一旦正確實施自動化驗收測試,你就是在測試應用程序的業(yè)務驗收條件进胯,即驗證應用程序是否為用戶提供了有價值的功能头朱。作為一個整體,驗收測試套件既驗證了應用程序是否交付了用戶期望的業(yè)務價值龄减,又能防止回歸問題或缺陷破壞了應用程序的原有功能。
7.1 為什么驗收測試是至關重要的
單元測試和組件測試都不能以實際運行來證明軟件能為客戶提供他們所期望的業(yè)務價值
應用程序出現(xiàn)的緊急行為以及由架構問題或環(huán)境及配置問題造成的其他類型的bug很難通過手工測試發(fā)現(xiàn)
手工驗收測試的成本昂貴
原計劃預留的時間并不足以修復手工驗收測試中發(fā)現(xiàn)的缺陷
1)如何創(chuàng)建可維護的驗收測試套件 關注驗收條件班眯、對驗收測試進行分層(驗收條件希停、測試實現(xiàn)層、應用程序驅動層)署隘、使用狀態(tài)管理宠能、超時處理和測試替身的方式
2)GUI上的測試的問題:界面變化速度很快、場景的設置復雜磁餐、拿到測試結果很難违崇,以及不可測的GUI技術
7.2 創(chuàng)建驗收測試
1)分析人員和測試人員的角色
分析人員與客戶一起工作阿弃,識別需求,并排定優(yōu)先級羞延;分析人員與開發(fā)一起工作渣淳,確保開發(fā)人員能從用戶的角度很好地理解應用程序,確保那些用戶故事真正交付了它們應有的業(yè)務價值伴箩;分析人員與測試人員一起工作入愧,確保驗收條件已被合理闡明,并且開發(fā)出來的功能滿足這些驗收條件嗤谚,交付了期望的價值棺蛛。
測試人員的角色就是確保交付團隊的每個人(包括客戶)都了解并理解正在開發(fā)的軟件的當前質量和生產準備情況。為了做到這一點巩步,他們要與客戶和業(yè)務分析師一起工作旁赊,為用戶故事或需求定義驗收條件,與開發(fā)人員一起工作椅野,編寫自動化驗收測試终畅,他們還要執(zhí)行手工測試活動惰赋,比如探索性測試罕伯、手工驗收測試和演示沸版。
2)迭代開發(fā)項目中的分析工作
在迭代交付方法中桥状,分析人員會花大量時間定義驗收條件赌蔑。最開始更扁,分析人員會與測試人員和客戶緊密合作前塔,定義驗收條件挪蹭。在這個階段鲸湃,鼓勵分析人員和測試人員協(xié)作不僅對雙方都有利赠涮,并且能使流程更加有效。分析師會有所收獲暗挑,因為測試人員會根據(jù)他們的經驗提供一些信息笋除,比如哪些事情可能或應該用戶定義用具故事是否做完了。而測試人員在測試這些需求之前炸裆,就能獲得對這些需求本質的理解垃它。
一旦驗收條件定義完成,在開始實現(xiàn)這個需求之前烹看,分析人員国拇、測試人員應該和將要實現(xiàn)這個需求的開發(fā)人員碰一下頭兒。確保實現(xiàn)需求的每一方都能很好地理解需求以及他們在交付過程中的角色惯殊。這種方法可以避免分析人員創(chuàng)建那種難以實現(xiàn)或測試的象牙塔式需求酱吝,也避免測試人員由于自己對系統(tǒng)的錯誤理解,把正常的系統(tǒng)行為當成缺陷寫在報告里土思,還可以避免開發(fā)人員實現(xiàn)一些不相干的务热、客戶并不想要的功能忆嗜。
在實現(xiàn)需求時,如果開發(fā)人員發(fā)現(xiàn)對某個地方不是非常理解(或者發(fā)現(xiàn)了一個問題崎岂,或找到更高效的方法可以解決需求問題)捆毫,就可以去問分析人員。
當開發(fā)人員認為工作已經完成時该镣,通常是指所有相關的單元測試和組件測試都已經通過了冻璃,驗收測試也全部實現(xiàn),并證明系統(tǒng)滿足需求损合。此時省艳,他們就可以向分析人員、測試人員和客戶進行演示嫁审。
3)將驗收條件變成可執(zhí)行的規(guī)格說明書
拿這些寫好的驗收條件直接在應用程序之上運行跋炕,來驗證它是否滿足規(guī)格說明;這種可執(zhí)行的規(guī)格說明不會過時律适;它們驗證應用程序的確向用戶交付了價值辐烂。這種創(chuàng)建可執(zhí)行規(guī)格說明的方法是行為驅動設計的本質
7.3 實現(xiàn)驗收測試
1)驗收測試中的狀態(tài)
建立一個已知的起始狀態(tài),并讓測試對復雜狀態(tài)的依賴最小化
2)過程邊界捂贿、封裝和測試
3)管理異步與超時問題
4)使用測試替身對象
7.4 驗收測試階段
提交測試一旦成功完成纠修,就應該開始在通過提交測試的軟件版本上運行驗收測試套件。令驗收測試失敗的構建版本不能被部署厂僧。
1)確保驗收測試一直處于通過狀態(tài)
整個交付團隊應該為保持驗收測試通過負責扣草。當某個驗收測試失敗時,團隊要停下來立即評估問題颜屠。至關重要的是辰妙,為了保證驗收測試一直可以工作,并使開發(fā)人員關注應用程序的行為甫窟,要讓整個交付團隊對驗收測試擁有所有權和維護權權密浑,而不僅僅是測試團隊的事情。盡早修復失敗的驗收測試是至關重要的粗井,否則測試套件就沒有貢獻真正的價值尔破。其中最重要的一步就是讓失敗可視化。
2)部署測試
在和生產環(huán)境一直的測試環(huán)境中運行驗收測試浇衬,用于斷言我們配置的環(huán)境與期望一致懒构,并且系統(tǒng)中各種組件中的通信也是正常的。
7.5 驗收測試的性能
引入問題的時間點和發(fā)現(xiàn)問題的時間點之間的時間越長径玖,發(fā)現(xiàn)問題根源并修復它的難度越大。有一系列的技術能用來縮短從驗收測試階段得到運行結果的時間颤介,從而提高團隊的整體效率梳星。
1)重構通用任務
2)共享昂貴資源
3)并行測試
4)使用計算網(wǎng)絡
7.6 小結
采納驗收測試條件驅動的測試代表了更先進的理念赞赖,因為它:
為系統(tǒng)進行大范圍修改提供了一個保護網(wǎng)
通過全面的自動回歸測試極大地提高了質量
無論什么時候出現(xiàn)缺陷,都能提供快速冤灾、可靠的反饋前域,以便可以立即修復
讓測試人員有更多的時間和精力去思考測試策略、開發(fā)可執(zhí)行的規(guī)格說明韵吨,以及執(zhí)行探索性測試和易用性測試
縮短周期時間匿垄,使持續(xù)部署成為可能
8 非功能需求的測試
性能是對處理單一事務所花時間的一種度量,既可以單獨衡量归粉,也可以在一定的負載下衡量椿疗。吞吐量是系統(tǒng)在一定時間內處理事務的數(shù)量,通常它受限于系統(tǒng)中的某個瓶頸糠悼。在一定的工作負載下届榄,當每個單獨請求的響應時間維持在可接受的范圍內時,該系統(tǒng)所能承擔的最大吞吐量被稱為它的容量倔喂。
在項目開始就識別出哪些是重要的非功能需求铝条,這一點至關重要。然后席噩,團隊就要找到某種方法來衡量這些非功能需求班缰,并在交付時間表中考慮什么時候做這些測試,把它們放在部署流水線的哪個位置悼枢。
8.1 非功能需求的管理
在交付過程的后期才發(fā)現(xiàn)應用程序因基本的安全漏洞或很差的性能而導致項目無法驗收埠忘,這種常見現(xiàn)象會導致項目推遲交付甚至被取消。在項目一開始萧芙,交付過程中的每個人(包括開發(fā)人員给梅、運維人員、測試人員和客戶)都需要思考一下應用程序的非功能需求双揪,以及它們對系統(tǒng)架構动羽、項目時間表、測試策略和總成本的影響渔期。
1)創(chuàng)建一些具體任務來管理非功能需求 以用戶故事的方式定量描述系統(tǒng)在這方面的期望是合理的运吓,并且要定義足夠多的細節(jié),這樣就可以做成本與收益的分析疯趟,并依此對它們進行優(yōu)先級的排定了拘哨。
2)如果有必要,向其他功能需求中加入非功能需求的驗收條件
8.2 如何為容量編程
容量測試階段的關鍵在于信峻,它要告訴我們是否存在問題倦青,以便我們可以修復它。不要妄自猜測盹舞,而要先進行度量产镐。
過早且過分地關注應用程序的容量優(yōu)化是低效且昂貴的隘庄。而且,最終交付的應用系統(tǒng)也很少是高性能的癣亚。更糟糕的是丑掺,它甚至可能讓項目無法交付。
1)為應用程序決定一種架構述雾。通常要特別注意進程街州、網(wǎng)絡邊界和I/O
2)了解并使用正確的模式,避免使用那些影響系統(tǒng)容量和穩(wěn)定性的反模式
3)除了采用適當模式以外玻孟,還要確保團隊在已經明確的應用架構下進行開發(fā)唆缴,不要為了容量做無謂的優(yōu)化。鼓勵寫清晰且簡單的代碼取募,而不是深奧難以理解的代碼琐谤。在沒有明確測試結果表明有容量問題時,堅決不能在代碼可讀性上作出讓步
4)注意在數(shù)據(jù)結構和算法方面的選擇玩敏,確保它們的屬性與應用程序相吻合斗忌。比如,只需要O(1)的性能旺聚,就不要用一個O(n)的算法
5)處理線程時要特別小心织阳。要能達到這一點,關鍵之一就是保持應用程序的核心是單線程的
6)創(chuàng)建一些自動化測試來斷言所期望的容量級別砰粹。當這些測試失敗時唧躲,用它們作為向導來修復這些問題
7)使用調測工具主要關注測試中發(fā)現(xiàn)的問題,并修復它碱璃,不要使用“讓它越快越好”這類策略
8)只要有可能弄痹,就使用真實的容量數(shù)據(jù)來做度量。生產環(huán)境是唯一真實度量的來源嵌器。使用這樣的數(shù)據(jù)肛真,并分析這些數(shù)據(jù)到底說明了什么。特別要注意系統(tǒng)的用戶數(shù)爽航,他們的行為模式以及生產環(huán)境中的數(shù)據(jù)量
8.3 容量度量
擴展性測試 隨著服務器數(shù)蚓让、服務或線程的增加,服務或線程的增加讥珍,單個請求的響應時間和并發(fā)用戶數(shù)的支持會如何變化
持久性測試 這是要長時間運行應用程序历极,通過一段時間的操作,看是否有性能上的變化衷佃。這類測試能捕獲內存泄漏或穩(wěn)定性問題
吞吐量測試 系統(tǒng)每秒能處理多少事務趟卸、消息或頁面點擊
負載測試 當系統(tǒng)負載增加到類似生產環(huán)境大小或超過它時,系統(tǒng)的容量如何?這也許是最典型的容量測試
容量測試的一個重要方面是能夠為給定的應用程序模擬真實的使用場景锄列。另外一種方法是找出系統(tǒng)中具體操作的技術基準新蟆。目標明確的基準式容量測試對于代碼中某個具體問題的防范或局部代碼優(yōu)化是非常有用的。如果對應用程序來說右蕊,性能或吞吐量是一個重要指標的話,我們就需要用一些測試來斷言系統(tǒng)能夠滿足業(yè)務需求吮螺,而不是通過技術經驗來猜測某個特定組件的吞吐量應該是多少饶囚。在容量測試策略中還要包含基于場景的測試,這一點非常關鍵鸠补。
如何定義容量測試的成功與失敗
首先萝风,把目標設定為得到穩(wěn)定、可重現(xiàn)的結果紫岩。只要有可能的話规惰,為容量測試專門準備一個環(huán)境,用于度量容量泉蝌。然后歇万,一旦某個測試通過了最低驗收標準,就把驗收標準提高一點兒勋陪,調整該測試的成功門檻贪磺。為了使測試更好用,而不只是性能度量诅愚,每個測試都必須體現(xiàn)一個具體的場景寒锚,并且只有達到某個標準門檻時,才能認為該測試通過了违孝。
8.4 容量測試環(huán)境
理想情況下刹前,系統(tǒng)容量的絕對度量應該在一個盡可能與生產環(huán)境相似的環(huán)境上執(zhí)行。假如對某應用程序來說雌桑,容量或性能是一個非常關鍵的問題喇喉,那么就 一定要有所投入,為該系統(tǒng)的核心部分準備一個生產環(huán)境的副本筹燕。使用相同的軟硬件規(guī)格要求轧飞,遵循我們關于如何管理配置信息的建議,以確保每個環(huán)境中都使用相同的配置文件撒踪,包括網(wǎng)絡配置过咬、中間件及操作系統(tǒng)的配置。然而制妄,大多數(shù)項目的情況應該在這兩者之間掸绞,即在一個與生產環(huán)境盡可能相似的環(huán)境中運行容量測試,它會讓那些嚴重的容量問題突顯出來。另外衔掸,也不要依據(jù)硬件的某種特定參數(shù)對應用程序的擴展性作出線性推論烫幕,復雜系統(tǒng)的行為很少是這種線性相關的。對于那些需要部署到服務器集群中的應用程序來說敞映,一個既可以降低環(huán)境成本又能提供適當準確度量的策略就是较曼,僅復制一小部分的服務器,而不是整個集群振愿。
8.5 自動化容量測試
如果想在部署流水線中增加容量測試的話捷犹,就應該創(chuàng)建一個自動化容量測試套件,并且每次對系統(tǒng)進行修改之后冕末,一旦通過了提交測試和驗收測試(可選)萍歉,就應該執(zhí)行容量測試。
容量測試應該達到以下幾點目標:
測試具體的現(xiàn)實場景档桃,這樣就不會因為測試太抽象而錯過真實應用場景中那些重要的bug
預先設定成功的門檻枪孩,這樣就能判定容量測試是否通過了
盡可能讓測試運行時間短一些,從而保證容量測試在適當時間內完成
在變更面前要更健壯一些藻肄,從而避免因對應用程序的頻繁修改而不斷返工
組合成大規(guī)模的復雜場景蔑舞,這樣就可以模擬現(xiàn)實世界中的用戶使用模式
是可重復的,并且既能串行執(zhí)行嘹屯,也能并行執(zhí)行斗幼,以便這些測試既可以做負載測試,也可以做持久性測試
8.6 將容量測試加入到部署流水線中
當明確規(guī)定了成功條件的自動化容量測試成功通過以后抚垄,就證明已滿足容量需求蜕窿。通過這種方式,可以知道我們避免對容量問題的過分設計呆馁。和其他測試一樣桐经,容量測試階段也要從部署準備開始,然后核實環(huán)境和應用程序都一杯正確配置和部署浙滤,并完成冒煙測試之后才是容量測試的執(zhí)行阴挣。
8.7 容量測試系統(tǒng)的附加價值
重現(xiàn)生產環(huán)境中發(fā)現(xiàn)的復雜缺陷
探測并調試內存泄漏
持久性測試
評估垃圾回收的影響
垃圾回收的調優(yōu)
應用程序參數(shù)的調優(yōu)
第三方應用程序配置的調優(yōu),比如操作系統(tǒng)纺腊、應用程序服務器和數(shù)據(jù)庫配置
模擬非正常的畔咧、最糟糕情況的場景
評估一些復雜問題的不同解決方案
模擬集成失敗的情況
度量應用程序在不同硬件配置下的可擴展性
與外部系統(tǒng)進行交互的負載測試,即使容量測試的初衷是與樁替身接口打交道
復雜部署的回滾演練
有選擇地使系統(tǒng)的部分或全部癱瘓揖膜,從而評估服務的優(yōu)雅降級
在短期可用的生產硬件上執(zhí)行真實世界的容量基準誓沸,以便能計算出長期且低配的容量測試環(huán)境中更準確的擴展因素
9 應用程序的部署與發(fā)布
啟動自動部署系統(tǒng),將要部署的軟件版本和目標環(huán)境的名稱告訴它壹粟,并點擊“開始”就行了拜隧。所有后續(xù)部署和發(fā)布都要使用同樣的流程。這樣,就能看到每個環(huán)境中究竟運行的是哪個版本的應用程序洪添,誰授權部署了這個版本垦页,從上次部署之后應用程序到底有哪些修改。
9.1 創(chuàng)建發(fā)布策略
明確負責人干奢、配置管理策略痊焊、監(jiān)控需求、災難恢復計劃忿峻、生產環(huán)境的數(shù)量大小及容量計劃宋光、修復和升級策略
1)發(fā)布計劃
第一次部署應用程序部署步驟、如何進行冒煙測試炭菌、升級和撤銷步驟、備份和恢復步驟逛漫、重新啟動和重新部署步驟黑低、遷移步驟
2)發(fā)布產品
考慮收費模式、使用許可策略酌毡、第三方技術的版權問題克握、打包、市場活動所需要的材料枷踏、產品文檔菩暗、安裝包、銷售和售后支持團隊的準備
9.2 應用程序的部署和晉級
1)首次部署
在第一個迭代結束時旭蠕,要實現(xiàn)部署流水線的提交階段停团、一個用于部署的類生產環(huán)境、通過一個自動化過程獲取在提交階段中生成的二進制包并將其部署到這個類生產環(huán)境中掏熬、簡單冒煙測試用于驗證本次部署是正確的
類生產環(huán)境的特點:它的操作系統(tǒng)與生產環(huán)境一致佑稠、安裝的軟件與生產環(huán)境一致、用與管理生產環(huán)境相同的方式對這種環(huán)境進行管理旗芬、對于客戶自行安裝的軟件要基于客戶硬件環(huán)境的調研結果
2)對發(fā)布過程進行建模并讓構建晉級
自動化部署機制使構建版本的晉級變成了一件非常簡單的事舌胶,只需要選擇某個發(fā)布候選版本并把它部署到正確的環(huán)境中即可。每個需要部署應用程序的人都能用這種自動化部署機制疮丛,而不需要了解部署本身相關的任何技術知識幔嫂。
3)配置的晉級
用冒煙測試來驗證配置信息的指向是正確的
4)聯(lián)合環(huán)境
在集成測試環(huán)境運行冒煙測試來作為驗收測試
5)部署到試運行環(huán)境
在用戶使用應用程序之前,應該在試運行環(huán)境上執(zhí)行一些最終測試誊薄。
9.3 部署回滾和零停機發(fā)布
當指定發(fā)布回滾計劃時履恩,需要遵循兩個通用原則。首先呢蔫,在發(fā)布之前似袁,確保生產系統(tǒng)的狀態(tài)(包括數(shù)據(jù)庫和保存在文件系統(tǒng)中的狀態(tài))已備份。其次,在每次發(fā)布之前都練習一下回滾計劃昙衅,包括從備份中恢復或把數(shù)據(jù)庫備份遷移回來扬霜,確保這個回滾計劃可以正常工作。
1)通過重新部署原有的正常版本來進行回滾
2)零停機發(fā)布 將用戶從一個版本幾乎瞬間轉移到另一個版本上
3)藍綠部署 系統(tǒng)的用戶被引導到當前正在作為生產環(huán)境的綠環(huán)境中而涉,把新版本發(fā)布到藍環(huán)境中著瓶,在藍環(huán)境上運行冒煙測試,當一切準備就緒以后只要修改一下路由配置啼县,將用戶從綠環(huán)境導向藍環(huán)境即可材原。
4)金絲雀發(fā)布 把應用程序的某個版本部署到生產環(huán)境中的部分服務器中,從而快速得到反饋
9.4 緊急修復
任何情況下季眷,都不能破壞流程余蟹。緊急修復版本也要走同樣的構建、部署子刮、測試和發(fā)布流程威酒,與其他代碼變更沒什么區(qū)別。同時要考慮這個缺陷帶來的影響程度挺峡。
9.5 持續(xù)部署
發(fā)布越頻繁葵孤,兩次發(fā)布版本之間的差異就會越少,發(fā)布的風險越低橱赠。同時持續(xù)部署迫使創(chuàng)建完整的自動化構建尤仍、部署、測試和發(fā)布流程狭姨。
9.6 小貼士和竅門
1)真正執(zhí)行部署操作的人應該參與部署過程的創(chuàng)建
2)記錄部署活動
3)不要刪除舊文件宰啦,而是移動到別的位置
4)部署是整個團隊的責任
5)服務器應用程序不應該有GUI
6)為新部署留預熱期
7)快速失敗
8)不要直接對生產環(huán)境進行修改
10 基礎設施和環(huán)境管理
環(huán)境:
組成運行環(huán)境的服務器的硬件配置信息——比如CPU的類型與數(shù)量、內存大小饼拍、spindle和NIC等绑莺,以及它們互聯(lián)所需的網(wǎng)絡基礎設施
應用程序運行所需要的操作系統(tǒng)和中間件(如消息系統(tǒng)、應用服務器和Web服務器惕耕,以及數(shù)據(jù)庫服務器等)的配置信息
原則:
使用保存于版本控制庫中的配置信息來指定基礎設施所處的狀態(tài)
基礎設施應該具有自治特性纺裁,即它應該自動地將自己設定為所需狀態(tài)
通過測試設備和監(jiān)控手段,應該每時每刻都能掌握基礎設施的實時狀況
測試環(huán)境和生產環(huán)境絕大多數(shù)是要相似的司澎,才能盡早發(fā)現(xiàn)環(huán)境方面的問題欺缘,以及在向生產環(huán)境部署之前對關鍵活動進行操作演練,從而減少發(fā)布風險挤安。利用敏捷技術對基礎設施進行有效管理谚殊。
10.1 理解運維團隊的需要
所有的項目干系人都能打成一個共識,即讓發(fā)布有價值的軟件成為一件低風險的事情蛤铜。做這件事的最佳方法就是盡可能頻繁地發(fā)布(即持續(xù)交付)嫩絮。這就能保證在兩次發(fā)布之間的變更很小丛肢。
1)文檔與審計
變更管理:任何人在任何時候想修改一下測試環(huán)境或生產環(huán)境,都必須提出申請剿干,并被審批蜂怎。在變更申請中,需要包括詳細的風險與影響分析置尔,以及出錯時的應對方案杠步。這個申請應該在新版本的部署流程啟動之前提交,而且不能是在業(yè)務人員期望上線前的幾個小時才提交榜轿。
2)異常事件的告警
運維團隊會有自己的系統(tǒng)來監(jiān)控基礎設施和正在運行的應用程序幽歼,并希望當系統(tǒng)出現(xiàn)異常狀況時收到警報,以便將停機時間最小化谬盐。在項目一開始就了解運維團隊希望怎樣來監(jiān)控應用程序甸私,并將其列在發(fā)布計劃之中。
3)保障IT服務持續(xù)性的計劃
RPO(恢復點目標飞傀,即災難之前丟失多長時間內的數(shù)據(jù)時可接受的)控制了數(shù)據(jù)備份和恢復策略皇型,因此數(shù)據(jù)備份必須足夠頻繁,并且要小心管理配置信息助析,才能達到這個RPO。
RTO(恢復時間目標椅您,即服務恢復之前允許的最長停機時間)要額外建立一個生產環(huán)境和基礎設施的副本外冀,以便當主系統(tǒng)出錯時,可以啟用這個后備系統(tǒng)掀泳。
4)使用運維團隊熟悉的技術
在每個項目開始時雪隧,開發(fā)團隊和運維團隊就應該坐下來,討論并決定應用程序的部署應該如何執(zhí)行员舵。一旦所用技術達成一致脑沿,雙方可能都需要學習一下這些技術。
10.2 基礎設施的建模和管理
每種環(huán)境中都有很多種配置信息马僻,所有這些配置信息都應該以自動化方式進行準備和管理庄拇。使用能夠以自動化方式進行配置和部署的技術是一個必要條件。并且應該把創(chuàng)建和維護基礎設施需要的所有內容都進行版本控制韭邓,包括操作系統(tǒng)的安裝定義項措近、數(shù)據(jù)中心自動化工具的配置信息、通用基礎設施配置信息女淑、用于管理基礎設施的所有腳本瞭郑。
對于基礎設施的變更來講,部署流水線的工作包括三部分鸭你。首先屈张,在對任何基礎設施的變更部署到生產環(huán)境之前擒权,它應該驗證所有的應用程序在這些變更之后也能正常工作,并確保在該新版本的基礎設施之上阁谆,所有受到影響的應用程序的功能和非功能測試都能成功通過碳抄。其次,它應該將這些變更放到運維團隊管理的測試和生產環(huán)境上笛厦。最后纳鼎,流水線還應該執(zhí)行部署測試,確保新的基礎設施配置已成功部署裳凸。
1)基礎設施的訪問控制
在沒有批準的情況下贱鄙,不允許他人修改基礎設施
制定一個對基礎設施進行變更的自動化過程
對基礎設施進行監(jiān)控,一旦發(fā)生問題姨谷,能盡早發(fā)現(xiàn)
2)對基礎設施進行修改
無論是更新防火墻規(guī)則逗宁,還是部署服務的新版本,每個變更都應該走同樣的變更管理流程
這個流程應該使用一個所有人都需要登錄的系統(tǒng)來管理
做過的變更應該詳細清楚地記錄到日志中梦湘,這樣便于以后做審計
能夠看到對每個環(huán)境進行變更的歷史瞎颗,包括部署活動
想做修改的話,首先必須在一個類生產環(huán)境中測試通過捌议,而且自動化測試也已經運行完成哼拔,以確保這次變更不會破壞該環(huán)境中的所有應用程序
對每次修改都應該進行版本控制,并通過自動化流程對基礎設施進行變更
需要有一個測試來驗證這次變更已經起作用了
10.3 服務器的準備及其配置的管理
一旦安裝好操作系統(tǒng)后瓣颅,就要保證任何配置的修改都是以受控方式進行的倦逐。配置管理過程的目標是,保證配置管理是聲明式且冪等的宫补,即無論基礎設施的初始狀態(tài)是什么樣檬姥,一旦執(zhí)行了配置操作后,基礎設施或系統(tǒng)所處的狀態(tài)就一定是你所期望的狀態(tài)粉怕,即時某個配置項進行了重復設置對配置結果也沒有影響健民。一旦這個系統(tǒng)準備好之后,就能用一個被集中版本控制的配置管理系統(tǒng)對基礎設施中的所有測試環(huán)境和生產環(huán)境進行管理了贫贝。之后秉犹,就可得到如下收益。
確保所有環(huán)境的一致性
很容易準備一個與當前環(huán)境配置相同的新環(huán)境稚晚,比如創(chuàng)建一個與生產環(huán)境相同的試運行環(huán)境
如果某個機器出現(xiàn)硬件故障凤优,可以用一個全自動化過程配置一個與舊機器完全相同的新機器
10.4 中間件的配置管理
1)管理配置項
2)產品研究
3)考查中間件是如何處理狀態(tài)的
4)查找用于配置的API
5)使用更好的技術
10.5 基礎設施服務的管理
1)網(wǎng)絡基礎設施配置的每個部分都應該進行版本控制
2)安裝一個好用的網(wǎng)絡監(jiān)控系統(tǒng)。保證當網(wǎng)絡連接被破壞時你就會得到通知蜈彼,而且監(jiān)控應用程序所使用的每個路由的每個端口筑辨。
3)每次網(wǎng)絡連接超時或者連接異常關閉時,應用程序都應該在WARNING這一級別進行記錄幸逆;每次關閉連接時棍辕,應該使用INFO級別進行記錄暮现,如果日志顯得太長,也可以使用DEBUG級別楚昭。每次打開連接時栖袋,應該使用DEBUG級別記錄,并且盡可能多地包含所連接終端的信息抚太。
4)確保冒煙測試在部署時檢查所有的連接塘幅,找出潛在的路由或連接問題
5)確保集成測試環(huán)境的網(wǎng)絡拓撲結構盡可能與生產環(huán)境相似,包括使用同樣的硬件和物理連接。以這種方式構建出來的環(huán)境甚至可以作為硬件故障時的一個備用環(huán)境。
10.6 虛擬化
虛擬化有助于減少部署軟件所花費的時間洪乍,并用一種不同的方式來降低與部署相關的風險。當將其應用到部署流水線中時匾乓,它可以算是簡化環(huán)境維護和準備工作最有用的技術了。虛擬化也有助于提高對功能需求和非功能需求的測試能力又谋。
1)虛擬環(huán)境的管理
對需求的變化作出快速響應拼缝、固化、硬件標準化彰亥、基線維護更容易
2)虛擬環(huán)境和部署流水線
虛擬化技術提供了一個簡單的機制來創(chuàng)建系統(tǒng)所需的環(huán)境基線咧七;很容易將任何環(huán)境恢復到原有狀態(tài);通過使用虛擬服務器來做主機環(huán)境的基線使創(chuàng)建生產環(huán)境的副本變得更容易任斋;實現(xiàn)一鍵部署應用程序任意版本继阻。
3)用虛擬環(huán)境做高度的并行測試
虛擬化提供了一種絕好的方法來處理多平臺測試。只要為應用程序可能運行的每種平臺創(chuàng)建虛擬機仁卷,并在其上創(chuàng)建VM模板穴翩,然后在所有這些平臺上并行運行部署流水線中的所有階段就行了犬第〗趸可以使用同樣的技術讓測試并行化,從而縮短代價高昂的驗收測試及容量測試的反饋周期歉嗓。
10.7 基礎設施和應用程序的監(jiān)控
當創(chuàng)建監(jiān)控策略時丰介,需要考慮以下四個方面
對應用程序和基礎設施進行監(jiān)測,以便可以收集必要的數(shù)據(jù)
存儲數(shù)據(jù)鉴分,以便可以很容易拿來分析
創(chuàng)建一個信息展示板哮幢,將數(shù)據(jù)聚合在一起,并以一種適合運維團隊和業(yè)務團隊使用的形式展現(xiàn)出來
建立通知機制志珍,以便大家能找出他們關心的事件
1)收集數(shù)據(jù)
硬件橙垢、操作系統(tǒng)、中間件伦糯、應用程序
2)記錄日志
3)建立信息展示板
4)行為驅動的監(jiān)控
11 數(shù)據(jù)管理
對數(shù)據(jù)庫進行版本管理柜某,使用DbDeploy這樣的工具管理數(shù)據(jù)遷移過程的自動化
努力保持數(shù)據(jù)庫模式修改的向前和向后兼容性嗽元,以便把數(shù)據(jù)的部署和遷移問題與應用程序的部署問題分開
確保在準備過程中,測試可以創(chuàng)建它們所依賴的數(shù)據(jù)喂击,并確保數(shù)據(jù)是分開的剂癌,以保證不會影響那些同時運行的其他測試
只保存不同測試之前應用程序啟動所需要的測試數(shù)據(jù),以及一些非常通用的引用數(shù)據(jù)
盡可能使用應用程序的公共API為測試創(chuàng)建正確的初始狀態(tài)
在大多數(shù)情況下翰绊,不要在測試中使用生產數(shù)據(jù)集的副本佩谷。創(chuàng)建自定義數(shù)據(jù)集既可以通過細心選擇生產數(shù)據(jù)集的最小子集來實現(xiàn),也可以通過運行驗收測試和容量測試來實現(xiàn)
11.1 數(shù)據(jù)庫腳本化
數(shù)據(jù)庫的初始化和所有的遷移都需要腳本化监嗜,并提交到版本控制庫中谐檀。
11.2 增量式修改
1)對數(shù)據(jù)庫進行版本控制
管理數(shù)據(jù)庫變更的技術需要達到以下兩個目標:首先,要能夠持續(xù)部署應用程序而不用擔心當前部署環(huán)境中所用的數(shù)據(jù)庫版本秤茅。其次稚补,部署腳本只要將數(shù)據(jù)庫向前或向后更新到與應用程序相匹配的版本即可。
2)聯(lián)合環(huán)境中的變更管理
對“哪個應用使用了哪個數(shù)據(jù)庫對象”進行登記是個很有效的方法框喳,這樣你就知道哪次修改會影響哪些應用程序了课幕。同時要確保在修改時已與維護其他應用程序的團隊達成一致。
11.3 數(shù)據(jù)庫回滾和無停機發(fā)布
1)保留數(shù)據(jù)的回滾
2)將應用程序部署與數(shù)據(jù)庫遷移解耦
11.4 測試數(shù)據(jù)的管理
1)為單元測試進行數(shù)據(jù)庫模擬
用測試替身對象來替代那些訪問數(shù)據(jù)庫的代碼五垮、使用假的數(shù)據(jù)庫
2)管理測試與數(shù)據(jù)之間的耦合
依賴測試的獨立性乍惊、適應性測試或測試的順序性,測試的獨立性在靈活性和擴展性方面較好
3)測試獨立性
測試結束后將數(shù)據(jù)庫中的數(shù)據(jù)狀態(tài)恢復到該測試運行之前的狀態(tài)放仗;數(shù)據(jù)的功能性分隔
4)建立和銷毀
5)連貫的測試場景
這種緊耦合的依賴性太大
11.5 數(shù)據(jù)管理和部署流水線
1)提交階段的測試數(shù)據(jù)
要將設計分成多個互相獨立的組件和測試润绎,使用測試替身對象來模擬依賴
2)驗收測試中的數(shù)據(jù)
盡可能減少測試對大型復雜數(shù)據(jù)結構的依賴
3)容量測試的數(shù)據(jù)
使用數(shù)據(jù)重用策略
4)其他測試階段的數(shù)據(jù)
利用生產數(shù)據(jù)的一個子集或運行一些自動化驗收測試或容量測試之后產生的數(shù)據(jù)庫,為手工測試創(chuàng)建一個定制數(shù)據(jù)集
12 組件和依賴管理
組件是指應用程序中的一個規(guī)模相當大的代碼結構诞挨,它具有一套定義良好的API莉撇,而且可以被另一種實現(xiàn)方式代替。對于一個與組件的軟件系統(tǒng)來說惶傻,通常其代碼庫被分成多個相互分離的部分棍郎,每個部分通過個數(shù)有限的定義良好的接口提供一些服務行為,與其他組件進行有限的交互银室⊥康瑁基于組件的設計通常被認為是一種良好的架構,具有松耦合性蜈敢,是一種鼓勵重用的設計辜荠。
12.1 保持應用程序可發(fā)布
為了在變更的同時還能保持應用程序的可發(fā)布,有如下四種應對策略
1)將新功能隱藏起來抓狭,直到它完成為止
把新功能直接放進主干伯病,但對用戶不可見;通過配置項開關來管理
2)將所有的變更都變成一系列的增量式小修改否过,而且每次小的修改都是可發(fā)布的
3)使用通過抽象來模擬分支的方式對代碼庫進行大范圍的變更
4)使用組件午笛,根據(jù)不同部分修改的頻率對應用程序進行解耦
12.2 依賴
在構建或運行軟件時膨蛮,軟件的一部分要依賴于另一部分,就產生了依賴關系季研。在軟件項目中敞葛,有兩種適當?shù)姆椒▉砉芾韼煳募环N是將它們提交到版本控制庫中与涡,另一種是顯式地聲明它們惹谐,并使用像Maven或Ivy這樣的工具從因特網(wǎng)或者從你所在組織的公共庫中下載。
12.3 組件
1)如何將代碼庫分成多個組件
它將問題分成更小且更達意的代碼塊
組件常常表示出系統(tǒng)不同部分代碼的變化率不同驼卖,并且有不同的生命周期
它鼓勵我們使用清晰的職責描述來設計并維護軟件氨肌,反過來也限制了因修改產生的影響,并使理解和修改代碼庫變得更容易
它給我們提供了額外的自由度來優(yōu)化構建和部署過程
2)將組件流水線化
每次提交修改時酌畜,就應該構建并測試整個應用怎囚。在大多數(shù)情況下,我們建議將整個軟件系統(tǒng)作為一個整體來構建桥胞,除非是反饋過程太長恳守。然而,在很多現(xiàn)實場景下贩虾,系統(tǒng)會受益于將其分成多個不同的構建流水線催烘。
應用程序的某些組成部分有不同的生命周期
應用程序的幾個功能領域由不同的團隊負責,那么這些團隊可能都會有自己的組件
某些組件使用不同的技術或構建流程
某些共享組件被不同的幾個項目所用
組件相對穩(wěn)定缎罢,不需要頻繁修改
全面構建整個應用程序所花時間太長伊群,但為每個組件創(chuàng)建一個構建會更快
3)集成流水線
當創(chuàng)建集成流水線時,需要牢記部署流水線的兩個通用原則:快速反饋和為所有相關角色提供構建狀態(tài)可視化策精。如果流水線或流水線鏈太長的話舰始,會讓反饋時間變長。一種解決方案是咽袜,在生成了二進制文件并通過單元測試之后就立即觸發(fā)下游的流水線丸卷。
12.4 管理依賴關系圖
1)構建依賴圖
每個組件都應該有自己的構建流水線,當其源代碼被修改時或者上游依賴有變化時都應該觸發(fā)它的構建流水線酬蹋。當該組件成功通過它自己的所有自動化測試時及老,就應該觸發(fā)下游依賴抽莱。
2)為依賴圖建立流水線
首先范抓,為了增加反饋的速度,一旦任何一個項目部署流水線的提交階段完成了食铐,就要觸發(fā)下游的項目匕垫,并不需要等待驗收測試全部通過,只要下游項目所需的二進制文件已經產生就行了虐呻。除了向手工測試環(huán)境和生產環(huán)境部署意外象泵,其他的觸發(fā)都是自動的寞秃。團隊要能夠追蹤在應用程序的某個具體版本中每個組件的源是什么。一個好的持續(xù)集成工具不僅可以做到這一點偶惠,還應該能夠展示它是由哪些徐建的哪個版本集成在一起的春寿。持續(xù)集成工具還要確保在每個流水線實例中,從前到后每個組件所有的版本都是一致的忽孽。它應該防止依賴地獄這樣的事绑改,并確保當版本控制庫中的某次變更影響到多個組件時,它只能通過流水線傳播一次兄一。
3)什么時候要觸發(fā)構建
一方面厘线,最好保持與上游依賴最新的版本一致,以確保得到最新的功能和已修復的缺陷出革。而另一方面造壮,集成每個依賴的最新版本會有一定的成本,因為要花時間來修復這些新版本帶來的破壞骂束。需要考慮的點是對這些依賴的新版本的信任度有多高耳璧。如果所依賴的組件是團隊自己開發(fā)的,通常能快速且簡單地修復由于API變更引起的問題展箱,這樣楞抡,頻繁集成是最好的。如果組件足夠小析藕,最好就讓整個應用只有一個構建召廷。假如上游依賴組件是由你所在公司的其他團隊開發(fā)的,那么最好這些組件有它們各自的流水線账胧。然后可以再判斷是使用上游依賴組件每次變更后的最新版本竞慢,還是仍舊使用某個具體版本。這個決定既依賴于它們變化的頻率治泥,又依賴于上游團隊解決問題的速度筹煮。
4)謹慎樂觀主義
為依賴圖增加觸發(fā)類型,“靜止類型”的上游依賴發(fā)生變化后居夹,不會觸發(fā)新的構建败潦;“活躍類型”的上游依賴發(fā)生變化后就一定會觸發(fā)新的構建;如果某個“活躍類型”的上游依賴發(fā)生變更后觸發(fā)了構建准脂,并且這次構建失敗了劫扒,那么就把上游依賴標記為“慎用類型”,并且將這個上游依賴的上一次成功的組件版本標記為“好版本”狸膏。
12.5 管理二進制包
1)制品庫是如何運作的
不建議將二進制產物提交到版本控制庫中沟饥。如果能重新生成它們,就不需要它們。為了達到這一點贤旷,版本控制系統(tǒng)就要包含重建這些二進制包所需的所有內容广料,包括自動化構建腳本。無論這些產物能保存多長時間幼驶,都應該一直保存每個產物的散列值艾杏,以便可以驗證生成二進制包的源代碼是否正確。
2)部署流水線如何與制品庫結合
實現(xiàn)部署流水線需要做兩件事:一是將構建過程中的產物放到制品庫里盅藻,二是以后需要時能把它取出來糜颠。
編譯階段會創(chuàng)建需要放到制品庫的二進制文件
單元測試和驗收測試階段會去除這些二進制文件,并在其上運行單元測試和驗收測試萧求,將生成的測試報告放到制品庫中其兴,以便開發(fā)人員查看結果
用戶驗收測試階段是將二進制文件部署到UAT環(huán)境中,用于手工測試
發(fā)布階段是取出二進制文件夸政,將其發(fā)布給用戶或部署到生產環(huán)境中元旬。
隨著候選發(fā)布版本在流水線中的進展,每個階段的成功或失敗都記錄到索引文件中守问。流水線的后續(xù)階段依賴于該文件中的狀態(tài)記錄匀归,即只有已經通過驗收測試的二進制文件才能用于手工測試和后續(xù)階段。
13 版本控制進階
13.1 版本控制系統(tǒng)
版本控制系統(tǒng)(也叫源文件控制或修訂控制系統(tǒng))用于維護應用程序每次修改的完整歷史耗帕,包括源代碼穆端、文檔、數(shù)據(jù)庫定義仿便、構建腳本和測試体啰,等等。然而嗽仪,它也有另一個重要的用途荒勇,讓團隊一起工作在應用程序的不同部分,同時維護系統(tǒng)記錄闻坚,即應用程序的權威代碼基沽翔。
13.2 分支與合并
分支的理由有三種。為了發(fā)布應用程序的一個新版本窿凤,需要創(chuàng)建一個分支仅偎;當需要調研一個新功能或做一次重構時;當需要對應用程序做比較大的修改雳殊。缺點是會阻礙持續(xù)集成橘沥,且需要花費額外的時間合并和解決沖突。
因此相种,需要對構建軟件所需要的所有內容進行版本控制威恼;需要有一個合理的流程來支持合并;只為發(fā)布創(chuàng)建長周期的分支寝并,新開發(fā)的代碼總是被提交到主干上箫措。分布式版本控制系統(tǒng)在軟件交付方式上有重大且積極的影響。
13.3 基于流的版本控制系統(tǒng)
基于流的版本控制系統(tǒng)可以把一系列修改一次性應用到多個分支上衬潦,從而減少合并時的麻煩斤蔓。流之間是可以相互繼承的,如果你把某次修改應用到一個指定的流上镀岛,它的所有子孫流都會繼承那些修改弦牡。可以應用在下發(fā)修復補丁包和向代碼基中添加第三方庫的新版本時漂羊。
不能每天向共享主干提交代碼是不符合持續(xù)集成實踐要求的驾锰。有很多辦法來解決這一問題,但這需要很強的紀律性走越,而且仍舊不能完全解決大中型團隊所遇到的窘境椭豫。最佳規(guī)則是盡可能頻繁地晉級修改,并在開發(fā)人員所共享的流上盡可能頻繁且盡可能多地運行自動化測試旨指。
13.4 主干開發(fā)
確保所有的代碼被持續(xù)集成
確保開發(fā)人員及時獲得他人的修改
避免項目后期的合并地獄和集成地獄
缺點是每次向主干簽入并不都是可發(fā)布狀態(tài)赏酥。且軟件需要良好的組件化、增量式開發(fā)和特性隱藏谆构。
13.5 按發(fā)布創(chuàng)建分支
一直在主干上開發(fā)新功能
當待發(fā)布版本的所有功能都完成了裸扶,且希望繼續(xù)開發(fā)新功能時才創(chuàng)建一個分支
在分支上只允許提交那些修復嚴重缺陷的代碼,并且這些修改必須立即合并回主干
當執(zhí)行實際的發(fā)布時搬素,這個分支可以選擇性地打一個標簽
13.6 按功能特性分支
每天都要把主干上的所有變更合并到每個分支上
每個特性分支都應該是短生命周期的呵晨,理想情況下應該只有幾天,絕對不能超過一個迭代周期
活躍分支的數(shù)量在任意時刻都應該少于或等于正在開發(fā)當中的用戶故事的數(shù)量熬尺。除非已經把開發(fā)的用戶故事合并回主干何荚,否則誰都不能創(chuàng)建新分支
在合并回主干之前,該用戶故事應該已經由測試人員驗收通過了猪杭。只有驗收通過的用戶故事才能合并回主干
重構必須即時合并餐塘,從而將合并沖突最小化。這個約束非常重要皂吮,但也可能非常痛苦戒傻,進而限制了這種模式的使用
技術負責人的一部分職責就是保證主干的可發(fā)布狀態(tài)。他應該檢查所有的合并蜂筹,有權拒絕可能破壞主干代碼的補丁
13.7 按團隊分支
創(chuàng)建多個小團隊需纳,每個團隊自己都有對應的分支
一旦某個特性或用戶故事完成了,就讓該分支穩(wěn)定下來艺挪,并合并回主干
每天都將主干上的變更合并到每個分支上
對于每個分支不翩,每次簽入后都要運行單元和驗收測試
每次一個分支合并回主干時,在主干上都要運行所有的測試(包括集成測試)
14 持續(xù)交付管理
風險管理是一個過程,它確保:
項目的主要風險已經被識別
已有適當?shù)木徑獠呗詫@些風險進行管控
在整個項目過程中口蝠,持續(xù)識別和管理風險