1. 程式人生 > >BDD行為驅動開發簡介

BDD行為驅動開發簡介

-o 註意 min form http oca ati order -s

在學習Cucumber時,認識了BDD(Behaviour-Driven Development)行為驅動開發這個概念。在搜索過程中,發現提及相關概念的博客或者技術網站比較少。雖然在Cucumber的官網就有介紹相關知識的文檔,但是沒有提供中文,而且有些專業術語也比較拗口。在記錄筆記時候,就把官網這篇文檔翻譯成了中文,也就是這篇博客。

但是博主的知識有限,也沒有來得及好好修習有關極限編程的內容,所以翻譯不當之處,懇請讀者能多多指導。

原網頁(https://docs.cucumber.io/bdd/)

以下是譯文:

BDD概述(BDD Overview)

行為驅動開發(Behaviour-Driven Development,BDD)是一套實用方法(practice),旨在減少軟件開發過程中的一些常見而多余的活動:

  • 因為誤解需求或者需求模糊導致的返工

  • 不願重構代碼而積累技術債(Technical debt)

  • (組織的)谷倉效應和交接問題(silos and hand-overs)導致緩慢的反饋周期

BDD目標是減小團隊成員之間的交流障礙,培養(團隊)更好地理解客戶以及促進(團隊)和現實世界的實例(example,這個單詞下面都翻譯成“實例”)進行持續交流。

實例(example)描述了軟件怎樣按照預想的運行(behave),通常說明一個特定業務規則或者需求

一個簡單例子

Liz should be asked to guess again when she guesses "joke"

這個例子來自於一個猜單詞的遊戲,它說明了一個規則,規定一次猜測必須是5個字母。

(譯者註:這個例子的解釋應為“它說明了一個規則,規定當她猜測‘joke’這個單詞的時候要求她再猜一次”,原來的解釋可能有誤)

BDD可以分成兩個部分:刻意發現(Deliberate Discovery)和測試驅動開發(Test-Driven Development)

刻意發現

軟件項目出錯有很多原因。一個非常常見的原因是,不同組織或者不同團隊的人對於軟件如何運行和軟件正要嘗試解決什麽問題,意見不一。

Ignorance is the single greatest impediment to throughput

無知是產能最大的阻礙。 --Dan North

在開發開始之前,想方設法去發現(在問題域上)未知(的知識)的團隊會更有生產效率。因為那樣就會帶來更少的返工。那樣做的最有效的方法是通過在以下主要利益相關者之間進行對話和合作:

  • 產品負責人

  • 業務分析師

  • 領域專家

  • 用戶

  • 程序員

  • UX設計師

  • 測試人員

  • 運維工程師

  • 可能還有其他一些人員

Cucumber是通過一種叫做實例映射(Example Mapping)的一種為了一起提出實例的簡單技術(a simple technique for coming up with examples together),來完成(上面說的發現未知)這件事。

當(在軟件生命周期中擔任)不同角色的人們談論一個具體實例的時候,他們通常會在問題域上發現很多(知識)。

他們產生的實例在一起就會變成自動化測試和描述系統如何運行的活文件(living documentation)。

測試驅動開發

測試驅動開發(Test-Driven Development,TDD)是一種自動化測試在編碼之前編寫的開發技術。開發者使用那些測試來驅動(drive)開發。

技術分享圖片

TDD可以在從驗收測試到單元測試(範圍內)的不同粒度上使用。 TDD的BDD風格(The BDD flavour of TDD)使用自然語言來描述測試。它們可以被非程序員理解,(同時)也能基於它使用實例映射來協同地創建實例。

Gherkin是一種關於自然語言測試的簡單語法,Cucumber是可以執行這些測試的工具。

編碼後測試不是BDD。

許多人在編碼後編寫測試,甚至在用Cucumber時也如此。但這既不是BDD,也不是TDD。因為測試並沒有在編寫完成後(用於)驅動(代碼)實現。

TDD/BDD並不屬於測試

一個關於TDD和BDD的常見誤解認為,它們是測試技術。但實際並不如此。就像其名字所說的那樣,TDD和BDD屬於軟件開發。

它是(讓你)接近你的設計(目標)和迫使你在編碼前思考你想要的結果以及API的過程。

自動化測試是TDD和BDD的副產品。


Example Mapping

在你把用戶故事(user story)投入到開發中之前,非常關鍵的一點是要通過對話來闡明並遵循驗收標準(acceptance criteria)。

實例映射是一個使得這個對話簡短和富於生產效率的簡單方法。

它是怎麽工作的

具體實例是一個幫助我們探索和理解問題域的好方法。它們(指具體實例)為我們的驗收測試打下一個好基礎。

當談論實例(example)時,其它也值得獲取的事情可能會出現在對話中:

  • 概述一個實例集合或表述其它限制的規則

  • 對話或制造的假設中不能被回答的問題

  • 已經發現或剖析過的,同時因延期而逾期的新的用戶故事

我們可以(通過)索引卡片(的方式)獲取這些不同種類的信息,(通過)導圖(放入方式)可以組織它們(的關系):

  • 我們在黃色卡片上寫下故事,然後把它放在頂部

  • 每一個驗收標準或規則寫在藍色卡片上,然後放在黃色故事卡片下面

  • 說明這些規則的實例寫在綠色卡片上,然後根據相關規則置放

  • 會話中不能回答的問題就寫在紅色卡片上,這樣我們的會話可以(暫時不用關註這些問題)繼續進行

我們可以保持(對話)進行下去,直到項目組對故事的邊界足夠清晰感到滿意,或者我們用完了時間。

更多信息

譯者註:原網頁有一些鏈接,請直接訪問原網頁


實例(Examples)

好的BDD實例是具體的而不是抽象的。它們提及(mention)人物和地點的名字、確切的時間和總數,還有與軟件的問題域有關的一切事物。

好的實例不會提及技術細節。

Imagine it‘s 1922

大多數軟件做的都是人們手工就能完成但不是那麽有效率的事情。

努力嘗試提出不對技術做任何假設的實例來。想像現在是1922年,一個沒有計算機的年代。


誰做了什麽(Who Does What?)

誰應該寫Gherkin文檔,誰應該寫步驟定義(step definition)呢?

產品負責人,業務分析師,程序員和測試人員經常搞不清楚誰應該承擔什麽責任。

答案取決於幾個因素,比如團隊結構、技能、文化、做事方法(process)等。

三劍客(The Three Amigos)

三劍客是一個將用戶故事帶到並轉變為整潔、徹頭徹尾的Gherkin場景(Scenario)的會議。它至少包含三種(角色的,或者劍客的)聲音:

  • 產品負責人----更關心應用的邊界(scope)。這涉及到將用戶故事轉譯成一系列的特征(Features)。當測試人員提出邊界情況(edge case)時,產品負責人負有決定哪一種(情況)在(應用)邊界內的責任。

  • 測試人員----產生很多的場景和邊界情況。應用將會怎樣崩潰?在這些特征裏面,什麽用戶故事還沒有被我們考慮進去呢?

  • 研發人員----為場景添加步驟(Steps),思考深入每個需求的細節。應用怎樣執行?有哪些不為人知的障礙和需求(需要越過和滿足)?

這些對話會帶來很好的測試,因為每一個人從不同的角度來看產品。由此,讓這些(擔任)角色(的人員)參與討論,一起發現實例是十分必要的。實例映射和事件風暴(Event Storming)對於發現實例來說,都是很好的協同分析技術。

最後,限制這些會議(指上面這個三劍客會議)參與人員只能為這三種人,或者在項目開始階段只舉行一次這樣的會議,都是不合理的。(應該)持續地提煉你的特征(features)和與任何人合作來深刻理解如何討論、開發和測試你的應用。

書寫Gherkin(Writing Gherkin)

任何特征的第一份手稿最好是由或者與“領域專家”合作書寫。這種人典型(情況下)是一個非程序員並且總是那些站在用戶或者業務角度、了解特征領域(features‘s domain)的人。

然後程序員會重做(go over)場景,提煉步驟來(使得情景容易)闡明和提升易測性(testability)。然後結果被領域專家評審,確保(項目)意圖沒有被程序員改變。

這個循環會重復下去直到參與(項目)的每個人都對場景(是否)精確地描述了哪些東西以一種可測的方式被需要(what is wanted in a testable manner)感到滿意。

書寫特征(Writing Features)

Cucumber測試從特征的角度來書寫。每一個特征(Feature)包含一個或多個場景(Scenario)。

讓我們從一個特征文件(Feature file)開始:

Feature: Explaining Cucumber
In order to gain an understanding of the Cucumber testing system
As a non-programmer
I want to have an overview of Cucumber that is understandable by non-geeks
?
Scenario: A worker seeks an overview of Cucumber
Given I have a coworker who knows a lot about Cucumber
When I ask my coworker to give an overview of how Cucumber works
And I listen to their explanation
Then I should have a basic understanding of Cucumber

註意場景並沒有深入軟件(在這個例子下是coworker)細節。它一直關註於特征用來服務的人(這種例子下是a non-programmer)的立場。

每一個特征文件可以有一個位於頂部的特征描述和任意數量的場景。

Feature那一行是特征的名字,名字應該是一個簡短的標簽。

In order to表現擁有特征的原因/正當理由,通常來說,應該要與項目的核心目標或者“業務價值”匹配:

  • 項目收入

  • 增益收入

  • 管理開銷

  • 提升品牌價值

  • 讓產品變得卓越

  • 為你的客戶提供更多價值

As a描述由特征服務的人物/用戶的角色。

I want用一句話解釋特征應該做什麽。

所以,這三行涵蓋了為什麽(Why)、誰(Who)和什麽(What)。接下來,這份文檔(指的是上面這個特征文件)將會用場景(Scenario)來深入介紹"How"。

場景(Scenarios)

一個特征可以有任意數量的場景。

當然,如果你在一個特征中擁有太多的場景,事實上你可能在描述不止一個特征。這種情況發生時,我們建議你把文檔(特征文件)分成幾個獨立的特征定義(Feature definition)。這裏所說的“太多”是主觀的,應由你決定何時該分解一個特征。

第一行簡單描述場景用來包含的內容。如果你不能用一句話來描述你的場景(不能用連寫句run-on sentence),那麽很可能你嘗試包含的內容太多,這個時候應該把特征分成多個場景。

在那之後跟著的是一些步驟(Step)的組合----以關鍵字Given,WhenThen(典型情況就是這個次序)開頭的幾行。

你可以有多個使用相同關鍵字的行。比如在Given there is something後跟著Given I have another thing。為了增加可讀性,你可以使用關鍵字AndBut來替換。比如在Given there is something之後跟著And I have another thing

一般說來,任何Given步驟所在行應該只描述一件事。如果你在一個步驟中有像這樣的詞,你可能在描述的內容超過了一個步驟,你應該把它分成多個步驟。

比如說:

When I fill in the  "Name" field and the "Adress" field

變成:

When I fill in the "Name" field
And I fill in the "Adress" field

Cucumber特征最好需要滿足一致性。不能用不同的方式來說同一件事,而是每次都用同一種方式。

比如:

Given I am logged in

Given I have logged in to the site

有完全一樣的意思,所以最好選擇一句並在之後的每個需要登錄的場景中使用同一句。


書寫更好的Gherkin(Writing better Gherkin)

有一些使得你的Gherkin更好的方式。

’描述行為(Describe behaviour)

你的場景(Scenario)應該描述系統預期的行為,並不是實現。換句話說,應該描述 什麽What而不是 怎樣How

比如,對於一個驗證身份的場景,你應該寫:

When "Bob" logs in

而不是

Given I visit "/login"
When I enter "Bob" in the "user name" field
And I enter "tester" in the "password" field
And I press the "login" button
Then I should see the "welcome" page

在第一個例子中,When "Bob" logs in是一個功能要求(functional requirement)。第二個長很多的例子是一個過程參照(procedural reference)。功能要求是特征,但是過程屬於實現細節。

那種方式下,當一個特征的實現改變了,你只需要改變過程步驟。行為不需要改變,因為只是實現發生了改變。事實上,當你寫一個特征項時,應該問你自己一個問題:如果實現改變了,(特征的)措辭也需要改變嗎?

如果答案是yes,那麽你應該返工(你寫的特征)來避免實現特定細節。附帶好處是因此你的場景將會更簡短和更加容易遵循和理解。

BDD行為驅動開發簡介