用“實(shí)例化需求”,讓需求澄清更高效
實(shí)例化需求不僅解決了需求分析和撰寫的問題,也給出了需求溝通和澄清的方法。本文從實(shí)例化需求的定義出發(fā),從使用實(shí)例化需求的原因、實(shí)例化需求的產(chǎn)生輸出、自動(dòng)化測(cè)試和操作流程這幾個(gè)方面對(duì)實(shí)例化需求進(jìn)行了說明介紹,與大家分享。
01 什么是實(shí)例化需求?
實(shí)例化需求的英文是 Specification by Example,簡(jiǎn)稱 SBE,直譯過來就是用實(shí)例說明需求。
實(shí)例化需求是一組方法,它以一種對(duì)開發(fā)開發(fā)團(tuán)隊(duì)有所幫助的方式(理想情況下表現(xiàn)為可執(zhí)行的測(cè)試)描述計(jì)算機(jī)系統(tǒng)的功能和行為,讓不懂技術(shù)的利益相關(guān)者也可以理解,即使客戶的需求在不斷變化,它也具有很好的可維護(hù)性,可以保持需求的相關(guān)性。從而幫助團(tuán)隊(duì)交付正確的軟件產(chǎn)品。
為避免需求溝通過程中的「知識(shí)詛咒」,“實(shí)例化需求”方法從場(chǎng)景出發(fā),以用戶的操作實(shí)例來澄清需求。
相比一般的規(guī)格說明,實(shí)例更加場(chǎng)景化,能夠激發(fā)參與和深度討論;同時(shí),實(shí)例是具體的,其典型形式是:「在什么情況下,做什么操作,會(huì)得到什么結(jié)果」。基于具體的實(shí)例,更加便于溝通中的雙向確認(rèn),保證理解的一致和場(chǎng)景覆蓋。
上圖是對(duì)實(shí)例化需求的概念說明:
- 用例子來分析和澄清需求。
- 這些例子隨后會(huì)轉(zhuǎn)化為測(cè)試用例。
- 最后再通過測(cè)試驗(yàn)證需求。
如此形成閉環(huán),這個(gè)三角是實(shí)例化需求的核心概念。
在「實(shí)例化需求」中,開發(fā)、測(cè)試和業(yè)務(wù)人員一起溝通需求,避免信息傳遞的噪音和損耗。
02 為什么使用實(shí)例化需求?
實(shí)例化需求的核心是,讓項(xiàng)目的所有干系方進(jìn)行有效的協(xié)作和溝通,用實(shí)例的方式說明需求,用自動(dòng)化測(cè)試的方式頻繁地驗(yàn)證需求,從實(shí)例化的需求說明和自動(dòng)化測(cè)試用例中演進(jìn)出一套“活文檔系統(tǒng)”。這套“活文檔系統(tǒng)”既可以有效地對(duì)系統(tǒng)進(jìn)行說明,又可以當(dāng)做交付驗(yàn)收的標(biāo)準(zhǔn)。
- 有效的交流溝通確保有足夠的時(shí)間澄清需求。
- 使用舉例的方法澄清需求能在第一時(shí)間識(shí)別出需求是否足以支撐開發(fā)。
- 所有的干系方參與需求討論,可以確保大家對(duì)于交付哪些東西有一致的理解。
- 具有不同領(lǐng)域背景的干系方一同參加需求討論,可以規(guī)避因個(gè)人認(rèn)知局限帶來的需求問題。
- ”活文檔系統(tǒng)”對(duì)于變更有著先天優(yōu)勢(shì),可以以最少的維護(hù)成本維持文檔的相關(guān)性和可靠性。又能避免過度說明需求而產(chǎn)生浪費(fèi),避免花時(shí)間在開發(fā)前有可能發(fā)生變化的細(xì)節(jié)上,對(duì)于變更天然友好。
- 采用自動(dòng)化測(cè)試的方法實(shí)現(xiàn)業(yè)務(wù)實(shí)例,代碼開發(fā)出來即可以驗(yàn)證,無須經(jīng)過冗長(zhǎng)的手動(dòng)回歸測(cè)試,降低返工。
03 產(chǎn)生哪些輸出?
實(shí)例化需求有9個(gè)過程模式:從目標(biāo)獲取范圍、協(xié)作產(chǎn)生需求說明、舉例說明、提煉需求說明、在不修改需求說明的情況下實(shí)現(xiàn)自動(dòng)化驗(yàn)證、頻繁驗(yàn)證、以及演化出一個(gè)活文檔系統(tǒng)。這 9 個(gè)過程模式涉及了如下的輸出(制品):目標(biāo)和范圍、需求說明、例子、自動(dòng)化測(cè)試及活文檔系統(tǒng)。
下面我們一個(gè)個(gè)來詳細(xì)說明。
1. 澄清價(jià)值,定義目標(biāo)和范圍
實(shí)例化需求的第一步“澄清價(jià)值”,它包含兩個(gè)子步驟:
- 描述背景。也就是需求的業(yè)務(wù)背景和系統(tǒng)的上下文。這一步形式相對(duì)自由。上面的示例圖中,我使用了面向?qū)ο蠓治鲋械某S玫南到y(tǒng)上下文圖(SCD,System Context Diagram),定義了系統(tǒng)的邊界、所處的環(huán)境以及主要組成部分,你也可以使用更自由的線框圖來表達(dá)系統(tǒng)的上下文。系統(tǒng)上下文相對(duì)穩(wěn)定,并不需要對(duì)每個(gè)需求重復(fù)這樣描述,只要在必要時(shí)(比如發(fā)生變化時(shí)),做出澄清就可以了。
- 澄清用戶問題和業(yè)務(wù)目標(biāo)。需求最終要解決用戶的問題,從而實(shí)現(xiàn)產(chǎn)品的業(yè)務(wù)目標(biāo)。因此,在討論具體的需求前,我們還要澄清用戶是誰,要解決他們什么問題。
針對(duì)目標(biāo)和問題的典型挑戰(zhàn)性檢驗(yàn)是:
- 如果不做這個(gè)需求會(huì)怎么樣?
- 有沒有其它替代方法?
認(rèn)真回答上面兩個(gè)問題,往往能挖掘出需求的本質(zhì),確保我們?cè)诮鉀Q的是真正的用戶或業(yè)務(wù)問題。
2. 需求說明
在實(shí)踐中,我們所產(chǎn)生的“需求說明”更具體的體現(xiàn)形式是:
- 工作流
- 領(lǐng)域模型
- 業(yè)務(wù)規(guī)則
3. 工作流
工作流也稱為業(yè)務(wù)流程或業(yè)務(wù)場(chǎng)景,是用戶通過一系列步驟,達(dá)成系統(tǒng)業(yè)務(wù)目標(biāo)的一種實(shí)現(xiàn)方式。在實(shí)例化需求工作坊中,參與人員在白板上使用順序圖、活動(dòng)圖、帶有泳道的活動(dòng)圖等方式,共同繪制出工作流。當(dāng)然,如果工作流足夠明顯,也可以直接采用業(yè)務(wù)用例的形式,列出標(biāo)題,理清它們之間的先后關(guān)系即可。
簡(jiǎn)單來說,就是為了實(shí)現(xiàn)上面的目標(biāo),系統(tǒng)需要支持哪些用戶操作?這些操作的流程是什么樣的?具體分為兩個(gè)子步驟:
1)列出用戶的操作。產(chǎn)品的功能體現(xiàn)為它所支持的用戶操作,列出用戶操作,可以涵蓋其功能性需求。如下圖,我們通過用例圖描述了用戶的操作。用例圖定義了為完成特定目標(biāo),操作者和系統(tǒng)之間的交互,它包含操作者和操作兩個(gè)部分。
用例是需求工程中獲取和列舉功能需求最常用的手段之一,如果不習(xí)慣用例的表示法,更簡(jiǎn)單的方法是直接列出用戶和用戶的操作。
2)畫出用戶操作的流程步驟。這一步的目的是:定義操作的具體交互流程。下圖使用了活動(dòng)圖和時(shí)序圖兩種形式,來表達(dá)操作步驟。其中,活動(dòng)圖形式上與流程圖類似,只不過它表達(dá)的是用戶操作流程,而不是技術(shù)實(shí)現(xiàn)流程;時(shí)序圖則在表達(dá)系統(tǒng)間的交互方面更勝一籌,例如針對(duì)金融類系統(tǒng)的需求,可以用時(shí)序圖表示系統(tǒng)間的資金往來和記錄存取等。
活動(dòng)圖示例
帶泳道的活動(dòng)圖示例:
時(shí)序圖:
這兩種表示法,都表示了操作的步驟,團(tuán)隊(duì)?wèi)?yīng)該靈活選取適合的表達(dá)方式,當(dāng)然也可以選取其它表示法如通信圖、狀態(tài)機(jī)等。
狀態(tài)機(jī):
用戶注冊(cè)通信圖:
針對(duì)操作和步驟的典型挑戰(zhàn)性檢驗(yàn)是:
- 這些操作能解決識(shí)別出的用戶問題并實(shí)現(xiàn)業(yè)務(wù)目標(biāo)嗎?
- 操作步驟合理嗎?
- 操作流程可以更簡(jiǎn)單嗎?
認(rèn)真應(yīng)對(duì)這些的挑戰(zhàn),將確保功能和操作的合理性、簡(jiǎn)單性和完整性。
或者就是簡(jiǎn)單地采用列表的形式,列出幾個(gè)相關(guān)的用戶場(chǎng)景:
- 新開通一個(gè)子代理商。
- 為子代理商充值。
- 為子代理商修改密碼。
- 修改子代理商的基本信息。
- 查詢子代理商列表。
- …
繪制工作流的目的不是為了描述,而是為了信息發(fā)現(xiàn)和挑戰(zhàn)(challenge, 這里是褒義),即既有的工作流是否合理,是否存在遺漏,是否需要進(jìn)一步討論其中的業(yè)務(wù)數(shù)據(jù)和業(yè)務(wù)規(guī)則,等等。
在上面的工作流中,我們可以看到的挑戰(zhàn)包括:
- 子代理商的初始化密碼怎么設(shè)定?
- 子代理商首次登錄時(shí)是否要被提示修改密碼?
- 子代理商可以自己添加用戶嗎?
- 子代理商的基本信息包括哪些?哪些信息需要校驗(yàn)?
- 是否需要在創(chuàng)建時(shí)就為子代理商進(jìn)行充值?
- 創(chuàng)建的子代理商可以進(jìn)一步創(chuàng)建子代理商嗎?
- …
回答上述挑戰(zhàn)的過程,事實(shí)上是一個(gè)需求澄清的過程,它也會(huì)對(duì)應(yīng)的更新工作流、領(lǐng)域模型和業(yè)務(wù)規(guī)則。在進(jìn)行挑戰(zhàn)和回答挑戰(zhàn)的過程中,也一般都會(huì)包含了對(duì)每個(gè)業(yè)務(wù)流程或規(guī)則背后的業(yè)務(wù)價(jià)值的討論,以及緊急程度的討論。例如:
- 密碼的一般性規(guī)則(例如必須包含特殊字符)是否要適用于初始密碼?這會(huì)不會(huì)對(duì)線下過程帶來困擾?
- 我們?yōu)槭裁匆崖?lián)系人和管理員區(qū)分開?
- 在我們的當(dāng)前階段,能否延遲支持代理商的多管理員功能?
- …
在上述案例中,一個(gè)可能的討論結(jié)果是:代理商的多管理員功能雖然是需要的,但是在當(dāng)前階段可以暫緩實(shí)現(xiàn),等等。
4. 領(lǐng)域模型(統(tǒng)一術(shù)語)
大多數(shù)討論都是很熱鬧的,但是效果卻不盡相同。其實(shí),熱鬧的背后是七嘴八舌還是井然有序,常常是因?yàn)楦拍钜鸬摹4蠖鄶?shù)人都有過這樣的經(jīng)驗(yàn):兩個(gè)人爭(zhēng)論的面紅耳赤,但是最終發(fā)現(xiàn)我們說的其實(shí)根本不是一件事情!或者發(fā)現(xiàn)我們說的其實(shí)就是同一個(gè)觀點(diǎn)!根本就無需爭(zhēng)論!
在討論中,我們常常看到有這么一種人能夠打破僵局,推動(dòng)討論:“來,讓我們看看每個(gè)人說的是什么”。
每個(gè)人在內(nèi)心所建的概念的差異,往往是導(dǎo)致爭(zhēng)論的根源。
領(lǐng)域模型有很多方面的價(jià)值,但是讓我們首先聚焦于它所表達(dá)的概念,對(duì)業(yè)務(wù)實(shí)體和它們之間的關(guān)系進(jìn)行建模。例如下面的這個(gè)領(lǐng)域模型:
有了上述的模型,當(dāng)我們?cè)谟懻撝姓f到代理商基本信息的時(shí)候,所有人就都知道哪些是基本信息。說到子代理商的時(shí)候,所有人都知道子代理商其實(shí)也是一個(gè)代理商。這其實(shí)就是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain Driven Design, DDD)中所講述的“統(tǒng)一語言”的應(yīng)用。
同時(shí),領(lǐng)域模型帶來的統(tǒng)一語言,使得業(yè)務(wù)規(guī)則討論變得更加精確,也更加高效。
例如:如果子代理商權(quán)限為”無“,則代理商不能創(chuàng)建子代理商。代理商可以查詢子代理商的基本信息。
像上面的這種模型如何獲得?盡管存在各種各樣的方法,例如關(guān)注需求描述中的名詞等等,但是可以肯定的一點(diǎn)是,模型是通過討論獲得的。它是持續(xù)演進(jìn)的結(jié)果。這個(gè)過程常常是這樣一個(gè)模式:
- 發(fā)現(xiàn)既有詞匯不足以表述需求,或者發(fā)現(xiàn)參與人員在過程中產(chǎn)生了困惑;
- 試圖提出一些關(guān)于新的詞匯的假設(shè),對(duì)既有模型進(jìn)行修正和補(bǔ)充
- 辯駁這些假設(shè);
- 修正,推翻,達(dá)成一致。 詞匯存在歧義是一個(gè)常見的問題,這類問題如果不通過討論,很難快速取得一致。上述模型的達(dá)成過程事實(shí)上首先是在白板上完成的。
具體領(lǐng)域模型使用 UML(統(tǒng)一建模語言)表示法,并體現(xiàn)為不包含操作的類圖,領(lǐng)域模型由三個(gè)要素構(gòu)成:
- 領(lǐng)域中的實(shí)體對(duì)象(如: 房產(chǎn),房主等)和概念(如:交易,按揭方案等)。
- 對(duì)象或概念間的關(guān)系。如:房主擁有房產(chǎn)等,”擁有“就是房主與房產(chǎn)之間的關(guān)系。
- 這些對(duì)象或概念所包含的屬性。如:房產(chǎn)的屬性包含房齡、價(jià)格、面積等。
5. 業(yè)務(wù)規(guī)則
實(shí)例化需求的最重要輸出是需求驗(yàn)收標(biāo)準(zhǔn),它們可以表達(dá)為一條條的業(yè)務(wù)規(guī)則。上一步,我們已經(jīng)列出了操作和操作步驟,用它們來組織業(yè)務(wù)規(guī)則非常合適,對(duì)于操作中的主要步驟,團(tuán)隊(duì)可以列出它們的業(yè)務(wù)規(guī)則。
最常見的業(yè)務(wù)規(guī)則可以表達(dá)為三段式的結(jié)構(gòu),也就是「Given(當(dāng)),When(如果),Then(那么)」。比如:
- 當(dāng)用戶是 VIP 會(huì)員時(shí),如果其購(gòu)買金額為100元,那么運(yùn)費(fèi)為0元。
- 當(dāng)用戶是 VIP 會(huì)員時(shí),如果其購(gòu)買金額為99元,那么運(yùn)費(fèi)為0元。
- 當(dāng)用戶是普通會(huì)員時(shí),如果其購(gòu)買金額為100元,那么運(yùn)費(fèi)為0元。
- 當(dāng)用戶是 VIP 會(huì)員時(shí),如果其購(gòu)買金額為99元,那么運(yùn)費(fèi)為10元。
實(shí)例的形式表達(dá)場(chǎng)景和業(yè)務(wù)規(guī)則,這是”實(shí)例化需求“這個(gè)詞的來源。之前對(duì)用戶操作步驟的分析,正好可以用來組織這些實(shí)例。上圖所示,正是按操作步驟分別列舉對(duì)應(yīng)的實(shí)例(業(yè)務(wù)規(guī)則)。
這些實(shí)例可以用條目化的方式表達(dá)。同時(shí),當(dāng)規(guī)則組合較多時(shí),可以將他們抽取為數(shù)據(jù)表格。上圖中關(guān)于”共同貸款人審查“這一步驟的規(guī)則,就被抽象成了表格。這一方面讓規(guī)則更清晰和易于理解;另一方面,將來表格在映射為測(cè)試用例時(shí),能自然的做到測(cè)試流程和測(cè)試數(shù)據(jù)分離,更易于閱讀、維護(hù)和擴(kuò)展。
以上列出的都是功能性的需求和規(guī)則。在實(shí)際過程中可能還會(huì)涉及非功能性需求,如可用性、可靠性、性能、安全性等。非功能性需求大部分體現(xiàn)在系統(tǒng)級(jí)別,而實(shí)例化需求針對(duì)的是單個(gè)需求。實(shí)例化需求過程中,一般只需要列出與特定功能相關(guān)的非功能性需求,如針對(duì)某一特定操作的特定安全性和性能要求。
針對(duì)業(yè)務(wù)規(guī)則的典型挑戰(zhàn)性檢驗(yàn)是:
- 相關(guān)業(yè)務(wù)規(guī)則考慮全面嗎?
- 特殊情況,異?;蝈e(cuò)誤處理包含了嗎?
- 是否考慮了不同用戶、數(shù)據(jù)和操作類別?
認(rèn)真應(yīng)對(duì)以上的挑戰(zhàn),將確保規(guī)則的完整性,以及產(chǎn)品交互細(xì)節(jié)的合理性。
先來一起看一下某測(cè)試:
- 首先添加員工信息。
- 執(zhí)行發(fā)放工資的動(dòng)作。
- 檢查工資數(shù)值是否正確。
- 檢查付款支票號(hào)碼正確。
這是一個(gè)反例。需求必須精確,不能在用戶故事開始實(shí)現(xiàn)時(shí)仍處于模糊的狀態(tài)。例如,付款支票應(yīng)該包括哪些信息?這屬于領(lǐng)域建模的范疇,應(yīng)該通過領(lǐng)域模型予以回答。除此之外,我們?nèi)匀粫?huì)提出下面的一些問題,例如:付款支票日期究竟應(yīng)該使用發(fā)薪日期還是當(dāng)前日期?工資發(fā)放的計(jì)算規(guī)則是否在本需求范圍內(nèi)?付款支票號(hào)碼的編號(hào)策略有沒有什么要求?等等。
即使一個(gè)看起來很清楚的需求,我們也建議舉一兩個(gè)實(shí)際的案例來說明。就像下面這種圖片展示的那樣:
6. 例子
舉例說明是項(xiàng)目需求交流過程中不可或缺的,團(tuán)隊(duì)中的人領(lǐng)域背景不同,對(duì)同一個(gè)事物的理解也可能不盡相同,通過舉例說明的方式可以讓目標(biāo)更一致。
功能模塊的例子必須具有精確性(不是簡(jiǎn)單的是或否的答案,使用具體的例子)、真實(shí)性(使用真實(shí)數(shù)據(jù),從客戶那兒獲取真實(shí)的例子)、完整性(使用不同的數(shù)據(jù)組合去試驗(yàn),利用其他方式去檢驗(yàn)和測(cè)試),并易于理解(不用試驗(yàn)所有組合,尋找隱含的概念)。
- Tip1:例子應(yīng)該關(guān)注用戶和系統(tǒng)之間的交互,而非關(guān)注系統(tǒng)本身的處理流程。因此,例子應(yīng)該包含前置條件、輸入、輸出。前置條件指的是場(chǎng)景發(fā)生時(shí),未作為輸入傳遞到本系統(tǒng)中,但是已經(jīng)存在,且對(duì)業(yè)務(wù)產(chǎn)生影響的數(shù)據(jù)。
- Tip2:當(dāng)大家用說的方式解釋不清的時(shí)候,舉例子是自然而然的選擇。事實(shí)上,即使你覺得能說清楚,也應(yīng)該舉例,以免大家的理解有誤差。例子應(yīng)該具體而精確,避免使用范圍。例如,不要用某一值“小于10”這一表述,而應(yīng)該用某一值等于“9”來舉例。
- Tip3:在場(chǎng)景特別復(fù)雜的情況下,還可以使用流程圖來輔助舉例。使用什么樣的方式不重要,重要的是這種方式能夠達(dá)到在團(tuán)隊(duì)中澄清需求的目的。
- Tip4:如果發(fā)現(xiàn)實(shí)例太復(fù)雜,就把它的復(fù)雜度降低,分解成若干個(gè)實(shí)例。例如,對(duì)于“如果數(shù)量大于10件,或者重量大于50kg,則收取50元運(yùn)費(fèi)”這個(gè)規(guī)則,可以拆分為“數(shù)量大于10件”和“重量大于50kg”兩個(gè)規(guī)則,再來舉出數(shù)量為20件和重量為60kg兩個(gè)實(shí)例。
- Tip5:在舉例說明的過程中極有可能會(huì)發(fā)現(xiàn)之前未能識(shí)別出來的潛在概念。當(dāng)潛在概念出現(xiàn)時(shí),應(yīng)當(dāng)把它加入到領(lǐng)域模型之中。
雖然協(xié)作過程中的需求討論可以建立大家對(duì)相關(guān)領(lǐng)域的共識(shí),但得到的實(shí)例往往包含很多不必要的細(xì)節(jié)。關(guān)鍵實(shí)例是從這些實(shí)例中提煉出來的,雖然精簡(jiǎn)但足以說明業(yè)務(wù)的實(shí)例。并且這些提煉好的實(shí)例本身就可以當(dāng)作交付的驗(yàn)收條件。
- Tip1:摒棄對(duì)業(yè)務(wù)走向沒有影響的實(shí)例。例如,當(dāng)輸入中的購(gòu)買者字段是“中學(xué)生”“小學(xué)生”“大學(xué)生”時(shí),如果它們的區(qū)別僅在于名稱不同,系統(tǒng)對(duì)業(yè)務(wù)的處理完全一樣,此時(shí)應(yīng)該只保留其中一個(gè)實(shí)例作為代表。
- Tip2:提煉實(shí)例可以由簡(jiǎn)入繁??梢韵劝鸦镜某晒η闆r提煉出來,再逐步推及到各種異常和失敗。關(guān)注影響業(yè)務(wù)規(guī)則的實(shí)例,關(guān)注邊界條件的實(shí)例。
- Tip3:實(shí)例應(yīng)當(dāng)有正反兩個(gè)方面。比如,有一條業(yè)務(wù)規(guī)則是:對(duì)于購(gòu)買重量在10kg以上的訂單,才收取6元運(yùn)費(fèi)。所舉出的實(shí)例就應(yīng)該有正反兩個(gè):一個(gè)是重量是11kg,收取運(yùn)費(fèi)6元;一個(gè)是:重量為5kg,收取運(yùn)費(fèi)0元。
一個(gè)好的需求說明的例子:
一個(gè)劣質(zhì)的需求說明的例子:
根據(jù)原則改進(jìn)的例子:
04 用自動(dòng)化測(cè)試來頻繁驗(yàn)證需求
- Tip1:測(cè)試是為了驗(yàn)證需求,因此不可以只偏重于測(cè)試本身,而忽略了測(cè)試和需求之間的聯(lián)系。過度飽和的數(shù)據(jù)和測(cè)試用例的大爆炸是不可取的。
- Tip2:還是那句,測(cè)試是為了驗(yàn)證需求,因此不要在測(cè)試代碼中引入業(yè)務(wù)流程或者業(yè)務(wù)邏輯,不要驗(yàn)證系統(tǒng)是怎么做的,而要驗(yàn)證系統(tǒng)做的事對(duì)不對(duì)。
- Tip3:自動(dòng)化測(cè)試有很多種優(yōu)秀的工具,但不要執(zhí)著于于特定工具,認(rèn)為工具才是解決問題的王道。工具是為了測(cè)試服務(wù)的。
在傳統(tǒng)的流程中,龐大的需求說明往往跟不上實(shí)際開發(fā)中的需求變更,導(dǎo)致需求文檔在交付之時(shí)就已經(jīng)過時(shí)。代碼才是唯一能真正信任的。但是,如果通過持續(xù)集成對(duì)需求說明進(jìn)行頻繁驗(yàn)證,我們就能及時(shí)發(fā)現(xiàn)需求說明和系統(tǒng)代碼之間的差異,及時(shí)解決它們,從而保證需求說明和代碼是一直同步的??梢韵裥湃未a一樣信任需求說明。
頻繁驗(yàn)證的依據(jù)就是提煉需求產(chǎn)生的實(shí)例化需求,它是所有過程實(shí)施中都必須要反復(fù)進(jìn)行的工作。需求通過頻繁驗(yàn)證與用戶進(jìn)行頻繁確認(rèn);設(shè)計(jì)通過實(shí)例 化需求來頻繁驗(yàn)證設(shè)計(jì)是否滿足用戶的需求;開發(fā)通過實(shí)例化需求頻繁驗(yàn)證代碼中業(yè)務(wù)邏輯;測(cè)試通過實(shí)例化需求來頻繁驗(yàn)證交付的功能,并作為最后驗(yàn)收測(cè)試的依據(jù)。
提煉好功能的需求說明之后,我們就有了實(shí)現(xiàn)要達(dá)到的清晰目標(biāo),并且有了一個(gè)精確的方式來衡量何時(shí)已經(jīng)實(shí)現(xiàn)了目標(biāo)。每當(dāng)系統(tǒng)有所變更,提煉過的需求說明就可以用來檢查原有功能是否依然生效。自動(dòng)化驗(yàn)證帶實(shí)例的需求說明中,如果必須大量修改需求說明,那么就會(huì)失去提煉需求說明帶來的價(jià)值。
主流自動(dòng)化可執(zhí)行需求說明工具中,自動(dòng)化代碼依賴于需求說明,而需求說明并不依賴于自動(dòng)化代碼。
手動(dòng)測(cè)試中,準(zhǔn)備上下文環(huán)境所花的時(shí)間往往是主要瓶頸所在。而在自動(dòng)化測(cè)試中,時(shí)間主要花在了尋找測(cè)試失敗的原因上。傳統(tǒng)的自動(dòng)化測(cè)試描述的是一系列相互依賴的步驟,所以出了問題很難定位究竟是什么導(dǎo)致了問題。因此如果我們不去使用一個(gè)較大的腳本,轉(zhuǎn)而使用更多較小的、專注的且獨(dú)立的測(cè)試,那么可以讓測(cè)試更具彈性且可以降低維護(hù)成本,可以更快找出問題。
用戶界面自動(dòng)化的3個(gè)層次:
- 業(yè)務(wù)規(guī)則層。測(cè)試所展示的或所操作的是什么?例如:為購(gòu)買2本或2本以上書籍的客戶提供免費(fèi)送貨服務(wù)。
- 用戶工作流層。用戶如何通過UI使用某個(gè)功能,以更高的行為級(jí)別應(yīng)該怎么描述?例如,將2兩本書放進(jìn)購(gòu)物車,輸入地址信息,然后驗(yàn)證配送選項(xiàng)是否包含免費(fèi)送貨服務(wù)。
- 技術(shù)行為層。操作單個(gè)工作流的步驟需要哪些技術(shù)性步驟?例如:打開店鋪主頁(yè),使用testuser與testpassword登陸,跳轉(zhuǎn)到/book頁(yè)面,點(diǎn)擊CSS類是book的第一個(gè)圖片,等待頁(yè)面加載結(jié)束,點(diǎn)擊購(gòu)買鏈接等。
需求說明應(yīng)該以業(yè)務(wù)規(guī)則層來描述。自動(dòng)化層應(yīng)該通過組合技術(shù)行為上編寫的程序塊來處理用戶工作流層。這樣的測(cè)試易于理解、編寫高校,而且維護(hù)成本也相對(duì)較低。
1. 活文檔系統(tǒng)
維護(hù)需求文檔,通常是件讓人頭疼的事情。過于繁瑣的需求文檔會(huì)讓人喪失維護(hù)的動(dòng)力??墒?,系統(tǒng)的重構(gòu)和更新又偏偏需要這樣一份文檔。怎么辦呢?所幸的是,實(shí)例化需求為我們提供了這樣一種省時(shí)省力的方式——從自動(dòng)化測(cè)試用例中提取文檔!
最成功的團(tuán)隊(duì)不會(huì)滿足于一些頻繁驗(yàn)證的可執(zhí)行的需求說明,他們能確保很好的組織需求說明,讓大家很容易找到和獲取,并讓他們保持一致。活文檔是關(guān)于系統(tǒng)功能可靠的、權(quán)威的信息源。他和代碼一樣可靠,但是更容易閱讀和理解。支持人員可以用它來查明系統(tǒng)在做什么以及這樣做的原因。開發(fā)可以用它作為開發(fā)目標(biāo)。測(cè)試用來測(cè)試。分析功能變更請(qǐng)求的影響時(shí),業(yè)務(wù)分析師可以從他開始著手。還提供了回歸測(cè)試。
提煉出來的需求實(shí)例是對(duì)系統(tǒng)做了什么事最有力、最準(zhǔn)確、最新鮮的描述。而自動(dòng)化測(cè)試用例又使用了可執(zhí)行的方式實(shí)現(xiàn)了這些需求實(shí)例,我們?cè)偈褂靡恍┕ぞ甙炎詣?dòng)化測(cè)試用例提煉為HTML或是PDF的文本,那么,砰!一份簡(jiǎn)單易懂的活文檔就產(chǎn)生了!水到渠成,簡(jiǎn)單易懂,永不過時(shí)!
如果沒有活文檔,任何重大的重構(gòu)都是自尋死路。
- Tip1:活文檔和敏捷中的用戶故事卡有什么區(qū)別嗎?好像很類似的樣子。當(dāng)然有所不同。用戶故事是用故事的形式描述需求,活文檔則是運(yùn)用實(shí)例。另一個(gè)不同是,敏捷的故事卡在Sprint結(jié)束之后就沒有用了,通常不會(huì)長(zhǎng)久保存,而活文檔則是易于保存,同步更新的。
- Tips2:活文檔必須組織的井井有條,便于訪問。
- Tips3:用戶故事作為計(jì)劃的工具是非常出色的,但是他在組織現(xiàn)有系統(tǒng)功能方面沒有太大用處。因此可以以功能區(qū)域組織活文檔層次結(jié)構(gòu)。當(dāng)前迭代的需求說明是以用戶故事和功能來組織的。
05 操作流程
1. Pre-planning Meeting
參加人
產(chǎn)品、開發(fā)、測(cè)試代表
目標(biāo)
選擇優(yōu)先級(jí)高的需求進(jìn)行需求澄清和實(shí)例撰寫、精煉,獲得相對(duì)成熟的需求規(guī)格說明書,并明確下一迭代的backlog。
內(nèi)容
產(chǎn)品準(zhǔn)備好需求說明和基礎(chǔ)實(shí)例(描述預(yù)期功能的關(guān)鍵實(shí)例,作為測(cè)試的基礎(chǔ)用例),產(chǎn)品、開發(fā)、測(cè)試代表一起對(duì)需求進(jìn)行澄清。
隨后開發(fā)和測(cè)試一起對(duì)實(shí)例進(jìn)行擴(kuò)展(如邊界情況、需重點(diǎn)標(biāo)識(shí)的有問題的地方),再精煉,得到相對(duì)成熟的需求規(guī)格說明書,并準(zhǔn)備好cucumber的驗(yàn)收標(biāo)準(zhǔn)。
基本要求是將下一個(gè)迭代的全部需求的需求說明和基礎(chǔ)實(shí)例準(zhǔn)備好,其中優(yōu)先級(jí)高的有若干個(gè)可以已準(zhǔn)備好cucumber驗(yàn)收標(biāo)準(zhǔn)。
小技巧
反饋調(diào)查。是檢驗(yàn)一組人員是否對(duì)需求說明達(dá)成共識(shí)的好方法。在討論過一個(gè)故事之后,如果有人對(duì)故事提出了一個(gè)特殊用例,工作坊的主持人必須請(qǐng)參與者寫下他們認(rèn)為系統(tǒng)應(yīng)該怎樣工作,然后比較全組的回答。如果回答不一致,可以按回答結(jié)果分成多個(gè)小組,每個(gè)小組選出一個(gè)人來解釋他們的回答。通過討論可以揭示誤解的根源。
“我們能出找出會(huì)讓這個(gè)例子失效的數(shù)據(jù)?”
備注
- Pre-planning meeting不一定要和迭代綁定,只要能保證每次迭代的需求都已經(jīng)滿足上述基本要求即可。
- 在敏捷開發(fā)中,用戶故事的拆分是一個(gè)難點(diǎn),因?yàn)榧纫WC故事足夠小,又要在一個(gè)迭代中做到端到端。對(duì)于用戶故事來說,除了 Card, 還有更重要的 Conversation 和 Confirmation 。如果用戶故事的“撰寫”、“拆分”都是由團(tuán)隊(duì)中的個(gè)人完成的,那么無論是不是采取了故事卡片的形式,無論是否進(jìn)行了拆分,它其實(shí)和傳統(tǒng)的需求分析方法沒有什么區(qū)別。真正有別于傳統(tǒng)需求方法的,是我們可以通過一組有序的工作步驟、通過協(xié)作,從看似模糊、混亂的業(yè)務(wù)需求中梳理出清晰的脈絡(luò),把它們從需求的重重迷霧中發(fā)掘出來,識(shí)別、澄清、歸類這些細(xì)節(jié),然后按照價(jià)值大小、成本高低、依賴關(guān)系等因素為它們分配優(yōu)先級(jí),成為可以在開發(fā)迭代中持續(xù)流動(dòng)的價(jià)值單元,以此指導(dǎo)后續(xù)的開發(fā)活動(dòng)。因此實(shí)例化需求其實(shí)是給出了一個(gè)需求澄清活動(dòng)的更好方式。我們并沒有去“拆分”用戶故事。我們?cè)凇坝懻摗庇脩艄适?。討論使得用戶故事的工作流、業(yè)務(wù)規(guī)則都已經(jīng)足夠詳盡。事實(shí)上,現(xiàn)在不是用戶故事拆不開的問題,而是要多細(xì)節(jié),就有多細(xì)節(jié),也許我們發(fā)現(xiàn),為了方便管理,有些場(chǎng)景下還可能需要做一些小的歸并。無論如何,迭代項(xiàng)怎么劃分的自主權(quán)已經(jīng)完全把握在工程人員手中。例如,我們可以選擇首先實(shí)現(xiàn)一個(gè)工作流的主干部分,可以選擇首先實(shí)現(xiàn)工作流的一個(gè)業(yè)務(wù)步驟,可以選擇首先實(shí)現(xiàn)幾條業(yè)務(wù)規(guī)則,推遲后續(xù)幾條業(yè)務(wù)規(guī)則,等等。因此實(shí)例化需求的輸出并非和用戶故事一一對(duì)應(yīng),而是可以先對(duì)產(chǎn)品功能進(jìn)行討論,形成清晰的認(rèn)知后,再基于多種因素來安排迭代開發(fā)中的用戶故事。
- 并不是需求的所有情況都討論完畢,才能開始迭代,需求只要有了一個(gè)完整的例子就能開始迭代。尚未討論完全的情況可以視作模糊的東西在迭代中做探索。即便是簡(jiǎn)單的例子,在程序開始開發(fā)后也能發(fā)現(xiàn)問題。通過完成一些例子反而能夠更好輔助后面未討論完全的場(chǎng)景明晰起來。在項(xiàng)目開始階段實(shí)例化需求工作坊會(huì)比較密集,但是這樣的討論每個(gè)迭代都應(yīng)該持續(xù)發(fā)生,用戶故事卡片,是一種占位符(Card),能夠持續(xù)推動(dòng)活動(dòng)進(jìn)行。
2. Scrum Planning Meeting
參加人
團(tuán)隊(duì)全員
內(nèi)容
產(chǎn)品對(duì)本次迭代需求進(jìn)行講解和澄清。
產(chǎn)品、開發(fā)、測(cè)試一起對(duì)backlog里故事的需求說明及實(shí)例進(jìn)行審核。
隨后開發(fā)進(jìn)行規(guī)模評(píng)估和任務(wù)拆解。
需要指定故事負(fù)責(zé)人。故事會(huì)分配給某個(gè)特定的開發(fā),他會(huì)堅(jiān)持到該故事完成,他負(fù)責(zé)與其他團(tuán)隊(duì)進(jìn)行溝通、有效傳遞信息而無需所有開發(fā)人員都參與審核來確保他們理解故事,在看板上跟蹤進(jìn)度、在每日例會(huì)上檢查狀態(tài)和清除障礙)開會(huì)并仔細(xì)檢查所有測(cè)試。
3. Scrum過程中
待澄清
針對(duì)還未形成cucumber驗(yàn)收標(biāo)準(zhǔn)的需求,開發(fā)與測(cè)試結(jié)對(duì),擴(kuò)展和精煉實(shí)例,并編寫cucumber驗(yàn)收標(biāo)準(zhǔn)。
在完成編寫后,與產(chǎn)品再次進(jìn)行確認(rèn),三方溝通無誤后,該需求可進(jìn)入待實(shí)現(xiàn)隊(duì)列。
待實(shí)現(xiàn)
針對(duì)已經(jīng)相對(duì)成熟的需求,開發(fā)編寫B(tài)DD測(cè)試代碼(TDD也進(jìn)行),然后進(jìn)行實(shí)現(xiàn)。過程中有發(fā)現(xiàn)新的用例,則對(duì)需求規(guī)格說明和cucumber進(jìn)行更新。
在開發(fā)階段結(jié)束前,所有可執(zhí)行的需求說明都必須運(yùn)行通過,且通過開發(fā)自測(cè)。
待驗(yàn)證
測(cè)試對(duì)已經(jīng)通過自動(dòng)化測(cè)試的故事進(jìn)行手工測(cè)試和探索性測(cè)試。
待驗(yàn)收
全部測(cè)試通過后,團(tuán)隊(duì)給產(chǎn)品做一個(gè)快速的產(chǎn)品演示,讓他驗(yàn)收。
待部署
全部集成后,重新運(yùn)行整個(gè)系統(tǒng)的自動(dòng)化測(cè)試,測(cè)試對(duì)核心功能做手工測(cè)試,無誤后,代碼可上線進(jìn)入生產(chǎn)環(huán)境。
參考文獻(xiàn):
1.《實(shí)例化需求:不可或缺的精益、敏捷需求實(shí)踐》
2.《實(shí)例化需求》
本文由 @扶木桑 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash,基于CC0協(xié)議
非功能性需求怎么描述
干貨