持續交付與傳統敏捷的矛盾
我在采用持續交付的組織中和開發團隊工作一起工作,發現很多開發者認為的正確的敏捷團隊的工作方式,在這里跑得不是很順暢。我認為傳統敏捷與持續交付的矛盾的根本在于,二者是采用不同的方式把軟件變得“可以發布“(ready to release)的。
軟件交付的演進
使軟件變得可以發布的過程一直在不停進化,下面是一個簡要的介紹:
瀑布模型
瀑布模型認為,當一個軟件所有的功能都發開完畢的時候(也就是功能完整的時候),才可以發布。
敏捷:
敏捷引入的思想是,在整個開發過程中,軟件都應該“可以發布”。許多敏捷的版本(在這篇文章里被稱為傳統敏捷)都認為,“可以發布”應該在固定周期的間隔點上完成。
持續交付:
持續交付是敏捷的一個子集,在持續交付中團隊會保持軟件在開發過程的所有時間內都可以發布。它和傳統敏捷不同之處在于,持續交付在開發過程中不會有停下來然后創建發布版本的過程。
持續性交付不是指更短的周期
從傳統的敏捷開發流程變成可持續性交付,不是指把軟件發布的周期變短。每天晚上做發布版本仍然不是可持續性交付。可持續性交付是說要把”做可以發布的軟件”這個動作本身從開發過程中去掉,取而代之的是保持軟件在開發的過程中始終是可以發布的。
可以發布不是意味著真正的發布
有一個普遍的誤解是可持續性交付就是非常頻繁地發布出產品。而當一些組織把每天數次發布軟件當作是持續交付的標桿時,就更加深了這一誤解。可持續性交付不是一定要頻繁的發布,它只是要求在開發過程中的任何一個點上,用非常少的工作,軟件就能夠發布(可參考Jez Humble的文章,可持續性交付VS可持續性部署)。盡管具備這一能力為更加頻繁的發布敞開了大門,但是許多團隊還是從持續交付的實踐中,找到了壓倒性的證據,來證明即便發布不是很頻繁時,持續交付也是有用的。
持續交付和傳統敏捷的沖突點
我前面講過,有時候持續交付和開發團隊所認為是“正確”的敏捷實踐流程有一些矛盾。
沖突點:當有工作沒有完成時,軟件依然是可發布的
其中一個沖突點是,一個迭代結束時,代碼庫中是否可以包含未完成的用戶故事(user stories)或者bug修復。我在上一篇關于迭代的帖子中做了探討。這個問題主要是源于,傳統敏捷認為在迭代結束時,team停止開發,并且來做準備軟件發布的一些額外工作,但是,如果團隊采用持續交付,讓軟件可發布就沒什么額外的工作需要做。
更有甚者,持續交付團隊甚至認為,通過使用功能切換等技術,他們的代碼即使在還有功能沒有完成也可以發布成產品。這也從另外一個方面說明,團隊在迭代結束時能夠達到可以發布的要求,即使有未完成的用戶故事。
這可能稍微有點難理解,團隊肯定還是可以要求在迭代結束點上所有的工作都必須完成,但是這容易讓人感覺是團隊原有的正常開發的節奏被隨便打斷了。持續交付不是要求沒有時間盒的迭代,這兩種實踐其實是互補的。
沖突點:snapshot(軟件快照)/發布版本(release build)
許多開發團隊把軟件的版本分為“snapshot”版本和“release”版本。這個并不是敏捷所特有的,而是隨著Maven的興起,被深深植入了Java開發中,因為Maven把snapshot的概念放入了它的設計核心中。這種方案把開發周期劃分成兩個階段,在軟件開發過程中使用snapshot,當軟件成為可以發布狀態時才創建release版本。
很明顯,這種發布周期的劃分和持續交付的“軟件應該總是可以發布”的理念是相沖突的。持續交付通常采用的方式是只在開始創建一次版本,然后通過不同階段的測試驗證等一系列串行工作來對版本進行改進,如果使用Maven,要用兩種方式創建版本,這種方式就不行了。
其實完全可以使用Maven做持續交付,比如說,為每個版本創建一個release build。當然,這個會和Maven的“release build只以生產部署為目的,不會經常創建”的理念矛盾。而且,像Nexus和Artefactory這樣的私服都有刪除舊的snapshot版本的清理功能,但不允許刪除release版本。所以一個活躍的持續交付團隊,一天可以產生幾十個版本,這樣很容易就吃掉服務器上幾G到幾T的空間。
矛盾點:更著重測試可部署性
標準的持續交付的實踐方式是,通過基本的持續集成自動地把每個版本部署到與真實生產環境盡量貼近的模擬環境中,使用相同的發布流程和工具。這對驗證每次提交的代碼是否是“可以發布”是至關重要的,但是這樣對持續集成的要求比現在大部分開發團隊正在使用的要高很多。
舉個例子,在沒有要求持續發布的持續集成,可能會使用Ant或者Maven將應用發布到嵌入應用服務器然后進行自動的功能測試。開發者使用和維護都很方便,但是這很可能不是生產環境中應用發布的方式。
所以持續交付團隊會自動化發布到一個更貼近真實生產的環境,包括不同的網頁/app/數據層,并且使用在真正生產中使用的部署工具。當然,這種更像生產的部署階段更加可能出錯,因為它增加了復雜性,而且可能對開發者而言更難以維護和修正,因為這些工具更像是給系統管理員而不是給開發者使用的。
不過這是個機會,可以和管理運營團隊一起創建一個更可靠、更易于支持的部署流程。但是實現和穩定這一流程的難度會比較大,可能會影響開發的進度。
值得采用持續交付嗎?
考慮到有這么多沖突的地方,那持續交付有什么好處,值得我們從傳統敏捷遷移過來呢?特別是對于那些實際上不太可能在一次迭代中有好幾次發布到生產環境的團隊來說,更是要問這個問題。值得這么做的原因如下:
盡早發現部署可能遇到的問題以降低風險
增加靈活性,組織可以選擇在任何時候發布,并把附加的代價和風險控制到最小
把生產發布涉及的每個人拉進來(比如QA、運營等),使得整個流程更有效率。組織必須識別出流程中的困難區域,并且通過自動化、更好的協作或者改進工作方法等方式找到克服它們的方法。
通過持續的演練發布流程,組織會對這個過程很精通,然后發布就會變得自動化,就像陣痛過后自由的呼吸,像生孩子一樣。
提升軟件質量,因為團隊不能再像以前一樣把問題留到后面,他們必須現在就解決。
消除沖突
當引入持續交付的時候,我以上所說的沖突點就會頻繁出現。我希望當這些問題出現的時候,了解沖突的根本原因,可以有助于更好地討論并解決它們。如果開發者一開始不愿意打破他們習慣的“正確”做事方式,或者認為持續交付所帶來的串行工作太復雜,或者很難理解這些實踐的目的和價值,那么我希望他們可以盡量開放地給自己一個機會去嘗試一下。一旦這些實踐方式根植于一個組織并且變得成熟,團隊成員們往往會覺得很難退回到以前的做事方式。
編者按:我重新定義了“傳統敏捷”中讓軟件可以發布的方式。這個定義不是適用于所有敏捷實踐,但是就我看到的,大部分主流概念都認為敏捷需要停下工作來將軟件變得可發布。
我在采用持續交付的組織中和開發團隊工作一起工作,發現很多開發者認為的正確的敏捷團隊的工作方式,在這里跑得不是很順暢。我認為傳統敏捷與持續交付的矛盾的根本在于,二者是采用不同的方式把軟件變得“可以發布“(ready to release)的。
軟件交付的演進
使軟件變得可以發布的過程一直在不停進化,下面是一個簡要的介紹:
瀑布模型
瀑布模型認為,當一個軟件所有的功能都發開完畢的時候(也就是功能完整的時候),才可以發布。
敏捷:
敏捷引入的思想是,在整個開發過程中,軟件都應該“可以發布”。許多敏捷的版本(在這篇文章里被稱為傳統敏捷)都認為,“可以發布”應該在固定周期的間隔點上完成。
持續交付:
持續交付是敏捷的一個子集,在持續交付中團隊會保持軟件在開發過程的所有時間內都可以發布。它和傳統敏捷不同之處在于,持續交付在開發過程中不會有停下來然后創建發布版本的過程。
持續性交付不是指更短的周期
從傳統的敏捷開發流程變成可持續性交付,不是指把軟件發布的周期變短。每天晚上做發布版本仍然不是可持續性交付。可持續性交付是說要把”做可以發布的軟件”這個動作本身從開發過程中去掉,取而代之的是保持軟件在開發的過程中始終是可以發布的。
可以發布不是意味著真正的發布
有一個普遍的誤解是可持續性交付就是非常頻繁地發布出產品。而當一些組織把每天數次發布軟件當作是持續交付的標桿時,就更加深了這一誤解。可持續性交付不是一定要頻繁的發布,它只是要求在開發過程中的任何一個點上,用非常少的工作,軟件就能夠發布(可參考Jez Humble的文章,可持續性交付VS可持續性部署)。盡管具備這一能力為更加頻繁的發布敞開了大門,但是許多團隊還是從持續交付的實踐中,找到了壓倒性的證據,來證明即便發布不是很頻繁時,持續交付也是有用的。
持續交付和傳統敏捷的沖突點
我前面講過,有時候持續交付和開發團隊所認為是“正確”的敏捷實踐流程有一些矛盾。
沖突點:當有工作沒有完成時,軟件依然是可發布的
其中一個沖突點是,一個迭代結束時,代碼庫中是否可以包含未完成的用戶故事(user stories)或者bug修復。我在上一篇關于迭代的帖子中做了探討。這個問題主要是源于,傳統敏捷認為在迭代結束時,team停止開發,并且來做準備軟件發布的一些額外工作,但是,如果團隊采用持續交付,讓軟件可發布就沒什么額外的工作需要做。
更有甚者,持續交付團隊甚至認為,通過使用功能切換等技術,他們的代碼即使在還有功能沒有完成也可以發布成產品。這也從另外一個方面說明,團隊在迭代結束時能夠達到可以發布的要求,即使有未完成的用戶故事。
這可能稍微有點難理解,團隊肯定還是可以要求在迭代結束點上所有的工作都必須完成,但是這容易讓人感覺是團隊原有的正常開發的節奏被隨便打斷了。持續交付不是要求沒有時間盒的迭代,這兩種實踐其實是互補的。
沖突點:snapshot(軟件快照)/發布版本(release build)
許多開發團隊把軟件的版本分為“snapshot”版本和“release”版本。這個并不是敏捷所特有的,而是隨著Maven的興起,被深深植入了Java開發中,因為Maven把snapshot的概念放入了它的設計核心中。這種方案把開發周期劃分成兩個階段,在軟件開發過程中使用snapshot,當軟件成為可以發布狀態時才創建release版本。
很明顯,這種發布周期的劃分和持續交付的“軟件應該總是可以發布”的理念是相沖突的。持續交付通常采用的方式是只在開始創建一次版本,然后通過不同階段的測試驗證等一系列串行工作來對版本進行改進,如果使用Maven,要用兩種方式創建版本,這種方式就不行了。
其實完全可以使用Maven做持續交付,比如說,為每個版本創建一個release build。當然,這個會和Maven的“release build只以生產部署為目的,不會經常創建”的理念矛盾。而且,像Nexus和Artefactory這樣的私服都有刪除舊的snapshot版本的清理功能,但不允許刪除release版本。所以一個活躍的持續交付團隊,一天可以產生幾十個版本,這樣很容易就吃掉服務器上幾G到幾T的空間。
矛盾點:更著重測試可部署性
標準的持續交付的實踐方式是,通過基本的持續集成自動地把每個版本部署到與真實生產環境盡量貼近的模擬環境中,使用相同的發布流程和工具。這對驗證每次提交的代碼是否是“可以發布”是至關重要的,但是這樣對持續集成的要求比現在大部分開發團隊正在使用的要高很多。
舉個例子,在沒有要求持續發布的持續集成,可能會使用Ant或者Maven將應用發布到嵌入應用服務器然后進行自動的功能測試。開發者使用和維護都很方便,但是這很可能不是生產環境中應用發布的方式。
所以持續交付團隊會自動化發布到一個更貼近真實生產的環境,包括不同的網頁/app/數據層,并且使用在真正生產中使用的部署工具。當然,這種更像生產的部署階段更加可能出錯,因為它增加了復雜性,而且可能對開發者而言更難以維護和修正,因為這些工具更像是給系統管理員而不是給開發者使用的。
不過這是個機會,可以和管理運營團隊一起創建一個更可靠、更易于支持的部署流程。但是實現和穩定這一流程的難度會比較大,可能會影響開發的進度。
值得采用持續交付嗎?
考慮到有這么多沖突的地方,那持續交付有什么好處,值得我們從傳統敏捷遷移過來呢?特別是對于那些實際上不太可能在一次迭代中有好幾次發布到生產環境的團隊來說,更是要問這個問題。值得這么做的原因如下:
盡早發現部署可能遇到的問題以降低風險
增加靈活性,組織可以選擇在任何時候發布,并把附加的代價和風險控制到最小
把生產發布涉及的每個人拉進來(比如QA、運營等),使得整個流程更有效率。組織必須識別出流程中的困難區域,并且通過自動化、更好的協作或者改進工作方法等方式找到克服它們的方法。
通過持續的演練發布流程,組織會對這個過程很精通,然后發布就會變得自動化,就像陣痛過后自由的呼吸,像生孩子一樣。
提升軟件質量,因為團隊不能再像以前一樣把問題留到后面,他們必須現在就解決。
消除沖突
當引入持續交付的時候,我以上所說的沖突點就會頻繁出現。我希望當這些問題出現的時候,了解沖突的根本原因,可以有助于更好地討論并解決它們。如果開發者一開始不愿意打破他們習慣的“正確”做事方式,或者認為持續交付所帶來的串行工作太復雜,或者很難理解這些實踐的目的和價值,那么我希望他們可以盡量開放地給自己一個機會去嘗試一下。一旦這些實踐方式根植于一個組織并且變得成熟,團隊成員們往往會覺得很難退回到以前的做事方式。
編者按:我重新定義了“傳統敏捷”中讓軟件可以發布的方式。這個定義不是適用于所有敏捷實踐,但是就我看到的,大部分主流概念都認為敏捷需要停下工作來將軟件變得可發布。
posted on 2012-07-20 10:04 順其自然EVO 閱讀(254) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄