在過去十年或更長的時間中,軟件開發(fā)團隊一直受益于敏捷開發(fā)方法。他們采用這些迭代和增量開發(fā)實踐,通過協(xié)作式開發(fā)推動解決方案的發(fā)展。傳統(tǒng)的、非敏捷的軟件創(chuàng)建方法通常依賴于一個更嚴(yán)格管制的開發(fā)流。瀑布流程就是這方面的一個示例,其中需求、設(shè)計、開發(fā)和測試的每個活動都是連續(xù)執(zhí)行的。 雖然瀑布式開發(fā)多年來一直是大型的復(fù)雜系統(tǒng)開發(fā)的標(biāo)準(zhǔn),但它有幾個明顯的缺陷。首先,即使需求會隨時間而變化是眾所周知的,但開發(fā)人員仍會努力在設(shè)計前完成文檔,在編寫代碼前完成設(shè)計,其中有大量工作被浪費。另一個缺陷是,將測試和集成一直延遲到項目結(jié)束時才執(zhí)行,問題往往發(fā)現(xiàn)得太晚,如果要解決問題,則有可能導(dǎo)致錯過最后期限。這兩個因素結(jié)合起來,在以較慢速度發(fā)展的世界中,也許可以容忍。但是,隨著創(chuàng)建創(chuàng)新系統(tǒng)的壓力的增加,這種方法的滿足組織需求的能力在下降。 雖然敏捷實踐是由開發(fā) IT 系統(tǒng)的團隊推廣的,但它們同樣適用于產(chǎn)品開發(fā),其中的產(chǎn)品包括硬件、電子和軟件。嵌入式軟件開發(fā)與 IT 應(yīng)用程序開發(fā)的主要區(qū)別在于部署目標(biāo)資源(如處理器性能和內(nèi)存)的有限可用性。嵌入式軟件往往要在這些約束條件中執(zhí)行復(fù)雜的實時操作。想像一下計算機控制的系統(tǒng),例如汽車?yán)锏陌踩珰饽?。您需要他們立即部署,但需要的是可靠的部署。敏捷方法最初專為不受管制的行業(yè)中的在同一地點工作的較小型項目團隊而設(shè)計。我們花了很多年對它們進(jìn)行擴展,使敏捷方法可以容納更大、更復(fù)雜的開發(fā)項目。 當(dāng)應(yīng)用為基于架構(gòu)的方法的一部分時,持續(xù)集成(CI)和測試驅(qū)動的開發(fā)(TDD)擴展了基本敏捷實踐,使之足以同時提供高品質(zhì)和項目靈活性。本文將探討在嵌入式軟件開發(fā)的上下文中如何采用敏捷方法、CI、TDD。本文還說明了這個組合的好處。 如何將持續(xù)集成和測試驅(qū)動的開發(fā)融入敏捷實踐中現(xiàn)在,大多數(shù)人可能都已經(jīng)聽說過敏捷方法。它們帶給軟件開發(fā)的概念改變了團隊組織的工作方式、適應(yīng)不斷變化的需求的方式以及發(fā)布軟件的方式。持續(xù)集成(CI)是為敏捷開發(fā)而創(chuàng)建的,所以敏捷方法是任何 CI 討論的背景。它將開發(fā)組織為功能性用戶故事(user story)。這些故事按優(yōu)先級分成較小的工作組,也稱為沖刺(sprint)。 這里的思路是不要提前嘗試解決每一個問題,相反,專注于您已經(jīng)知道的東西。因此,團隊設(shè)計、構(gòu)建和測試他們對預(yù)期功能所知道的內(nèi)容。這將在完整產(chǎn)品需求的一個子集的基礎(chǔ)上創(chuàng)建一個工作產(chǎn)品。然后,團隊繼續(xù)到下一個最高優(yōu)先級的需求集,并重復(fù)上述過程。當(dāng)然,這是一個高度簡化的視圖,這個過程中有許多變化,但核心是:以增量方式構(gòu)建您的產(chǎn)品,并嘗試在過程中做一些改進(jìn)。 根據(jù) ThoughtWorks 的 Martin Fowler 的觀點,持續(xù)集成(continuous integration)是一種軟件開發(fā)實踐,要求團隊成員經(jīng)常集成他們的工作。每個人至少每天集成一次,這導(dǎo)致每天有多個集成。集成是通過自動化的構(gòu)建進(jìn)行驗證的,這些構(gòu)建運行回歸測試,以盡快檢測集成錯誤。團隊發(fā)現(xiàn),這種方法會導(dǎo)致集成問題大幅減少,更快地實現(xiàn)有凝聚力的軟件開發(fā)。 這導(dǎo)致 CI 流程的成功執(zhí)行的最終細(xì)節(jié)。如果持續(xù)集成的思路是為了快速發(fā)現(xiàn)問題,從而向每個開發(fā)人員提供工作反饋,則必須以某種方式快速評估其工作。測試驅(qū)動的開發(fā)填補了這項空白。利用 TDD,您可以構(gòu)建測試,然后等代碼通過測試后再開發(fā)功能。隨著每一個新代碼的添加,可以將它的測試添加到在構(gòu)建集成工作時運行的測試套件中。這將確保新增內(nèi)容不會破壞之前出現(xiàn)的運作中的工作,并且事實上 “破壞了構(gòu)建” 的代碼的開發(fā)人員可以迅速獲得通知。在圖 1 中顯示了持續(xù)集成和測試驅(qū)動的開發(fā)的典型組合。 圖 1. 使用持續(xù)集成和測試驅(qū)動開發(fā)的敏捷實踐受益于持續(xù)集成的項目類型少于 50 人,處理不太復(fù)雜的項目的團隊絕對是敏捷開發(fā)和 CI 的試驗場。但因為產(chǎn)品已變得 “更智能”,其復(fù)雜性也會明顯增加。 進(jìn)入傳統(tǒng)產(chǎn)品的嵌入式軟件的數(shù)量是驚人的。如今,一輛新汽車已較少以其馬力作為賣點,而是以其嵌入式軟件技術(shù)(例如,自動泊車、先進(jìn)的安全警告、燃油效率、信息娛樂系統(tǒng))作為賣點。為創(chuàng)建一輛新汽車而編寫的代碼行數(shù)多于為 F16 戰(zhàn)斗機所編寫的代碼行數(shù)。 產(chǎn)品復(fù)雜性的增加,同時加速了新產(chǎn)品的上市時間。嵌入式軟件的普及,結(jié)合更嚴(yán)格的最后期限,這些將敏捷實踐和 CI 帶到了嵌入式開發(fā)人員的面前。 使用敏捷方法實現(xiàn)嵌入式系統(tǒng)開發(fā)敏捷方法讓軟件和系統(tǒng)團隊能夠快速響應(yīng)變化。敏捷方法減少了與傳統(tǒng)的軟件工程相關(guān)聯(lián)的時間進(jìn)度風(fēng)險,在傳統(tǒng)方法中,組件的集成被視為后期階段的工作。后期階段的集成會引起對設(shè)計規(guī)范的誤解,在發(fā)現(xiàn)問題時,對于要解決該問題同時又要滿足其最后期限的團隊而言,已經(jīng)為時已晚。 然而,系統(tǒng)團隊要生成的不僅僅是軟件組件,他們對敏捷方法的某些方面持懷疑態(tài)度。他們說,刪除過多的早期規(guī)劃,最后就會獲得糟糕的軟件和硬件集成。如果沒有早期的、經(jīng)常的檢查點來根據(jù)架構(gòu)藍(lán)圖驗證進(jìn)度,團隊可能無法生成可在更廣泛的系統(tǒng)中正常運作的組件。此外,對于正在尋求設(shè)計的可重用性和可擴展至較大型項目需求的復(fù)雜系統(tǒng)的開發(fā)人員來說,敏捷方法看起來可能存在局限性。 這些擔(dān)心是可以理解的,因為建模和架構(gòu)不是敏捷技術(shù)的特點。但系統(tǒng)開發(fā)的 CI 方法對純敏捷方法提供了多項改進(jìn)。CI 幫助系統(tǒng)開發(fā)團隊變得敏捷,并且能夠響應(yīng)快速的業(yè)務(wù)變化,在同一時間確保正在開發(fā)的實際硬件和軟件都在不斷同步。CI 使得團隊成員能夠在自己的領(lǐng)域組中有效地工作,集中精力于他們最擅長的任務(wù)。在每天結(jié)束時,他們知道,他們對項目的貢獻(xiàn)被集成,并且各組件可以一起工作。如果有哪個組件無法集成,該組件很快就會被發(fā)現(xiàn)。 讓我們來考慮復(fù)雜系統(tǒng)開發(fā)和交付的一些必不可少的組成部分,并探討 CI 如何有助于迎接挑戰(zhàn)。 架構(gòu)當(dāng)您正在構(gòu)建復(fù)雜系統(tǒng)時,如果沒有藍(lán)圖,就無法不斷添加新的特性。如果沒有藍(lán)圖,那么在利用額外的迭代時,就會遭遇更多返工的情況。不管您將它稱為藍(lán)圖、模型還是架構(gòu),它都提供一個開始迭代過程的堅實基礎(chǔ)。 架構(gòu)在最多 50 名團隊成員的較小型項目中很有幫助,但是,如果超出了這個規(guī)模,就必須做一些前期工作,以了解組件化、重用和可變性。此前期分析使您可以拆分團隊,但仍發(fā)布協(xié)調(diào)的產(chǎn)品。在讓硬件和軟件開發(fā)人員一起工作也是這樣,就像對包括嵌入式軟件的復(fù)雜系統(tǒng)一樣。 仿真 通過在仿真模型中捕獲架構(gòu),團隊可以看到系統(tǒng)如何響應(yīng)不同的輸入。這種形式的早期測試可以驗證系統(tǒng)是否如預(yù)期般執(zhí)行,從而滿足要求。這也使得設(shè)計人員能夠可視化設(shè)計的任何意想不到的后果。在檢查代碼文本時,很難看出這些意想不到的后果。當(dāng)查看系統(tǒng)模型時,它們會變得明顯得多,在查看工作中的系統(tǒng)模型時,它們甚至變得更加明顯。 在這種方式中,建模和仿真讓測試和集成可以在設(shè)計工作開始時就立刻開始執(zhí)行,從而消除了在嵌入式硬件尚未可用時可能遇到的延遲。它可以節(jié)省對那些不可行的早期架構(gòu)原型所進(jìn)行沒有必要的大量投資。即使您的確有可用的硬件,持續(xù)集成也要求不斷地構(gòu)建。 越早需要看到結(jié)果,構(gòu)建環(huán)境就會變得越昂貴。由于 CI 的主要目的是盡可能快地提供結(jié)果,仿真使您能夠在無需支付超高硬件成本的情況下進(jìn)行測試。它還提供了一個更簡單的方法來溝通組件的功能,這對于敏捷開發(fā)中常見的結(jié)對編程和 “代碼審查” 非常有價值。 構(gòu)建自動化持續(xù)集成要求構(gòu)建自動化,也就是說,提供讓軟件自動編譯和鏈接到可執(zhí)行文件的能力。速度非常重要,因為大型構(gòu)建可能需要很長時間。如果沒有快速、可靠的構(gòu)建,就會缺乏解決集成問題所需的洞察力。在運行集成構(gòu)建時,會識別由兩位或多位開發(fā)人員所做的更改之間的沖突,以便解決該沖突。所以,如果發(fā)現(xiàn)問題,要解決前一個構(gòu)建的沖突的開發(fā)人員可以通過硬件仿真來測試更改后的代碼,不會耽誤其他開發(fā)人員的工作。但是,要實現(xiàn)這種效率,則必須不斷進(jìn)行集成構(gòu)建,在上一個構(gòu)建完成時就立刻開始新的構(gòu)建。這與其他流程所使用的每天一次或每周一次的構(gòu)建非常不同。 當(dāng)然,這種方法要求構(gòu)建自動化,因為要將一天中反復(fù)多次開始構(gòu)建的任務(wù)指定給一個人是不切實際的。此外,構(gòu)建應(yīng)快速執(zhí)行,這往往要求構(gòu)建是多線程的。多線程的構(gòu)建可以使用軟件的不同組件,利用在某個其他組件上運行的構(gòu)建并行地執(zhí)行這些組件,從而加快匯總的構(gòu)建時間。它的確需要更多硬件和更復(fù)雜的腳本。腳本變得越復(fù)雜,構(gòu)建管理工具就會變得越有價值。 工作管理 主要的敏捷概念是將工作拆分成為易于管理的小塊的價值。這也是 CI 的基本前提:及早地、經(jīng)常地改正錯誤。這樣就可以避免它們稍后在項目中發(fā)展成為更大、更難解決的問題。 該技術(shù)提供的好處之一是能夠提供在項目時間表中多個日期進(jìn)行構(gòu)建和測試的更小的功能性發(fā)布。通過驗證來自團隊的架構(gòu)、需求和時間表估算,每個交付都降低了項目風(fēng)險。在敏捷方法中,尚未完成的工作被稱為積壓(backlog)工作。如果您開始將工作分配給小交付增量(被稱為沖刺),分配給某個沖刺的工作被稱為沖刺積壓(sprint backlog)。分配給未來沖刺的剩余工作被稱為項目積壓(project backlog)。目標(biāo)是將在沖刺定義的時間內(nèi)可以實現(xiàn)的盡可能多的工作項分組到?jīng)_刺中。 此流程高度依賴于指標(biāo)的收集,使團隊可以更準(zhǔn)確地預(yù)測任務(wù)所需的時間量,并推算出可以放入某個沖刺交付的任務(wù)量。然而,與這些指標(biāo)等價的是,數(shù)據(jù)收集即使對于小團隊也非常繁瑣。當(dāng)您將這些小團隊組合在一起來產(chǎn)生更加復(fù)雜的產(chǎn)品時,任務(wù)會相當(dāng)龐大,且無法手工完成。 市場上有很多產(chǎn)品可以幫助組織完成其工作,跟蹤工作的完成狀況,并生成與工作完成了多少、完成的速度、完成的質(zhì)量等有關(guān)聯(lián)的指標(biāo)。如果遵循了 CI 實踐,則必須將所確定的集成錯誤迅速添加到工作積壓中,并作為高優(yōu)先級移動到列表的頂部。在這方面,在市場上最好的產(chǎn)品提供了新工作項和構(gòu)建管理系統(tǒng)之間某種程度的集成,因此,在每個構(gòu)建后識別的錯誤就可以迅速得到修復(fù),并與現(xiàn)有工作項集成,優(yōu)先升級,并路由到正確的團隊。 質(zhì)量管理質(zhì)量管理是確保所有產(chǎn)品要求均已經(jīng)過測試的開發(fā)生命周期實踐。該工作需要得到組織和理解,使正確的測試可以在需求變更時得到更新。質(zhì)量管理有助于項目經(jīng)理回答以下問題:
在面對加快交付周期的市場壓力時,快速回答這些問題可以幫助業(yè)務(wù)充滿信心地將產(chǎn)品發(fā)布到市場。管理人員可以更好地了解要添加哪些資源、在何處調(diào)整產(chǎn)品特性,以及何時重新建立交付日期,從而獲得最大優(yōu)勢。 利用測試驅(qū)動的開發(fā),測試的概念對于開發(fā)工作更加重要。在 TDD 中,需要根據(jù)需求編寫測試,然后開發(fā)代碼,直到它通過測試。這將確保沒有創(chuàng)建額外的功能,即開發(fā)團隊稱為 “鍍金” 的東西。即使額外的功能或特性似乎是一個好主意,但在不要求驅(qū)動決策時,額外的工作可能會提高成本,并增加交付時間。最終產(chǎn)品可能并沒有實際提高客戶滿意度。 自動測試 在創(chuàng)建多個構(gòu)建后,團隊需要重新測試之前的版本中的可行功能。這個重新測試的流程以前被稱為 “好代碼(good code)”,現(xiàn)在稱之為回歸測試(regression testing)。它確保沒有因為剛剛完成的變更而將錯誤引入或重新引入之前測試過的代碼。利用 CI,可以將自動的回歸測試編寫為腳本,在每個構(gòu)建結(jié)束時運行。這使得開發(fā)人員能夠得到有關(guān)在在新構(gòu)建中發(fā)現(xiàn)的錯誤的即時反饋。這一步是為了通知開發(fā)人員,他們所生產(chǎn)的新代碼在按要求(或沒有按要求)工作。如果沒有回歸測試,開發(fā)人員只知道構(gòu)建已完成。由于無論如何都必須創(chuàng)建測試,所以 TDD 并沒有添加額外的工作。它只是將工作的順序顛倒了,首先創(chuàng)建測試,然后編寫代碼。 即使沒有任何自動化測試,傳統(tǒng)的瀑布式開發(fā)項目也是有可能生存的。可以描述和構(gòu)建項目,然后讓一大堆人不斷對其進(jìn)行測試。但只要您開始定期發(fā)布,這一流程就會出現(xiàn)問題。手動測試一個在一天中被多次構(gòu)建的系統(tǒng)是不可行的。 協(xié)作IBM? Rational? 軟件組織長期以來一直主張協(xié)作是成功的系統(tǒng)開發(fā)和交付的一個關(guān)鍵因素。但在軟件和硬件團隊都參與的 CI 中,協(xié)作不僅包括從一個團隊到另一個團隊的有效構(gòu)件移交,還包括對要求、特性和最后期限之間的權(quán)衡的全面協(xié)調(diào)的理解。 良好的架構(gòu)可以支持這種協(xié)作,部分原因是人們可以更好地了解他們正在構(gòu)建的各個組件之間的依賴關(guān)系。利用項目組合管理,您可以了解特性、重用和資源分配。但在合作開發(fā)的硬件和軟件項目中,管理要求并制定有關(guān)何時可以更改這些要求以及何時不得更改它們的明智決策也很重要。 這些項目通常涉及決策的多個層次中的多個利益相關(guān)者。良好的協(xié)作有助于滿足更大比例的利益相關(guān)者。它可以確保創(chuàng)建了正確的產(chǎn)品,并且可以快速識別來自更廣泛的目標(biāo)的偏差。這將產(chǎn)生可以更好地滿足客戶需求的產(chǎn)品。 結(jié)束語從技術(shù)角度來看,CI 可以幫助團隊更高效地工作。這些團隊可能是跨職能的,創(chuàng)建配合工作的硬件和軟件。他們在地理上可能是分散的,因為不斷的集成工作將會確保您沒有偏離設(shè)計。人們可以在大型團隊中工作,因為復(fù)雜系統(tǒng)的不同組件將以更可靠的方式一起工作。CI 解決了許多非傳統(tǒng)的敏捷團隊在沒有 CI 時可能都經(jīng)歷過的早期陷阱。CI 與測試驅(qū)動的開發(fā)相結(jié)合使更多人可以利用敏捷,因為它可以讓敏捷方法更高效地工作。 從業(yè)務(wù)的角度來看,CI 可以提供更好的業(yè)務(wù)成果,讓團隊可以擁有自己的蛋糕并吃掉它。也就是說,通過在問題的早期并且在問題還是小問題時發(fā)現(xiàn)它們,而不是等到這些問題變成大問題且更難解決時才發(fā)現(xiàn)它們,團隊可以將產(chǎn)品更快地推向市場。他們還可以在產(chǎn)品開發(fā)過程中更好地響應(yīng)所引入的需求。敏捷開發(fā)將為客戶創(chuàng)建更好的產(chǎn)品,這才是敏捷性的真正承諾。 |
|