一文講清楚什么是行為驅(qū)動開發(fā)
行為驅(qū)動開發(fā)(Behavior-Driven Development, BDD)的概念來自于測試驅(qū)動開發(fā),強調(diào)使用DSL(Domain Specific Language,領(lǐng)域特定語言)描述用戶行為,定義業(yè)務(wù)需求,是需求分析人員、開發(fā)人員與測試人員進行溝通的有效方法。DSL是一種編碼實現(xiàn),相比自然語言更加精確,又能以符合領(lǐng)域概念的形式滿足所謂“活文檔(Living Document)”的要求。可以說,行為驅(qū)動開發(fā)將編碼實現(xiàn)與業(yè)務(wù)行為描述***地結(jié)合起來,走出了一條業(yè)務(wù)分析人員、開發(fā)人員與測試人員都能接受的中庸之道。
行為驅(qū)動開發(fā)的核心在于“行為”。當業(yè)務(wù)需求被劃分為不同的業(yè)務(wù)場景,并以“Given-When-Then”的形式描述出來時,就形成了一種范式化的領(lǐng)域建模規(guī)約。編寫領(lǐng)域特定語言的過程,其實就是不斷發(fā)現(xiàn)領(lǐng)域概念的過程。因此,采用BDD進行開發(fā),最重要的產(chǎn)出不是可以自動運行的驗收測試,而是它提供了團隊交流的平臺,并在其約束之下完成了領(lǐng)域建模。由于團隊的不同角色都參與了這個過程,就保證了領(lǐng)域模型的一致性與準確性。
在進行行為驅(qū)動開發(fā)時,需要避免兩種錯誤的傾向:
- 從UI操作去表現(xiàn)業(yè)務(wù)行為
- 描述技術(shù)實現(xiàn)而非業(yè)務(wù)需求
例如,我們要編寫“發(fā)送郵件”這個業(yè)務(wù)場景,可能會寫成這樣:
- 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ù)場景描寫的不是業(yè)務(wù)行為,而是用戶通過UI進行交互的操作流程。這種方式實則是讓用戶界面捆綁了你對領(lǐng)域行為的認知。準確地說,這種UI交互操作并非業(yè)務(wù)行為,例如上述場景中提到的button與textbox控件,與發(fā)送郵件的功能并沒有關(guān)系。或許換一個UI設(shè)計,使用的控件又完全不同了。
那么換成這樣的寫法呢?
- 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
該場景的編寫暴露了不必要的技術(shù)細節(jié),如連接到smtp服務(wù)器、消息組合為郵件、郵件通過smtp協(xié)議發(fā)送等。對于BDD而言,場景應(yīng)該關(guān)注于做什么(what),而不是怎么做(how)。如果在業(yè)務(wù)分析過程中,糾纏于技術(shù)細節(jié),就可能導致我們忽略了業(yè)務(wù)價值。在業(yè)務(wù)建模階段,業(yè)務(wù)才是重心,不能舍本逐末。
那么,該怎么寫?當我們使用DSL編寫業(yè)務(wù)場景時,不要考慮任何UI操作,甚至需要拋開業(yè)已設(shè)計好的UI原型,也不要考慮任何技術(shù)細節(jié)。在編寫好業(yè)務(wù)場景之后,可以驗證:如果我們更換了UI設(shè)計,調(diào)整了UI布局,是否需要修改業(yè)務(wù)場景?同理,如果我們改變了技術(shù)實現(xiàn)方案,是否需要修改業(yè)務(wù)場景?如下場景采用業(yè)務(wù)行為的形式編寫:
- 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描述的場景視為一種可讀的需求規(guī)格(Specification),通過它準確地表現(xiàn)領(lǐng)域知識,就可以幫助我們提煉出隱含的領(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
場景描述中的ReportingPeriod蘊含了與財務(wù)報表相關(guān)的領(lǐng)域知識,即有效報表周期為13個月,ReportingPeriod自身應(yīng)該履行驗證給定日期是否有效的職責。
【本文為51CTO專欄作者“張逸”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】