6

BDD(6):讓Step找到Step Definition

 2 years ago
source link: http://teddy-chen-tw.blogspot.com/2017/02/bdd6stepstep-definition.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

2017年2月21日 星期二

BDD(6):讓Step找到Step Definition

Feb. 21 10:57~12:46

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

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

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

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

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

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

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

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傳進來。

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

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

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

延伸閱讀

沒有留言:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK