l

2017年2月21日 星期二

BDD(6):讓Step找到Step Definition

Feb. 21 10:57~12:46

屏幕截图 2017-02-21 12.45.19

 

Cucumber的初學者首先會遇到環境設定的問題,在〈在IntelliJ IDEA使用Cucumber(上)〉與〈在IntelliJ IDEA使用Cucumber(下)〉已經介紹了如何設定環境,接下來要談另一個常見的問題:「如何把scenario的每一個step對應到一個step definition程式碼?

***

假設鄉民們要開發會計系統或門市銷售系統,其中有一個「開發票」功能。發票分成三聯式(公司報帳使用)與二聯式(個人使用)。三聯式發票會顯示含稅金額(tax included price)未稅金額(tax excluded price)稅金(VAT,加值型營業稅),二聯式發票則只會顯示前兩者。

▼以下是一個Cucumber範例,第一個例子是開立三聯式發票。稅率5%,含稅價格17000,則稅金為810,未稅價格為16190。

屏幕截图 2017-02-21 11.29.08

 

這個用「文字」寫成的例子,其中Given、When、Then、And開頭的每一條敘述稱為一個step(步驟)。要讓這個例子「跑起來」,必須要連結到step definition(步驟定義)程式,也就是這系列文章前幾集提到的「膠水程式」。

▼有些IDE有內建或外掛工具可以自動產生step definition程式,如果沒有也沒關係,直接跑Cucumber會看到以下錯誤訊息:

屏幕截图 2017-02-21 11.37.01

 

Cucumber告訴我們有1個Scenario其中包含5個Step都沒有定義,並且建議宣告長成上圖中「那個樣子」的程式碼來定義它。也就是說Cucumber把它想尋找的step definition程式長什麼樣子告訴我們,我們只要照抄即可。上述例子是Java  8的程式,step definition支援Lambda語法。

***

▼以下是Java 8的step definition程式碼,因為使用Lambda所以不需要針對每一個step單獨定義一個method,只要把全部的step definition寫成Lambda(沒有名字的函數)定義在建構函數之中即可。

屏幕截图 2017-02-21 11.47.32

Cucumber會用regular expression去對應step與step definition,例如:

Given The VAT rate is 0.05

對應到下面這條Lambda表示式:

Given("^The VAT rate is (\\d+)\\.(\\d+)$", (Integer arg1, Integer arg2)

「The VAT rate  is」這幾個字在step和step definition中都一樣,0.05被Cucumber轉成 (\\d+)\\.(\\d+),\d代表「數字」,+代表「一或多」,() 稱為capture group,表示被括號括起來的部分要特別處理。至於\d前面要多加一個\表示逸出字元。最後,「The VAT rate is (\\d+)\\.(\\d+)」字串前後各有一個^和$字元稱為anchor,用來表示只比對到此的意思。舉個例子,如果忘了打$:

Given("^The VAT rate is (\\d+)\\.(\\d+)", (Integer arg1, Integer arg2)

則以上這個step definition可以對應到以下這兩個step:

Given The VAT rate is 0.05

Given The VAT rate is 0.08 in Japan

***

看到這裡發現Cucumber自動幫我們產生的Given("^The VAT rate is (\\d+)\\.(\\d+)$", (Integer arg1, Integer arg2)有一個問題,它把0.05當成兩個整數,中間隔著「.」這個字元,但我們希望0.05是double型態,怎麼辦?很簡單,自己改一下regular expression就可以了:

Given("^The VAT rate is (\\d+\\.\\d+)$", (Double arg1) -> {
    System.out.println("VAT = " + arg1);
});

▼執行結果確認Cucumber有把0.05當成double傳進來。

屏幕截图 2017-02-21 13.22.20

***

剛開始看到Cucumber產生的step definition可能會被其中奇怪的符號給嚇一跳,仔細一看其實不難理解,除了\d以外,另外還有兩個常用的字元表示法:

  • \w:[A-Za-z0-9_],英文字母和數字,以及底線符號。
  • \s:[\t\r\n],代表空白字元。

***

友藏內心獨白:看久了就習慣了。

 

延伸閱讀

  1. BDD(1):詳盡的文件就是可用的軟體
  2. BDD(2):大家來吃小黃瓜之Cucumber運作原理
  3. BDD(3):在Eclipse執行Cucumber-JVM
  4. BDD(4):第一個Cucumber-JVM範例,上集
  5. BDD(5):第一個Cucumber-JVM範例,下集
  6. 在IntelliJ IDEA使用Cucumber(上)
  7. 在IntelliJ IDEA使用Cucumber(下)

沒有留言:

張貼留言