|
英文原文:Patterns for Continuous Delivery
當(dāng)你有了持續(xù)集成需要的構(gòu)建服務(wù)器和腳本之后,下一個(gè)問題肯定是:“我們?cè)撃眠@些構(gòu)建版本怎么辦?”持續(xù)交付,以自動(dòng)化或半自動(dòng)化方式,將構(gòu)建版本從一個(gè)環(huán)境提送(promote)到更接近實(shí)際生產(chǎn)的交付準(zhǔn)備環(huán)境;這常常是公司在這方面演進(jìn)的下一步。
任何規(guī)模的公司都可以實(shí)施持續(xù)交付,但是具體流程會(huì)根據(jù)公司具體情況差異很大。顯而易見,四人全能團(tuán)隊(duì)的需要,與大規(guī)模、多團(tuán)隊(duì)、配備正式QA和設(shè)備精良的產(chǎn)品支持部門這樣的公司,二者一定有很大差別。本文沒有試圖提出萬能方案,而是覆蓋多種場(chǎng)景和選擇。
選擇持續(xù)交付工具集
為持續(xù)交付選擇工具集,是最不重要的決策。當(dāng)你制定出工作流程之后,只需要選擇相匹配的工具集即可。考慮到初始設(shè)置和配置的工作量,花幾天時(shí)間構(gòu)建自己定制的工具也不是非理性選擇。
更重要的是,這樣做沒有鎖定的風(fēng)險(xiǎn)。跟選擇版本控制系統(tǒng)不同,你可以使用多種持續(xù)交付工具,而且可以互相之間自由切換。QA團(tuán)隊(duì)從開發(fā)人員那里拉出構(gòu)建版本使用一種工具,向準(zhǔn)備服務(wù)器推送時(shí)使用另一種工具,這樣的事情也有所耳聞。
基線場(chǎng)景
在基線場(chǎng)景中,我們要以有限的資源找出公司中的模式。像由3到4人構(gòu)成的IT部門,常常兼做開發(fā)和系統(tǒng)管理。這樣規(guī)模的團(tuán)隊(duì)常常支持中小型業(yè)務(wù),特別是不以技術(shù)為主業(yè)務(wù)的公司。大型公司也有可能這樣組織,把人分成多個(gè)、很可能是互相獨(dú)立的小組,各小組之間也沒有交互。
在真正開始進(jìn)行持續(xù)交付之前,需要做一些必要的設(shè)置工作。首先,最重要的是要有版本控制系統(tǒng),以及與之匹配的構(gòu)建服務(wù)器。這第一臺(tái)構(gòu)建服務(wù)器將會(huì)是你的持續(xù)集成服務(wù)器,它要保證每次簽入動(dòng)作都能成功構(gòu)建。一般來說,你需要一個(gè)“現(xiàn)成”的構(gòu)建服務(wù)器擔(dān)當(dāng)此任。能夠監(jiān)控簽入動(dòng)作還要自動(dòng)初始化構(gòu)建,要想手工開發(fā)這樣的東西,真正操作起來常常要比聽起來難得多。即使可以在版本控制系統(tǒng)中加入觸發(fā)機(jī)制,完成諸如失敗構(gòu)建通知這樣的功能也不值得花太多功夫。
即使在資源有限的作坊式公司,交付準(zhǔn)備服務(wù)器(staging server)也是持續(xù)交付的必要組成部分。交付準(zhǔn)備服務(wù)器應(yīng)該盡可能模擬出生產(chǎn)環(huán)境。“你有多少預(yù)算”常常是首要問題。如果你的生產(chǎn)環(huán)境有價(jià)值幾十萬美元的數(shù)據(jù)庫服務(wù)器,很可能你無法負(fù)擔(dān)搭建一個(gè)同樣的交付準(zhǔn)備服務(wù)器。而且可能你也不想這么做。
在模擬生產(chǎn)環(huán)境時(shí),有一個(gè)常見錯(cuò)誤:過高匹配硬件環(huán)境。假如你的生產(chǎn)環(huán)境每秒處理100個(gè)請(qǐng)求,如果為交付準(zhǔn)備服務(wù)器購(gòu)買同樣硬件,但測(cè)試時(shí)每秒只執(zhí)行幾個(gè)請(qǐng)求,你的結(jié)果就是有問題的。理想情況下,為了模擬生產(chǎn)環(huán)境請(qǐng)求,你還應(yīng)該購(gòu)買并設(shè)置負(fù)載服務(wù)器,但這么做成本太高,而且耗費(fèi)時(shí)間。對(duì)于這種規(guī)模的團(tuán)隊(duì),降低交付準(zhǔn)備服務(wù)器處理能力是更佳策略。
另一個(gè)常常忽略的需求,是構(gòu)建的版本化。必須有某種唯一的識(shí)別機(jī)制,保證可以區(qū)分開每個(gè)構(gòu)建和其他構(gòu)建版本。如果針對(duì)單一的公共主干代碼,簡(jiǎn)單的時(shí)間戳或是自增長(zhǎng)版本號(hào)也就夠了。本文后面會(huì)討論更復(fù)雜的場(chǎng)景。
結(jié)構(gòu)
有了上面列出來的部件,現(xiàn)在你的環(huán)境應(yīng)該跟下面的圖很像:
交付策略
構(gòu)建服務(wù)器編譯代碼,交付準(zhǔn)備服務(wù)器等候接收構(gòu)建結(jié)果,有了這二者之后,下一步就是決定你的部署策略。小團(tuán)隊(duì)有兩種選擇:“簽入時(shí)交付”和“定時(shí)交付”。
簽入時(shí)交付
“簽入時(shí)交付”策略的優(yōu)勢(shì)在于馬上產(chǎn)生的滿足感。根據(jù)代碼庫的規(guī)模,從簽入新功能代碼到能夠在交付準(zhǔn)備服務(wù)器上測(cè)試,一兩分鐘就夠了。
這種方式的主要問題在于:交付準(zhǔn)備服務(wù)器會(huì)被蹂躪得不穩(wěn)定。很多時(shí)候,我見到有人試圖測(cè)試某個(gè)功能,突然新的版本推到交付準(zhǔn)備服務(wù)器上了,破壞了正在運(yùn)行的測(cè)試。更糟糕的是:交付準(zhǔn)備服務(wù)器常常作為演示服務(wù)器使用,在某些重要的演示時(shí),很可能出現(xiàn)嚴(yán)重的后果。
代碼混亂是另一個(gè)問題。比如,如果三次簽入在很短的時(shí)間內(nèi)先后進(jìn)行,那么可能觸發(fā)三個(gè)構(gòu)建、交付周期,實(shí)際上只有最后一次才是必要的。極端情況,這會(huì)帶來很大混亂,交付部署環(huán)境將無法有充足的時(shí)間展示自己的功用。不過,大多數(shù)構(gòu)建服務(wù)器都有選項(xiàng),可以延遲構(gòu)建的開始,或是在給定時(shí)間間隔內(nèi)避免多次構(gòu)建。
定期交付
定期交付策略更易于預(yù)測(cè)。所有人都知道交付何時(shí)啟動(dòng),并可以規(guī)劃自己的代碼簽入是在交付之前還是之后進(jìn)行。典型做法是一天構(gòu)建/交付一次或兩次。
每日構(gòu)建的缺點(diǎn)在于,它會(huì)給工作環(huán)境帶來不必要的壓力。開發(fā)人員會(huì)發(fā)現(xiàn)自己要趕著在構(gòu)建截止時(shí)間之前完成一次簽入。在每日深夜構(gòu)建,這時(shí)開發(fā)人員應(yīng)該不在工作,可以減輕壓力,但也意味著除非到第二天,他們無法執(zhí)行第二層測(cè)試。
當(dāng)我們開始使用“每日構(gòu)建”這樣的詞匯時(shí),很容易忘記我們實(shí)際上不是在談?wù)摌?gòu)建。我們真正在談?wù)摰氖峭暾臉?gòu)建、交付周期。有了持續(xù)集成,如果構(gòu)建失敗,你馬上就能知道。接下來是要修復(fù)問題,還是要回滾簽入,就很簡(jiǎn)單了;只要規(guī)劃好的交付完成了,軟件就已經(jīng)準(zhǔn)備好部署到生產(chǎn)環(huán)境。
部署到生產(chǎn)環(huán)境
該場(chǎng)景的假設(shè)是:實(shí)在沒人能夠完成任何特定版本前要做的大量測(cè)試工作。只要交付準(zhǔn)備服務(wù)器上的檢查完成,構(gòu)建版本就會(huì)直接提送到生產(chǎn)環(huán)境中。但即使如此,也有多種選項(xiàng),各有其妥協(xié)之處。
從交付準(zhǔn)備階段提送
將經(jīng)過驗(yàn)證的構(gòu)建版本從交付準(zhǔn)備服務(wù)器直接提送,是常見的選擇。其優(yōu)勢(shì)在于高度確定性。理論上,測(cè)試一個(gè)版本的構(gòu)建、然后錯(cuò)誤地部署另一個(gè)版本,這樣的事情不可能發(fā)生。寫腳本把文件從交付準(zhǔn)備服務(wù)器拷貝到生產(chǎn)環(huán)境,也很容易。
但像很多事情一樣,理論跟現(xiàn)實(shí)總是有差距的。有了到交付準(zhǔn)備服務(wù)器的自動(dòng)化推送,很可能出現(xiàn)這樣的情況:測(cè)試完成,去倒一杯咖啡,回來后工作針對(duì)的構(gòu)建版本可能就完全不同了。更糟糕的情況是:構(gòu)建代理會(huì)開始覆蓋交付準(zhǔn)備服務(wù)器上的文件,而這時(shí)這些文件正在推送到生產(chǎn)環(huán)境服務(wù)器上。
從構(gòu)建服務(wù)器提送
將構(gòu)建版本從構(gòu)建服務(wù)器直接提送是更好的選擇。這可以消除我上面提到的那種方式中的多種時(shí)間沖突。而且,人們更容易知道被推送的是哪個(gè)版本。
這種方法也有弱點(diǎn):人們很容易選擇錯(cuò)誤的版本推送到生產(chǎn)環(huán)境中。
重新構(gòu)建并推送
第三種選擇是為持續(xù)集成服務(wù)器創(chuàng)建新的構(gòu)建選項(xiàng),其中包括推送到生產(chǎn)環(huán)境這一步。我提醒大家要小心這種方式。雖然理論上重新構(gòu)建的代碼與你測(cè)試的代碼沒有區(qū)別,但還是有某些東西增加了出錯(cuò)的可能性。
另一個(gè)問題是:這讓你可以選擇多種編譯選項(xiàng)。如果你可以選擇,你可能希望在交付準(zhǔn)備服務(wù)器上使用調(diào)試構(gòu)建版本,在生產(chǎn)環(huán)境上使用發(fā)布構(gòu)建版本。如果有些行為在兩個(gè)構(gòu)建配置中有變化,這會(huì)產(chǎn)生災(zāi)難性后果。
雖然使用持續(xù)集成服務(wù)器做配置很容易,但我再次強(qiáng)調(diào):我不推薦人們選擇這種方式。
場(chǎng)景2:加入QA
如果QA加入進(jìn)來,事情就變得非常復(fù)雜了。因?yàn)槟悻F(xiàn)在必須處理跨團(tuán)隊(duì)的溝通和規(guī)劃,你需要更多的構(gòu)建環(huán)境,還有更具意義的所有制感覺。
結(jié)構(gòu)
一旦QA加入,你可能需要至少3個(gè)非生產(chǎn)環(huán)境服務(wù)器。在某些特定條件下,代碼變更從一臺(tái)服務(wù)器提送到下一臺(tái)服務(wù)器。
集成環(huán)境
這是功能代碼簽入后,構(gòu)建版本到達(dá)的第一臺(tái)服務(wù)器。被稱為“集成環(huán)境”,是因?yàn)楹炄牍δ艽a會(huì)與其他功能代碼完全集成。用來現(xiàn)場(chǎng)檢查一個(gè)構(gòu)建版本是否適于提供給QA。這個(gè)環(huán)境中允許不穩(wěn)定,但是不允許構(gòu)建版本停留太長(zhǎng)時(shí)間。
QA環(huán)境
這是QA團(tuán)隊(duì)完成自己大部分工作的地方,根據(jù)需要會(huì)從集成環(huán)境更新代碼。
交付準(zhǔn)備環(huán)境
交付準(zhǔn)備環(huán)境現(xiàn)在完全用作演示和在構(gòu)建進(jìn)入生產(chǎn)環(huán)境前的最后檢查。任何構(gòu)建版本到了這個(gè)環(huán)境,都應(yīng)該是牢固可靠的。交付準(zhǔn)備環(huán)境也許可以連接到生產(chǎn)環(huán)境資源,比如數(shù)據(jù)庫和文件系統(tǒng),但不是必須這么做。
QA交付選項(xiàng)
從構(gòu)建服務(wù)器向集成環(huán)境交付代碼,可以使用基線場(chǎng)景中提到的多種方式之一。從集成到QA環(huán)境就需要?jiǎng)觿?dòng)腦子,因?yàn)樯婕岸鄠€(gè)團(tuán)隊(duì)。下面是我看到的一些成功模式。
開發(fā)者發(fā)起
在“開發(fā)者發(fā)起”模式中,開發(fā)人員決定何時(shí)進(jìn)行編譯檢查和把構(gòu)建版本提送給QA。說得難聽一點(diǎn),當(dāng)QA完全“服從”開發(fā)人員時(shí),可以使用該模式。可能第一眼看上去,這對(duì)開發(fā)人員來說還挺好,實(shí)際上常常陰暗著某種問題。比如:如果發(fā)生某個(gè)質(zhì)量上的問題,QA人員可能要等很長(zhǎng)時(shí)間,等著阻礙他們工作的bug得到解決。
極端情況下,需要設(shè)置自動(dòng)提送機(jī)制,定時(shí)自動(dòng)提送到QA環(huán)境。
QA發(fā)起
這是更適合大部分團(tuán)隊(duì)的典型方式。開發(fā)人員仍然參與,他們需要在集成環(huán)境中檢查他們的構(gòu)建,然后確定構(gòu)建版本是否可以提送。
在這種方式下,QA準(zhǔn)備好測(cè)試新功能時(shí),他們會(huì)拉過來“已知正常”的最新構(gòu)建版本。通常是QA經(jīng)理完成該工作,一般來說他對(duì)于QA人員的需要最了解。雖說如此,有些QA團(tuán)隊(duì)允許所有成員提取新構(gòu)建版本。
Test Runner啟動(dòng)
對(duì)于想真心做好自動(dòng)化測(cè)試的公司來說,這才是目標(biāo)。構(gòu)建版本到達(dá)集成服務(wù)器后,整個(gè)自動(dòng)化測(cè)試套件就開始運(yùn)行。如果全部通過,構(gòu)建版本會(huì)自動(dòng)提送到QA。跟其他自動(dòng)化交付方式一樣,可以采取簽入時(shí)方式或定時(shí)方式。
不要低估這種方式需要投入的成本。不僅需要有完整的測(cè)試套件,所有的測(cè)試必須還都能通過。構(gòu)建服務(wù)器無法區(qū)分測(cè)試失敗是由于新功能出問題,還是說有些問題需要留待將來解決。
變通方式,是把測(cè)試拆分成必須通過(must-pass)的項(xiàng)目和臨時(shí)項(xiàng)目。測(cè)試從臨時(shí)項(xiàng)目開始,特別是在TDD風(fēng)格編程中用到的測(cè)試。只要測(cè)試驗(yàn)證正確、有用,代碼也可以通過這些測(cè)試,就轉(zhuǎn)而處理必須通過的項(xiàng)目。構(gòu)建服務(wù)器不會(huì)運(yùn)行臨時(shí)測(cè)試,但是會(huì)看重必須通過的測(cè)試項(xiàng)目的結(jié)果。
交付準(zhǔn)備/生產(chǎn)環(huán)境交付選項(xiàng)
在持續(xù)交付思想指導(dǎo)下,QA對(duì)于接收到的給定構(gòu)建版本,只有兩個(gè)選項(xiàng):構(gòu)建要么失敗,要么提送到交付準(zhǔn)備服務(wù)器。QA不會(huì)一邊處理一個(gè)可用的構(gòu)建版本,同時(shí)等待某些功能完成
這的確提出一個(gè)問題:如何定義某個(gè)構(gòu)建版本是“可用的”?任何可以安全放到生產(chǎn)環(huán)境的構(gòu)建版本,都是可用的構(gòu)建版本。如果其中有未完成的功能,但這些功能可以以as-is方式工作,那么構(gòu)建就可以往前提送。除非某個(gè)失敗的功能會(huì)影響應(yīng)用在生產(chǎn)環(huán)境中的使用,構(gòu)建版本就不能停滯在QA這里。
進(jìn)入交付準(zhǔn)備服務(wù)器后,構(gòu)建版本在下個(gè)發(fā)布周期中就要提送到生產(chǎn)環(huán)境。盡管持續(xù)部署到生產(chǎn)環(huán)境很難完全實(shí)現(xiàn),還是經(jīng)常聽到成功的每周、甚至每日部署。關(guān)鍵點(diǎn)在于:一旦一個(gè)某件版本證明沒有問題,就需要快速移動(dòng)到生產(chǎn)環(huán)境,這樣團(tuán)隊(duì)就可以聚焦于下一系列要開發(fā)的功能。如果構(gòu)建版本停留在交付準(zhǔn)備階段長(zhǎng)達(dá)幾周乃至幾個(gè)月,就會(huì)造成無盡的問題。
把QA環(huán)境和交付準(zhǔn)備環(huán)境分開,是為了推進(jìn)工作流。只要一個(gè)構(gòu)建版本提送到交付準(zhǔn)備服務(wù)器,下一個(gè)構(gòu)建版本就會(huì)從集成服務(wù)器拉過來。這樣一來,交付準(zhǔn)備服務(wù)器就總會(huì)有一個(gè)穩(wěn)定的環(huán)境,供利益相關(guān)者和其他第三方查看演示版本,同時(shí)QA仍有自己可以工作的環(huán)境。如果把服務(wù)器的職責(zé)混合起來,當(dāng)環(huán)境鎖定時(shí),QA的工作就必須要停下來。
配置相關(guān)問題
一旦有了多個(gè)環(huán)境之后,配置文件就會(huì)成為嚴(yán)重的問題。舉個(gè)例子,交付準(zhǔn)備服務(wù)器必須配置正確,避免發(fā)生諸如發(fā)送測(cè)試郵件給所有用戶,或是通過正式支付網(wǎng)關(guān)下訂單等問題。我曾與一個(gè)剛?cè)腴T的開發(fā)人員一起工作,他當(dāng)時(shí)試圖通過一個(gè)配置錯(cuò)誤的測(cè)試服務(wù)器購(gòu)買幾百萬美元的債券。(幸運(yùn)的是,每張債券的價(jià)格比實(shí)際價(jià)格高,因?yàn)橛唵螞]有成功購(gòu)買。)
出現(xiàn)這種狀況,因?yàn)樯a(chǎn)環(huán)境的配置保存在版本控制系統(tǒng)中,并與應(yīng)用一起部署。這么做,是要防止出現(xiàn)非生產(chǎn)環(huán)境的配置放在版本控制系統(tǒng)中,然后被部署到生產(chǎn)環(huán)境服務(wù)器上的狀況。
要避免上述問題,有個(gè)出人意料的解決方法:不要讓構(gòu)建代理的網(wǎng)絡(luò)賬號(hào)對(duì)配置文件有寫權(quán)限。這樣,如果有人不相信簽入了配置文件,部署將會(huì)失敗,錯(cuò)誤就可以得到糾正。
不過這么做也有自己的問題。用這種方法,只要文件中的配置需要修改,就必須手工操作。如果失敗了,將會(huì)使得環(huán)境出現(xiàn)問題,從而帶來風(fēng)險(xiǎn),因?yàn)閿?shù)據(jù)更新隨時(shí)可能發(fā)生。
關(guān)注點(diǎn)分離和配置文件
“關(guān)注點(diǎn)分離”這個(gè)詞常常用來說明正確的設(shè)計(jì)決策應(yīng)該怎么做,如果認(rèn)真思考誰應(yīng)該負(fù)責(zé)做什么,這種方法也是很有幫助的。比如,負(fù)責(zé)生產(chǎn)環(huán)境技術(shù)支持的人不關(guān)心開發(fā)人員選擇注入哪種日志記錄框架。然而,他們關(guān)心數(shù)據(jù)庫連接串和警告發(fā)送的郵件地址。
我推薦下面這些類型的配置文件。
環(huán)境設(shè)置:與特定環(huán)境相關(guān)的值,必須按照服務(wù)器分開設(shè)置。只有某些重要事件發(fā)生時(shí),才會(huì)需要改動(dòng)它們,比如新數(shù)據(jù)庫或新文件服務(wù)器上線。
代碼作為配置:類似于驅(qū)動(dòng)依賴注入框架的XML文件。雖然看起來像配置文件,但除開發(fā)人員外任何人都不應(yīng)該碰它們。這些文件必須要放在版本控制系統(tǒng)中,而且應(yīng)該把服務(wù)器上的文件標(biāo)記為只讀。
微調(diào)配置:這些配置與環(huán)境無關(guān),但也許生產(chǎn)環(huán)境支持人員需要訪問。可能包括比如批量上傳批次限制、或是web頁面請(qǐng)求超時(shí)設(shè)置等。
這三種配置中,微調(diào)配置需要付出最多精力以保證正確。理想狀態(tài)下,應(yīng)該有缺省配置放在文件中,并保存于版本控制系統(tǒng),并可以根據(jù)特定服務(wù)器修改出多個(gè)文件,并且不必控制這些文件的版本。
配置和培訓(xùn)
避免增加不必要的配置設(shè)置,有一個(gè)技巧:要求為每個(gè)配置項(xiàng)提供文檔和培訓(xùn)。如果不花時(shí)間教給生產(chǎn)環(huán)境支持人員何時(shí)、為何調(diào)整某些值,他們就無法完成這些工作,這些值就成為無法配置的擺設(shè)。
場(chǎng)景3:使用SOA的多個(gè)團(tuán)隊(duì)
使用SOA時(shí),通常采取多團(tuán)隊(duì)方式。比如,一個(gè)團(tuán)隊(duì)構(gòu)建數(shù)據(jù)庫和服務(wù),另一個(gè)團(tuán)隊(duì)處理UI,這種情況很常見。有時(shí),兩個(gè)團(tuán)隊(duì)的工作會(huì)非常緊密,相關(guān)團(tuán)隊(duì)成員會(huì)常常互相交換。有時(shí),團(tuán)隊(duì)可能來自地球兩邊的不同公司。不管他們?cè)趺辞蟹郑镜哪J较嗤?/p>
結(jié)構(gòu)
如場(chǎng)景2,服務(wù)團(tuán)隊(duì)需要一個(gè)地方來測(cè)試構(gòu)建版本,這樣他們不會(huì)對(duì)團(tuán)隊(duì)之外造成負(fù)面影響。同時(shí),UI開發(fā)人員需要一臺(tái)可信的服務(wù)器,能夠一直保持穩(wěn)定,否則他們就無法完成自己的工作。因此,除了我們前面提到的單一團(tuán)隊(duì)場(chǎng)景,有必要加入“開發(fā)環(huán)境”。
不考慮UI集成階段,我們看到的順序與場(chǎng)景2相同。交付選項(xiàng)相同,附加條件是只有UI團(tuán)隊(duì)參與在這個(gè)流程中。UI團(tuán)隊(duì)對(duì)于構(gòu)建版本質(zhì)量的意見比服務(wù)團(tuán)隊(duì)的意見重要。
開發(fā)交付選項(xiàng)
何時(shí)以及如何將代碼交付給開發(fā)環(huán)境,是很多緊張情勢(shì)的來源。有問題的構(gòu)建版本到了QA環(huán)境,QA團(tuán)隊(duì)只要讓其失敗,然后就可以轉(zhuǎn)向其他任務(wù),比如為新功能準(zhǔn)備測(cè)試,或是改進(jìn)回歸測(cè)試。要是有問題的構(gòu)建版本到了開發(fā)環(huán)境,整個(gè)UI團(tuán)隊(duì)就會(huì)發(fā)現(xiàn)自己無法工作了。因此,雖然QA交付中的多種交付模式都可以運(yùn)作,基于自動(dòng)化測(cè)試的方式目前是最成功的模式。
說明:誰編寫集成測(cè)試?
處理分離的服務(wù)層時(shí),提供服務(wù)和消費(fèi)服務(wù)的團(tuán)隊(duì)都要編寫自動(dòng)化測(cè)試,這很重要。提供服務(wù)層的團(tuán)隊(duì)最了解服務(wù)層內(nèi)部機(jī)制,因此能編寫出別人不知道、或是了解其重要性的測(cè)試。
不過,這不能成為消費(fèi)服務(wù)的團(tuán)隊(duì)不寫測(cè)試的接口。他們的測(cè)試覆蓋的場(chǎng)景不僅服務(wù)開發(fā)者想不到,而且能測(cè)試他們對(duì)于服務(wù)層的理解。比如:UI開發(fā)人員會(huì)假定某個(gè)給定調(diào)用永遠(yuǎn)不會(huì)返回null或負(fù)值。測(cè)試過UI使用的所有參數(shù)組合后,他們就可以確保自己的假設(shè)沒有問題。
如果你的公司有QA工程師保佑,而不僅僅是只有QA分析人員,他們會(huì)發(fā)現(xiàn)自己也要針對(duì)服務(wù)層開發(fā)自動(dòng)化測(cè)試。這常常與自動(dòng)化UI測(cè)試連在一起,特別是動(dòng)作結(jié)果不需要通過用戶界面驗(yàn)證的時(shí)候。
場(chǎng)景4:采用并行功能開發(fā)的多個(gè)團(tuán)隊(duì)
這種情況很棘手。目前,前面提到的各個(gè)場(chǎng)景都假定只有一個(gè)單獨(dú)的開發(fā)主干。一旦開始處理多個(gè)開發(fā)團(tuán)隊(duì)針對(duì)同一代碼庫并行開發(fā),就必須決定何時(shí)、如何將功能代碼從團(tuán)隊(duì)分支轉(zhuǎn)移到基本開發(fā)主干中。下面兩種模型是我見過的成功范例。
功能推送模型
在該模型中,不管何時(shí),只要確定沒有問題,每個(gè)團(tuán)隊(duì)都會(huì)把自己的變更推送到主干中。該模型的優(yōu)點(diǎn)在于:團(tuán)隊(duì)可以自給自足。
合并-推送
該模型中最常用的策略是:在本地合并及測(cè)試。只要測(cè)試通過,修改的部分就可以推送到主分支。
該模型最大的風(fēng)險(xiǎn)是缺乏原子合并。很可能某個(gè)團(tuán)隊(duì)修改了某個(gè)函數(shù)的名字或簽名,而另一個(gè)團(tuán)隊(duì)正在加入新的文件使用了同一個(gè)函數(shù)。如果兩個(gè)更改同時(shí)簽入,構(gòu)建版本就會(huì)失敗,而且版本控制系統(tǒng)不會(huì)報(bào)告任何沖突。
鎖定-合并-推送
該方式需要版本控制系統(tǒng)支持鎖定。推送新的構(gòu)建版本時(shí),主干應(yīng)該是鎖定的。新的功能要在本地與主干合并,完成冒煙測(cè)試,然后推送到主干。雖然合并的問題可以在鎖定時(shí)解決,任何測(cè)試的失敗必須馬上把鎖釋放掉。
功能拉模型
該模型中,團(tuán)隊(duì)永遠(yuǎn)不能發(fā)布他們的變更。相反,變更控制團(tuán)隊(duì)的人負(fù)責(zé)將功能拉入到主干中。這樣一來,QA團(tuán)隊(duì)就只會(huì)接收到他們準(zhǔn)備好測(cè)試的變更。
功能拉模型需要高級(jí)的版本控制系統(tǒng),支持集成工作項(xiàng)跟蹤。僅僅給變更打上任務(wù)號(hào)是不夠的,成員必須要說明“將功能X合并入分支Y”,并讓版本控制系統(tǒng)識(shí)別所有需要的變更。這可以手工完成,但是會(huì)耗費(fèi)很長(zhǎng)時(shí)間,而且很容易出錯(cuò)。
對(duì)于簡(jiǎn)單的合并,變更控制工程師可以自己一個(gè)人搞定。復(fù)雜的合并,特別是團(tuán)隊(duì)們沒有定期更新自己分支的情況下,需要開發(fā)相關(guān)功能的團(tuán)隊(duì)協(xié)助合并工作。
結(jié)構(gòu)
不管功能特性如何進(jìn)入主干,結(jié)構(gòu)都是一樣的。每個(gè)團(tuán)隊(duì)都有自己的集成環(huán)境,他們會(huì)不斷發(fā)布,就像基線場(chǎng)景一樣。這些團(tuán)隊(duì)特定的集成環(huán)境向通用集成環(huán)境導(dǎo)入代碼,然后就走正常流程了。
修正補(bǔ)丁(hot fix)如何處理?
所有這些場(chǎng)景中,我們都沒有提到修正補(bǔ)丁的概念。這是有意為之,如果遵循持續(xù)交付的思想和理念,是沒有所謂的修正補(bǔ)丁的。一旦變更進(jìn)入集成環(huán)境,它們就會(huì)很快進(jìn)入生產(chǎn)環(huán)境。在這個(gè)理論下,不需要修正補(bǔ)丁,只有正常的bug修復(fù),其優(yōu)先級(jí)偶爾會(huì)超過功能特性的開發(fā)。
然而,現(xiàn)實(shí)世界不是完全由理論指導(dǎo)的。功能常常會(huì)停滯在QA階段,其時(shí)間超過預(yù)期,要么是質(zhì)量問題,或者僅僅是因?yàn)樗鼈兊囊?guī)模。與之類似,生產(chǎn)部署也可能延遲,因?yàn)闃I(yè)務(wù)需要,比如合同強(qiáng)制要求,或是早已公之于眾的特定日期升級(jí)計(jì)劃。類似事件發(fā)生時(shí),修正補(bǔ)丁就有必要了。此時(shí),最佳方案是拋開流程,完成工作優(yōu)先。不要讓形式成為公司和客戶不必要的負(fù)擔(dān)。一旦塵埃落定,危機(jī)解決,就可以開始研究問題發(fā)生的根本原因了。
持續(xù)交付的目標(biāo),不是要讓修正補(bǔ)丁更易于處理,而是要制定出編碼和測(cè)試的標(biāo)準(zhǔn),消除對(duì)修正補(bǔ)丁的需要。每次流程失敗的時(shí)候,就是你學(xué)習(xí)如何改進(jìn)代碼標(biāo)準(zhǔn)和測(cè)試實(shí)踐的機(jī)會(huì),避免重大bug再次發(fā)生。同樣地,這也能為你提供理由,檢查日程表制定方針中的缺陷,看看是什么導(dǎo)致流程的停滯和問題。如果無法同時(shí)在這兩方面聚焦,你就永遠(yuǎn)不能保證所有的bug修復(fù)都可以通過嚴(yán)格控制的流程。
簡(jiǎn)而言之,持續(xù)改進(jìn)是任何形式的持續(xù)交付的根本組件。
關(guān)于作者
Jonathan Allen從2006年開始就為InfoQ撰寫新聞報(bào)道,目前是.NET領(lǐng)域的首席編輯。如果您希望為InfoQ編寫新聞或是有價(jià)值的文章,請(qǐng)通過jonathan@infoq.com聯(lián)系他。
it知識(shí)庫:持續(xù)交付模式,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。