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