一文講清楚什么是行為驅(qū)動(dòng)開(kāi)發(fā)
行為驅(qū)動(dòng)開(kāi)發(fā)(Behavior-Driven Development, BDD)的概念來(lái)自于測(cè)試驅(qū)動(dòng)開(kāi)發(fā),強(qiáng)調(diào)使用DSL(Domain Specific Language,領(lǐng)域特定語(yǔ)言)描述用戶行為,定義業(yè)務(wù)需求,是需求分析人員、開(kāi)發(fā)人員與測(cè)試人員進(jìn)行溝通的有效方法。DSL是一種編碼實(shí)現(xiàn),相比自然語(yǔ)言更加精確,又能以符合領(lǐng)域概念的形式滿足所謂“活文檔(Living Document)”的要求??梢哉f(shuō),行為驅(qū)動(dòng)開(kāi)發(fā)將編碼實(shí)現(xiàn)與業(yè)務(wù)行為描述***地結(jié)合起來(lái),走出了一條業(yè)務(wù)分析人員、開(kāi)發(fā)人員與測(cè)試人員都能接受的中庸之道。
行為驅(qū)動(dòng)開(kāi)發(fā)的核心在于“行為”。當(dāng)業(yè)務(wù)需求被劃分為不同的業(yè)務(wù)場(chǎng)景,并以“Given-When-Then”的形式描述出來(lái)時(shí),就形成了一種范式化的領(lǐng)域建模規(guī)約。編寫(xiě)領(lǐng)域特定語(yǔ)言的過(guò)程,其實(shí)就是不斷發(fā)現(xiàn)領(lǐng)域概念的過(guò)程。因此,采用BDD進(jìn)行開(kāi)發(fā),最重要的產(chǎn)出不是可以自動(dòng)運(yùn)行的驗(yàn)收測(cè)試,而是它提供了團(tuán)隊(duì)交流的平臺(tái),并在其約束之下完成了領(lǐng)域建模。由于團(tuán)隊(duì)的不同角色都參與了這個(gè)過(guò)程,就保證了領(lǐng)域模型的一致性與準(zhǔn)確性。
在進(jìn)行行為驅(qū)動(dòng)開(kāi)發(fā)時(shí),需要避免兩種錯(cuò)誤的傾向:
- 從UI操作去表現(xiàn)業(yè)務(wù)行為
- 描述技術(shù)實(shí)現(xiàn)而非業(yè)務(wù)需求
例如,我們要編寫(xiě)“發(fā)送郵件”這個(gè)業(yè)務(wù)場(chǎng)景,可能會(huì)寫(xiě)成這樣:
- Scenario: send email
- Given a user "James" with password "123456"
- And I sign in
- And I fill in "mike@dddpractice.com" in "to" textbox
- And fill in "test email" in "subject" textbox
- And fill in "This is a test email" in "body" textarea
- When I click the "send email" button
- Then the email should be sent sucessfully
- And shown with message "the email is sent sucessfully"
該業(yè)務(wù)場(chǎng)景描寫(xiě)的不是業(yè)務(wù)行為,而是用戶通過(guò)UI進(jìn)行交互的操作流程。這種方式實(shí)則是讓用戶界面捆綁了你對(duì)領(lǐng)域行為的認(rèn)知。準(zhǔn)確地說(shuō),這種UI交互操作并非業(yè)務(wù)行為,例如上述場(chǎng)景中提到的button與textbox控件,與發(fā)送郵件的功能并沒(méi)有關(guān)系?;蛟S換一個(gè)UI設(shè)計(jì),使用的控件又完全不同了。
那么換成這樣的寫(xiě)法呢?
- Scenario: send email
- Given a user "James" with password "123456"
- And I sign in after OAuth authentification
- And I fill in "mike@dddpractice.com" as receiver
- And "test email" as subject
- And "This is a test email" as email body
- When I send the email
- Then it should connect smtp server
- And all messages should be composed to email
- And a composed email should be sent to receiver via smtp protocal
該場(chǎng)景的編寫(xiě)暴露了不必要的技術(shù)細(xì)節(jié),如連接到smtp服務(wù)器、消息組合為郵件、郵件通過(guò)smtp協(xié)議發(fā)送等。對(duì)于BDD而言,場(chǎng)景應(yīng)該關(guān)注于做什么(what),而不是怎么做(how)。如果在業(yè)務(wù)分析過(guò)程中,糾纏于技術(shù)細(xì)節(jié),就可能導(dǎo)致我們忽略了業(yè)務(wù)價(jià)值。在業(yè)務(wù)建模階段,業(yè)務(wù)才是重心,不能舍本逐末。
那么,該怎么寫(xiě)?當(dāng)我們使用DSL編寫(xiě)業(yè)務(wù)場(chǎng)景時(shí),不要考慮任何UI操作,甚至需要拋開(kāi)業(yè)已設(shè)計(jì)好的UI原型,也不要考慮任何技術(shù)細(xì)節(jié)。在編寫(xiě)好業(yè)務(wù)場(chǎng)景之后,可以驗(yàn)證:如果我們更換了UI設(shè)計(jì),調(diào)整了UI布局,是否需要修改業(yè)務(wù)場(chǎng)景?同理,如果我們改變了技術(shù)實(shí)現(xiàn)方案,是否需要修改業(yè)務(wù)場(chǎng)景?如下場(chǎng)景采用業(yè)務(wù)行為的形式編寫(xiě):
- Scenario: send email
- Given a user "James" with password "123456"
- And I sign in
- And I fill in a subject with "test email"
- And a body with "This is a test email"
- When I send the email to "Mike" with address "mike@dddpractice.com"
- Then the email should be sent sucessfully
我們要將DSL描述的場(chǎng)景視為一種可讀的需求規(guī)格(Specification),通過(guò)它準(zhǔn)確地表現(xiàn)領(lǐng)域知識(shí),就可以幫助我們提煉出隱含的領(lǐng)域概念。例如:
- Scenario: validate the given date for reporting period
- Given the reporting period as prior 13 month to report month
- And the reporting month is "April 2018"
- When user choose the "April 2017"
- Then validation result is true
- When user choose "March 2017"
- Then validation result is false
場(chǎng)景描述中的ReportingPeriod蘊(yùn)含了與財(cái)務(wù)報(bào)表相關(guān)的領(lǐng)域知識(shí),即有效報(bào)表周期為13個(gè)月,ReportingPeriod自身應(yīng)該履行驗(yàn)證給定日期是否有效的職責(zé)。
【本文為51CTO專欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】