0

BDD(2):大家來吃小黃瓜之Cucumber運作原理

 2 years ago
source link: http://teddy-chen-tw.blogspot.com/2013/07/bdd2cucumber.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

BDD(2):大家來吃小黃瓜之Cucumber運作原理

July 17 21:05~23:59

在《BDD(1):詳盡的文件就是可用的軟體》Teddy提到將使用者需求採用「可執行軟體」來表達的好處,今天以及接下來這一系列文章要介紹Cucumber這個BDD工具(嚴格講起來是Cucumber-JVM)。

Feature、Scenario、Step

首先看一個例子,如何將使用者需求以Cucumber來表達:

Feature: Greeting
  Scenario: Say hello world
    Given I have a greeting application with "Hello"
    When I ask it to say hi
    Then I receive "Hello World"

上面這個驗收測試的意思是說:「我有一隻greeting應用程式,在啟動它的時候同時傳給它 "Hello"這個字串。當我呼叫它的hi功能,我會收到 "Hello World"」。雖然上面的驗收測試是用英文撰寫,但Cucumber的驗收測試其實支援40幾種不同的語言,其中包含了正體中文,日後有機會再介紹用正體中文撰寫驗收測試的例子。一個Cucumber的驗收測試檔案要描述在.feature的文字檔當中,這個檔案有三個基本元素:

  • Feature:一個feature代表一個功能,大小相當於一個user story。以ATM(提款機)應用程式為例子,feature包含「身分驗證」 、「提款」 、「轉帳」 、「繳費」 、「餘額查詢」 等 。
  • Scenario:一個功能的操作路徑,以ATM的「提款」feature為例子,可能包含「提款成功」 、「餘額不足」、 「密碼錯誤」 、「卡片無法讀取」、「金資中心連線錯誤」、「提款機現金不足」 、「銀行暫停作業」等scenario。以驗收測試的角度來看,一個scenario就是一個驗收測試案例。因為一個feature可以包含好幾的scenario,所以一個Cucumber的.feature檔案相當於好幾的測試案例,如果這些測試案例全部通過,就代表這個feature通過驗收條件。
  • Step:一個scenario的操作步驟。在Cucumber裡面scenario的標準寫法由given-when-then所組成。Given的步驟用來描述要準備那些測試環境(相當於單元測試裡面的準備test fixture),when的步驟用來描述如何執行待測程式(相當於單元測試裡面的execution),then的步驟用來描述如何驗證測試是否成功(相當於單元測試裡面的assertion)。

如果有寫過use case的鄉民,應該對於feature、scenario、step的這種關係很熟悉。一個use case展開之後有很多執行路徑,每一個執行路徑就是一個scenario,而每一個scenario的執行步驟就是step。所以要把feature想成是一個use case應該也沒什麼不行,只不過從大小的角度來看,一個use case通常包含了若干的user story,也就是說use case比user story大,而且有些use case可能會很複雜。一般來講一個feature裡面通常包含5~20個scenario,如果是use case的話,展開之後的scenario應該很輕易地就會超過這個數量。

膠水程式—Step Definition

看到這邊鄉民們應該會有一個疑問:「不是說好了要把需求用可執行軟體的方式來表達嗎?前面那個Cucumber驗收測試範例,也還是一個純文字檔,根本不是可執行軟體啊。」

為了讓非開發人員 (客戶、使用者、Product Owner或測試人員)能夠看懂需求,所以Cucumber的驗收測試是採用「地球人看得懂的語言」(spoken language)來撰寫。當然這樣的純文字檔是無法單獨執行,必須還要有一個機制,告訴Cucumber每一個.feature檔案裡面所描述的step,對應到哪一段可執行程式。這些對應程式(膠水程式)是一個method,在這個method裡面開發人員手動把step的文字描述轉換成相對應的程式碼。以上面這個Greeting feature為例,它包含三個step:

  • Given I have a greeting application with "Hello":開發人員自己寫一個method,在這個method裡面把這個greeting待測程式給new出來,然後傳入"Hello"給greeting程式。
  • When I ask it to say hi:呼叫greeting程式的hi method,並把它的傳回值保存起來。
  • Then I receive "Hello World":比對剛剛呼叫hi method的傳回值是否等於"Hello World",如果是則測試通過。

上面的邏輯寫成Java程式就變成下圖這個鳥樣子挑眉質疑,內容看不懂沒關係,以後會解釋。運作原理就是在method上面貼annotation,Cucumber把這種method稱為Step Definition,是由開發人員負責撰寫的。在執行驗收測試案例的時候,Cucumber會自動做字串比對,把.feature檔案裡面的每一個step連結到每一個step definition method。如果找不到相對應的step definition,Cucumber會丟出錯誤訊息提醒開發人員去定義這些step definition。

依據BDD的流程,這些step definition一開始的內容都是空的(因為此時待測程式根本還沒開始寫),也就是說這些驗收測試一開始的執行結果都是失敗。等待開發人員實作了待測程式的功能之後,這些驗收測試才會通過。

附帶說明一下,上圖的step definition是用Java程式撰寫,原本Cucumber的step definition是使用Ruby程式撰寫。因為Teddy不懂Ruby,但又想用Cucumber來當作BDD的工具(還記得嗎,Cucumber是用Ruby開發的工具),所以找了一個Cucumber-JVM這個用Java開發的工具,讓開發人員可以用Java程式來撰寫step definition。下一集Teddy會介紹如何在Eclipse裡面使用Cucumber-JVM,敬請期待。

Cucumber測試案例執行結果。

最後以一張圖作為這一集的結論。

友藏內心獨白:了解之後就覺得蠻簡單的微笑


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK