因此,做為最基本的持續集成實(shí)踐,請保證你使用一款體面的代碼管理系統。成本不是問(wèn)題,有許多高質(zhì)量的開(kāi)源代碼管理工具存在。當前的選擇為Subversion(譯者注:現在有了更新的hg和git)。(更老的開(kāi)源工具CVS如今仍然被大量使用,雖然比沒(méi)有強,但是Subversion是更現代的選擇。)有趣的是,當我和一些開(kāi)發(fā)者聊天時(shí),我發(fā)現相比起多數商業(yè)化的代碼管理系統,他們更喜歡Subversion。據我所知,唯一值得花錢(qián)買(mǎi)的只有Perforce。
當你有了代碼管理系統之后,確保每個(gè)開(kāi)發(fā)者都能方便的獲得到源代碼。不應該有人還在問(wèn):“foo-whiffle 文件在哪兒?”所有東西都必須在代碼庫里。
雖然許多團隊都在使用代碼庫,但是我經(jīng)常發(fā)現,他們并不把所有東西都放在里面。如果大家需要使用一個(gè)文件,他們知道該文件放到代碼庫中,但是,構建所需的所有都應該包含在代碼庫里,包括測試腳本,屬性文件,數據庫模式文件,安裝腳本和第三方庫等。我所知道的有項目將編譯器加到代碼庫中的(對于早期脆弱的C++編譯器來(lái)說(shuō)非常重要)?;驹瓌t是:在一臺新機器上check out代碼后構建也能構建成功。新機器上的東西應該盡量的少,通常包括很大的,難于安裝的,并且穩定的軟件,比如操作系統,Java開(kāi)發(fā)環(huán)境或者數據庫管理系統等。
你需要將構建所需的所有東西都加到代碼管理系統中,同時(shí)也需要將大家經(jīng)常操作的東西方進(jìn)去,IDE配置便是一個(gè)很好的例子,這樣便于大家共享IDE配置。
版本控制系統的一大功能是它允許你創(chuàng )建多個(gè)分支,以此來(lái)處理不同的“開(kāi)發(fā)流”。這種功能很有用,但卻經(jīng)常被過(guò)度使用以至給開(kāi)發(fā)者帶來(lái)了不少麻煩。所以,你需要將分支的使用最小化,特別建議使用主線(xiàn),即項目中只有單一的開(kāi)發(fā)分支,并且每人在多數時(shí)間里都在“離線(xiàn)”工作。
總之,你應該將構建所需的所有東西都放在代碼管理系統中,而不應該將構建的輸出放進(jìn)去。有些朋友確實(shí)將構建輸出放在代碼管理系統中,但我認為這是一個(gè)壞味道,可能導致更深的問(wèn)題——通常是你無(wú)法完成重新構建。
使構建自動(dòng)化
將源代碼變成一個(gè)能運行的軟件系統通常是一個(gè)復雜的過(guò)程,包括編譯,文件搬移,加載數據庫模式等等。但其中大多數任務(wù)都是可以自動(dòng)化的,并且也應該被自動(dòng)化。讓人去輸入奇怪的命令或點(diǎn)擊對話(huà)框是非常耗時(shí)的,而且從根本上來(lái)說(shuō)也是個(gè)錯誤的做法。
構建所需的自動(dòng)化環(huán)境對于軟件系統來(lái)說(shuō)是一個(gè)通用功能。Unix的Make已經(jīng)誕生好多年了,Java社區有Ant, .NET社區有Nant,現在又有了MSBuild。當你用這些工具構建和啟動(dòng)系統時(shí),請確保只使用一個(gè)命令完成任務(wù)。
一個(gè)常見(jiàn)的錯誤是在自動(dòng)化構建里并沒(méi)有完全包括構建所需的東西。構建過(guò)程中應該從代碼庫里取得數據庫模式文件并自動(dòng)執行之。結合我上文所講的原則來(lái)看,任何人都應該能夠在一臺新機器上拉下代碼庫中的代碼,并只用一個(gè)命令將系統運行起來(lái)。
構建腳本是多種多樣的,通常特定于某個(gè)平臺或社區,但情況并不必須如此。我們的多數Java項目都使用Ant,而另外有些用Ruby(Ruby世界的Rake是一個(gè)非常不錯的構建工具)。我們用Ant完成了早期的一個(gè)微軟COM工程的構建自動(dòng)化,并從中大獲裨益。
大型的構建通常需要很長(cháng)的時(shí)間,而在你只做了很小的修改的情況下,你是不想運行所有的構建步驟的。因此,優(yōu)秀的構建工具能夠分析出哪些地方需要做相應的修改,并將這個(gè)分析過(guò)程本身做為整個(gè)構建過(guò)程的一部分。通常的做法是檢查源代碼和目標文件的修改日期,只有當源代碼的修改日期晚于其對應的目標文件時(shí)才執行編譯。依賴(lài)關(guān)系因此變得微妙起來(lái)了:如果一個(gè)目標文件發(fā)生了修改,那些依賴(lài)于它的文件也需要重新構建。有些編譯器能夠處理這種依賴(lài)關(guān)系,而有些就不見(jiàn)得。
根據自己的需要,你可以選擇不同的東西進(jìn)行構建。構建中既可以包括測試,也可以不包括,甚至可以包括不同的測試板塊。有些組件可以進(jìn)行單獨構建。構建腳本應該能夠允許你針對不同的情形進(jìn)行不同的構建目標。
我們大多數都使用IDE,而多數IDE都或多或少地集成了構建管理功能。但是這樣構建文件通常是特定于IDE的,而且非常脆弱。此外,它們需要依賴(lài)于IDE才能工作。雖然對于開(kāi)發(fā)者個(gè)人來(lái)說(shuō),在IDE中做這樣的構建配置并無(wú)不妥,但對于持續集成服務(wù)器來(lái)說(shuō),一份能夠被其它腳本調用的主構建腳本卻是至關(guān)重要的。比如一個(gè)Java項目,各個(gè)開(kāi)發(fā)者可以在自己的IDE中進(jìn)行構建,但應該還有一個(gè)Ant主構建腳本來(lái)保證構建能在集成服務(wù)器上順利完成。
使構建自測試
傳統意義上的構建包括只編譯,鏈接等過(guò)程。此時(shí)程序也許能運行起來(lái),但這并不意味著(zhù)系統就能正確地運行。雖然現在的靜態(tài)語(yǔ)言已經(jīng)能夠捕捉到許多bug,但是漏網(wǎng)之魚(yú)卻更多。
一種快速并高效發(fā)現bug的方法是將自動(dòng)化測試包含到構建過(guò)程中。當然,測試也不見(jiàn)得完美,但的確能發(fā)現很多bug——足夠多了。特別是隨著(zhù)極限編程(XP)的升溫,測試驅動(dòng)開(kāi)發(fā)(TDD)也使自測試代碼流行起來(lái),越來(lái)越多的人開(kāi)始注意到這種技術(shù)的價(jià)值所在。
經(jīng)常讀我著(zhù)作的讀者可能知道我是一個(gè)TDD和XP的大粉絲,然而我想強調的是這兩種方法和自測試并沒(méi)有必然聯(lián)系。TDD和XP都要求先寫(xiě)測試代碼,再寫(xiě)功能代碼使測試通過(guò)。在這種模式下,測試既用于發(fā)現bug,又用于完成系統設計。這是非常好的,但對于持續集成來(lái)說(shuō)不必如此,因為此時(shí)我們自測試代碼的要求并不那么高。(然而TDD是我寫(xiě)自測試代碼的首選。)
對于自測試代碼而言,你需要一組自動(dòng)化測試來(lái)檢測一大部分代碼庫中的bug。測試能通過(guò)一個(gè)簡(jiǎn)單的命令來(lái)運行并且具備自檢功能。測試的結果應該能指出哪些測試是失敗的。對于自測試的構建來(lái)說(shuō),測試失敗應導致構建失敗。
過(guò)去這些年里,TDD使開(kāi)源的XUnit家族流行起來(lái),成為了理想的測試工具。在ThoughtWorks,XUnit已經(jīng)是非常有用的測試工具,我也經(jīng)常建議人們使用。這組工具起初由Kent Beck開(kāi)發(fā),它們使自測試環(huán)境的搭建變得非常簡(jiǎn)單。
XUnit當之無(wú)愧地是你進(jìn)行代碼自測試的起點(diǎn)。當然,你也應當多看看那些更側向于端到端測試的工具,包括FIT,Selenium,Sahi,Watir,FITnesse等等,我就不逐一列舉了。
原文轉自:http://kjueaiud.com