前言
實(shí)例化需求被認(rèn)為是構(gòu)建正確軟件的優(yōu)秀實(shí)踐之一,越來(lái)越多的開發(fā)團(tuán)隊(duì)開始使用這種工作方法,本文將為大家分享一個(gè)真實(shí)團(tuán)隊(duì)的實(shí)例化需求實(shí)踐過(guò)程。
實(shí)例化需求這個(gè)概念來(lái)自于一本書《實(shí)例化需求:團(tuán)隊(duì)如何交付正確的軟件》(Specification by Example: How Successful Teams Deliver the Right Software)。
書的作者叫Gojko Adzic,是一名英國(guó)的戰(zhàn)略軟件交付顧問(wèn)。在近十幾年來(lái),一直在各種行業(yè)領(lǐng)域(例如財(cái)務(wù)和能源交易平臺(tái)、移動(dòng)定位、電子商務(wù)、在線游戲、復(fù)雜配置管理系統(tǒng)等等)從事著程序員、架構(gòu)師、技術(shù)指導(dǎo)和顧問(wèn)等工作。
實(shí)例化需求就是Gojko在這十多年的軟件生涯中總結(jié)出來(lái)的一套行之有效方法。官方對(duì)于它的介紹是這樣的:實(shí)例化需求是一組方法,它以一種對(duì)開發(fā)開發(fā)團(tuán)隊(duì)有所幫助的方式(理想情況下表現(xiàn)為可執(zhí)行的測(cè)試)描述計(jì)算機(jī)系統(tǒng)的功能和行為,讓不懂技術(shù)的利益相關(guān)者也可以理解,即使客戶的需求在不化,它也具有很好的可維護(hù)性,可以保持需求的相關(guān)性。從而幫助團(tuán)隊(duì)構(gòu)建正確的軟件產(chǎn)品。
在我看來(lái),這就是這套方法最牛的地方——幫助團(tuán)隊(duì)構(gòu)建正確的軟件產(chǎn)品。正確這個(gè)詞,說(shuō)起來(lái)簡(jiǎn)簡(jiǎn)單單,但實(shí)現(xiàn)起來(lái)卻真的很難。
我們?yōu)槭裁词褂脤?shí)例化需求
我們都明白,需求是一切軟件開發(fā)的源頭。有了需求,開發(fā)才能開始。但實(shí)際情況往往是,當(dāng)項(xiàng)目發(fā)生延期,或是項(xiàng)目測(cè)試投產(chǎn)出了問(wèn)題的時(shí)候,第一個(gè)被揪出來(lái)當(dāng)替罪羊的也往往是——需求不明確!
咦,需求不是應(yīng)該在開發(fā)之前就已經(jīng)搞明白了嗎?怎么還會(huì)不明確?造成這個(gè)問(wèn)題的無(wú)非下面幾種情況:
真的沒(méi)好好搞懂需求就開始了。在需求討論中,很常見的一種情況就是,剛開始說(shuō)的是要做什么,為什么要做,講著講著,大家的探討焦點(diǎn)就變成了怎么做,如何實(shí)現(xiàn),然后迫不及待地投入到軟件開發(fā)之中。很多團(tuán)隊(duì)都會(huì)有這樣的誤解:只有開始寫代碼才是真正的干活。
項(xiàng)目干系人并沒(méi)有對(duì)需求有著一致的理解。常規(guī)的需求通常是用自然語(yǔ)言編寫而成的文檔,自然語(yǔ)言本身就會(huì)存在著一千個(gè)人有一千個(gè)漢姆雷特這樣的理解偏差。如果團(tuán)隊(duì)使用的是需求-開發(fā)-測(cè)試這樣的軟件開發(fā)流程,需求在產(chǎn)生階段并沒(méi)有整個(gè)團(tuán)隊(duì)的介入,僅由需求人員負(fù)責(zé),在開發(fā)之初才移交給開發(fā)團(tuán)隊(duì),即使需求人員和開發(fā)人員有理解偏差也很難在第一時(shí)間發(fā)現(xiàn)。
不是我不明白,是這世界變化快?;ヂ?lián)網(wǎng)時(shí)代,軟件致勝只有一個(gè)法寶——快。很多人慨嘆,現(xiàn)在的時(shí)代過(guò)于浮躁,精雕細(xì)琢的東西不復(fù)存在。而事實(shí)是,整個(gè)IT界的業(yè)態(tài)變化得如此之快,如果你再按照從前的項(xiàng)目節(jié)奏走下去,當(dāng)你的產(chǎn)品交付之時(shí),也將是被淘汰之時(shí)。如今,大多相互的項(xiàng)目周期是按月來(lái)衡量的,項(xiàng)目階段則是以周甚至是天來(lái)計(jì)數(shù)的。所以,如果團(tuán)隊(duì)期待的是一份大而全,且永不變更的需求文檔,并以此為依據(jù)進(jìn)行開發(fā),那項(xiàng)目延期或者出問(wèn)題簡(jiǎn)直是必然的情況。
過(guò)于依賴個(gè)人的認(rèn)知結(jié)構(gòu)。需求從哪里來(lái)?有的團(tuán)隊(duì)的做法是把用戶提出的需求當(dāng)做用戶故事的源頭,竭盡全力去實(shí)現(xiàn)。但是用戶不了解你的系統(tǒng),所以他所說(shuō)的有可能超過(guò)了系統(tǒng)的范疇。再加上用戶也許并不真的像他以為的那么了解自己,往往把真實(shí)的需要隱藏在一個(gè)他自以為的解決方案中提出。如果真的照他說(shuō)的做,那就慘了,只有在交付的時(shí)候才能聽到他說(shuō)——這不是我想要的。另一種做法是由產(chǎn)品人員把用戶的需求翻譯過(guò)來(lái)。但是在翻譯的過(guò)程中只有產(chǎn)品人員孤軍奮戰(zhàn)。而每個(gè)人總有每個(gè)人思維的局限性,一定會(huì)有想不到的地方。
讓我們來(lái)看看實(shí)例化需求可以做什么吧。
實(shí)例化需求的核心是:讓項(xiàng)目的所有干系方進(jìn)行有效的協(xié)作和溝通,用實(shí)例的方式說(shuō)明需求,用自動(dòng)化測(cè)試的方式頻繁地驗(yàn)證需求,從實(shí)例化的需求說(shuō)明和自動(dòng)化測(cè)試用例中演進(jìn)出一套“活文檔系統(tǒng)”。這套“活文檔系統(tǒng)”既可以有效地對(duì)系統(tǒng)進(jìn)行說(shuō)明,又可以當(dāng)做交付驗(yàn)收的標(biāo)準(zhǔn)。
有效的交流溝通確保有足夠的時(shí)間澄清需求。
使用舉例的方法澄清需求能在第一時(shí)間識(shí)別出需求是否足以支撐開發(fā)。
所有的干系方參與需求討論,可以確保大家對(duì)于交付哪些東西有一致的理解。
具有不同領(lǐng)域背景的干系方一同參加需求討論,可以規(guī)避因個(gè)人認(rèn)知局限帶來(lái)的需求問(wèn)題。
“活文檔系統(tǒng)”對(duì)于變更有著先天優(yōu)勢(shì),可以以最少的維護(hù)成本維持文檔的相關(guān)性和可靠性。又能避免過(guò)度說(shuō)明需求而產(chǎn)生浪費(fèi),避免花時(shí)間在開發(fā)前有可能發(fā)生變化的細(xì)節(jié)上,對(duì)于變更天然友好。
采用自動(dòng)化測(cè)試的方法實(shí)現(xiàn)業(yè)務(wù)實(shí)例,代碼開發(fā)出來(lái)即可以驗(yàn)證,無(wú)須經(jīng)過(guò)冗長(zhǎng)的手動(dòng)回歸測(cè)試,降低返工。
完美解決上述問(wèn)題。
實(shí)例化需求怎么做
在《實(shí)例化需求》一書中,Gojko提出了實(shí)例化需求的主要過(guò)程模式,包含以下幾個(gè)環(huán)節(jié):
從目標(biāo)中獲取范圍:與客戶溝通協(xié)作,以用戶的業(yè)務(wù)目標(biāo)為起始,通過(guò)協(xié)作節(jié)點(diǎn)可以實(shí)現(xiàn)目標(biāo)的范圍。需要注意的是:1)要一直牢記商業(yè)價(jià)值,為什么要做。很多時(shí)候執(zhí)行項(xiàng)目時(shí)太關(guān)注怎么做了。2)不要把用戶自以為的解決方案當(dāng)做系統(tǒng)需求。
從協(xié)作中制訂需求說(shuō)明:協(xié)作是關(guān)鍵詞。目的是讓需求、設(shè)計(jì)、開發(fā)以及測(cè)試都參與進(jìn)來(lái),發(fā)揮整個(gè)團(tuán)隊(duì)的知識(shí)和經(jīng)驗(yàn),力求讓項(xiàng)目的干系人都更多的參與到交付過(guò)程中。排除理解的不一致性,盡量減少個(gè)人認(rèn)知造成的局限性。一定要在團(tuán)隊(duì)著手開始項(xiàng)目之前再進(jìn)行實(shí)例化需求的工作,否則太早進(jìn)行有可能導(dǎo)致遺忘,或者是遇到需求變更使之前的工作沒(méi)有價(jià)值。
舉例說(shuō)明:舉例說(shuō)明其實(shí)是項(xiàng)目需求交流過(guò)程中不可或缺的,團(tuán)隊(duì)中的成員業(yè)務(wù)背景不同,對(duì)同一事物的理解也不同,通過(guò)舉例說(shuō)明的方式可以讓目標(biāo)更一致。
提煉需求說(shuō)明:協(xié)作過(guò)程中的開發(fā)討論可以建立大家對(duì)相關(guān)領(lǐng)域的共識(shí),但得到的實(shí)例往往包含很多不必要的細(xì)節(jié)。而關(guān)鍵實(shí)例是從這些實(shí)例中提煉出來(lái)的,雖然精簡(jiǎn)但足以說(shuō)明業(yè)務(wù)流程的實(shí)例。并且這些提煉好的實(shí)例本身就可以當(dāng)作交付的驗(yàn)收條件。
在不修改需求的前提下,用自動(dòng)化測(cè)試來(lái)驗(yàn)證需求。需要根據(jù)需求實(shí)例生成自動(dòng)化的測(cè)試用例和代碼。生成的自動(dòng)化測(cè)試用例可以用來(lái)驗(yàn)證程序是否符合需求。由此產(chǎn)生的自動(dòng)化測(cè)試用例可以準(zhǔn)確地描述系統(tǒng)是做什么的,由于和需求實(shí)例同步,因此也是最新的,所以它是提取“活文檔”的可靠來(lái)源。
重構(gòu)需求的同時(shí),頻繁驗(yàn)證:頻繁驗(yàn)證的重要性不用多說(shuō),在任何一種軟件開發(fā)方法論,例如敏捷、BDD中它都被反復(fù)提及。頻繁驗(yàn)證一定是所有過(guò)程實(shí)施中需要不斷進(jìn)行的工作。有很多種方法可以用來(lái)實(shí)施頻繁驗(yàn)證,例如持續(xù)集成等等。
利用工具,提取組織良好的、易于尋找的、前后一致的活文檔:使用工具,可以從自動(dòng)化測(cè)試用例中提取出一份活文檔,這樣的文檔是最新的,最能描述系統(tǒng)行為的。通常來(lái)說(shuō),需求實(shí)例說(shuō)明和自動(dòng)化測(cè)試用例做好了,從中提取出一份好文檔也是水到渠成的事情。
原書中的流程圖是這樣的:
翻譯成中文是醬紫的:
我們?nèi)绾螌?shí)踐實(shí)例化需求
1、從目標(biāo)中獲取范圍:
當(dāng)咨詢老師詢問(wèn)我們的業(yè)務(wù)目標(biāo)時(shí),我們先給老師介紹了某個(gè)完整的業(yè)務(wù)流程。于是老師問(wèn)道,你們的目標(biāo)就是實(shí)現(xiàn)這個(gè)購(gòu)買的功能嗎?但是,隨著討論的深入,我們意識(shí)到,對(duì)于我們來(lái)說(shuō),業(yè)務(wù)目標(biāo)并不是這個(gè),而是——實(shí)現(xiàn)系統(tǒng)的透明轉(zhuǎn)移!這意味著我們要保證整個(gè)遺留系統(tǒng)在用戶眼中的樣子和現(xiàn)有系統(tǒng)不能有區(qū)別。而現(xiàn)有系統(tǒng)的文檔不完備,而且,即使有文檔,也未必表示現(xiàn)有系統(tǒng)和文檔完全一致。這就更需要我們使用實(shí)例化的方法來(lái)進(jìn)一步探討需求。
2、從協(xié)作中制訂需求:
第一次討論是產(chǎn)品經(jīng)理、開發(fā)經(jīng)理、測(cè)試經(jīng)理、咨詢團(tuán)隊(duì)共同進(jìn)行的。后來(lái)我們又經(jīng)過(guò)了一次討論,包含了整個(gè)開發(fā)團(tuán)隊(duì)。不同視角的人員的參與能保證需求考慮的全面性,以及建立起一套統(tǒng)一的描述語(yǔ)言,從而在第一時(shí)間消除理解偏差。事實(shí)上,我們?cè)谟懻撝?,建立起?lái)了本項(xiàng)目的領(lǐng)域模型,而此后的討論也一直確保探討的各個(gè)名詞或術(shù)語(yǔ)的范圍都在領(lǐng)域模型之中。
從哪里梳理領(lǐng)域模型中的詞匯呢?一切都從系統(tǒng)的工作流開始。從工作流中,我們可以識(shí)別出基礎(chǔ)場(chǎng)景、異常場(chǎng)景,還可以從系統(tǒng)交互的接口中識(shí)別出校驗(yàn)的各種情況。這里有一點(diǎn)需要注意的,就是不僅要畫出系統(tǒng)之間的調(diào)用流程,并且需要明確出系統(tǒng)之間傳遞的數(shù)據(jù)有哪些。識(shí)別得越明確,對(duì)于后面的舉例工作越有幫助。
3、舉例說(shuō)明:
將工作流中識(shí)別出來(lái)的種種情況,用具體的例子來(lái)說(shuō)明。例子應(yīng)該包含前置條件、輸入、輸出。前置條件指的是場(chǎng)景發(fā)生時(shí),未作為輸入傳遞到本系統(tǒng)中,但是已經(jīng)存在,且對(duì)業(yè)務(wù)產(chǎn)生影響的數(shù)據(jù)。當(dāng)大家用說(shuō)的方式解釋不清的時(shí)候,舉例子是自然而然的選擇。事實(shí)上,即使你覺(jué)得能說(shuō)清楚,也應(yīng)該舉例,以免大家的理解有誤差。甚至在場(chǎng)景特別復(fù)雜的情況下,我們會(huì)使用流程圖來(lái)輔助舉例。
4、提煉需求說(shuō)明:
將例子整理成更加精煉和清晰的表格。
5、在不修改需求的前提下,使用自動(dòng)化測(cè)試驗(yàn)證需求:
這一步由咨詢團(tuán)隊(duì)指導(dǎo)我們使用Cucumber工具根據(jù)業(yè)務(wù)規(guī)則實(shí)現(xiàn)自動(dòng)化測(cè)試用例。
6、重構(gòu)需求的同時(shí),頻繁驗(yàn)證:
通過(guò)持續(xù)集成和自動(dòng)化測(cè)試的方式頻繁驗(yàn)證代碼的實(shí)現(xiàn)是否符合業(yè)務(wù)規(guī)則。
7、利用工具,提取組織良好的、易于尋找的、前后一致的活文檔:
文檔一定是在每個(gè)迭代之前,針對(duì)這個(gè)迭代要做的價(jià)值點(diǎn),整個(gè)團(tuán)隊(duì)進(jìn)行了需求澄清之后,再形成的。這樣可以保證這個(gè)文檔在這個(gè)迭代的進(jìn)行中是權(quán)威的,有效的。當(dāng)價(jià)值點(diǎn)做完了之后,再做新的價(jià)值點(diǎn)的時(shí)候,整個(gè)團(tuán)隊(duì)再對(duì)需求進(jìn)行澄清,再對(duì)已澄清的需求進(jìn)行描述。這樣形成的文檔是可以自我生長(zhǎng),自我描述的,不斷更新,易于維護(hù)的。目前我們生成的文檔是這樣子的,包含了當(dāng)前迭代中需要的工作流、業(yè)務(wù)規(guī)則和實(shí)例化說(shuō)明。
實(shí)際上,這離作者所說(shuō)的“活文檔系統(tǒng)”還是有一定的距離?;钗臋n還有一個(gè)更加重要的部分,就是根據(jù)業(yè)務(wù)規(guī)則實(shí)例形成的自動(dòng)化測(cè)試用例。當(dāng)規(guī)則實(shí)例不斷更新和增長(zhǎng)時(shí),自動(dòng)化測(cè)試的用例和代碼也不斷更新和增長(zhǎng),永遠(yuǎn)都是最新的,最能描述系統(tǒng)行為的,一目了然的。而自動(dòng)化測(cè)試的用例和代碼通過(guò)BDD的一些工具能自動(dòng)提取為html文件或者pdf文件,形成一份真正的“文檔”,這也就是作者書中描述的“活文檔系統(tǒng)”。這個(gè)也是我們未來(lái)要著重進(jìn)行的部分。
(本文于2017-07-07首次發(fā)布)