# Cucumber 入門筆記 (BDD自動化測試框架)
###### tags: `publishmynoteblog`

## TOC
[TOC]
## 觀念介紹
### BDD
* BDD(Behaviour-Driven Development) 是用來發現問題、方便協作和示範,而非測試本身。
> BDD is about discovery, collaboration and examples (and not testing).
> (Ref: [Cucumber: Introduction](https://cucumber.io/docs/guides/overview/))
* Why BDD?
* TDD 是一種軟體開發流程,先測試再開發
* TDD 所實作的測試程式碼,可以作為工程師之間討論測試案例或使用情境的基礎
* 但是對非開發人員,如 PM、PO、Designer 來說,很難透過程式碼去理解想討論的測試案例,也更難根據測試案例進一步討論軟體的功能
* What's BDD?
* TDD 是實作前先寫測試
* BDD 比 TDD 更進一步,在寫測試前還要先寫測試規格,這份測試規格會用更接近人類語意的方式描述軟體功能和測試案例
* 但是這份規格並不是單純的敘述軟體的功能,而是一份「可以被執行的規格」,也就是可以被轉成自動化測試。
### Cucumber
* Cucumber 是一個支援 BDD 的工具。
* 可以讀取純文字的 specification 檔案,並驗證軟體是不是符合 Spec 描述。
* 重要術語:specification, scenario, step
* 一個 specification 裡包含多個 scenario,每一個 scenario 有很多 step 要完成。
* (In Cucumber, an example is called a scenario)。
* specification 是可執行的(executable),使用名叫 **Gherkin** 的語法來描述。
* Cucumber 驗證軟體是否符合 specification,並生成一個報告,指示每個 scenario 的成功或❌失敗。
* 在寫 Production code 前先寫 Scenarios/specification)。
* 當 Production code 寫好後,Scenarios 擔任文件(living documentation)和自動化測試的角色。
* Cucumber 三大目的:

(Source: [Cucumber: Introduction](https://cucumber.io/docs/guides/overview/))
### Gherkin 描述語法 (feature)
* 一種簡單的描述語法,用來撰寫 specification。
* Gherkin 有幾個目的:
* 能描寫明確可執行的 specification,讓 Cucumber 能看懂,同時具備人類語意可讀性
* 能透過 Cucumber 進行自動化測試
* 能文件化系統的實際行為(actually behaves)
* Gherkin 的撰寫支援許多種人類語言,團隊可以用自己喜歡的語言
* e.g., 英文、繁簡體中文
* Ref: [Cucumber: Gherkin Reference - Spoken Languages](https://cucumber.io/docs/gherkin/reference/#spoken-languages)

(Source: [Cucumber-java入门基础篇 - chengly0129的专栏 - CSDN博客](https://blog.csdn.net/chengly0129/article/details/79197598))
* Gherkin 文件
* Scenario 用 Gherkin 的表現形式撰寫
* 存成副檔名為`.feature` 的檔案,放在 `feature` 或其子資料夾底下
* 一個專案有很多 feature,一個 `.feature` 檔裡有很多 scenario,一個 scenario 有很多step
* Gherkin 文件會一起加入版控
* 誰應該寫 Gherkin
* 建議是開發人員或 tester
* PO或業務寫容易適得其反(可能畢竟不像工程師那樣有語法定義的概念)
### Step Definitions
* 為了將 specification 裡的 step 轉換成實作程式語言(e.g., JavaScript, Java)
* Step Definitions 定義每一個 `Gherkin Step` 對應的實作(稱為硬連結 `hard-wire`)
* 誰應該寫Step Definition:
* 和寫 Gherkin 同樣的人
* 這就是為什麼建議 Gherkin 由 developer 或 tester 寫
### Step Keywords
> Ref: [Cucumber: Gherkin Reference - Steps](https://cucumber.io/docs/gherkin/reference/#steps)
* feature 檔裡,每個 `Gherkin Step` 前面都會配一個關鍵字,例如 `Given`, `When`
* Step 開頭 Keywords:
| Keyword | Semantics |
| :-------: | --------- |
| `Given` | 前置條件的設置 |
| `When` | 發生一個事件 |
| `Then` | 驗證預期結果 |
| `And` | 如果有連續多個 `Given`,第二個開始可以用 `And` 更貼近人類語意 |
| `But` | 如果有連續多個 `Then`,第二個開始可以用 `But` 更貼近人類語意 |
> PS: `And` 和 `But` 不是硬性要用
* **Note: 當 Cucumber 在尋找 `Gherkin Step` 對應的實作程式 (Step Definitions) 時,不會管關鍵字是什麼。**
* 換句話說,不能使用兩個 Keyword 對同一句文法定義 step definition
* 例如以下會視為重複定義:
```
Given I log in
Then I log in
```
* 換句話說,一個 step 用什麼關鍵字其實不影響程式,只是選擇語意適當的關鍵字更有助於人類閱讀
* 實際 step 做什麼事,還是看 Step Definitions 的實作內容
* 硬要的話也可以在 Given 開頭的 step 實作 Then 概念的動作
## References
* [Cucumber 官方網站](https://cucumber.io/)
* [Cucumber: Guides (官方教學)](https://cucumber.io/docs/guides/)
* [第一章——自動化測試框架總結Cucumber - IT閱讀 - ITREAD01.COM](https://www.itread01.com/content/1544337666.html)
* [Cucumber-java入门基础篇- chengly0129的专栏- CSDN博客](https://blog.csdn.net/chengly0129/article/details/79197598)