# 一起玩 Cypress(2) - 導入BDD工具Cucumber ###### tags: `Test` `Cypress` ## 介紹 Behaviour-Driven Development (BDD)以翻譯來說就是**行為驅動開發**,依據[Cucumber](https://cucumber.io/docs/bdd/)的介紹,測試雖然是其中一個重要項目但更重要的是縮小團隊之間的差距,其中有三個主要流程 1. Discovery:從[User Story](https://medium.com/3pm-lab/3-use-cases-for-writing-effective-user-stories-cd42625fef53)取得一個即將到來的變更,並討論其具體的功能需求。 2. Formulation:將需求寫成可被自動化執行的流程。 3. Automation:使用程式碼實踐文件內的操作描述,使其可以被自動化測試。 > 以上的介紹來自於[Cucumber](https://cucumber.io/docs/bdd/),這邊整理成自己方便理解的文字 其BDD要導入專案進行可能還牽扯專案管理相關的範疇,有興趣的人可以在多深入了解,這邊主要會專注功能描述撰寫流程及測試。 ## 目錄 [TOC] # 一、前言 延續上一篇文章的需求,完成測試之後又接到不同的需求,主要想要產出Cucumber的測試報告,使AWS在測試報告上支援`Cucumber JSON (.json)`格式,因此這篇文章就因此而誕生了,不過目前這邊不會講到測試報告產生及AWS上面的整合,只會專注在單純再導入`Cucumber`這一區塊。 # 二、實作步驟 因為是延續這邊就不再講解如何建立,想知道的可以參考[一起玩 Cypress(1) - 初探及快速建立](/OttG8UPkQE6ZuMUHrTVWZg) ## 環境建立 這邊我們使用套件[cypress-cucumber-preprocessor](https://github.com/badeball/cypress-cucumber-preprocessor)來快速架構,輸入以下指令進行安裝 ```shell= npm install @badeball/cypress-cucumber-preprocessor ``` 安裝完成後`package.json`會出現安裝的套件和及版本 :::info :bulb: **提示**: Cypress有再持續更新,參考時記得確認版本 ::: ![](https://i.imgur.com/duz3EO1.png) ## 撰寫描述 這邊我們建立一個`google.feature`的描述檔 ```gherkin= # cypress/e2e/google.feature Feature: Google.com Scenario: visiting the google and then use search When I visit google.com And I type CypressTest in the box And I click the search button Then I should see a search result page ``` 其句法是`Gherkin`這邊我們來簡單說明一下吧! 1. Feature: 主要用來分類`Scenario`和描述其整體軟體特徵 2. Scenario: 具體的例子來說明此業務功能,底下的組則為每一個執行步驟 步驟類別為如下 1. Given: 描述`Scenario`初始的內容 2. When: 描述事件或是行為 3. Then: 描述預期結果 4. And、But:如果有連續動作可以用此單字陳述分類 > 詳細內容可以參考官網[Gherkin Reference](https://cucumber.io/docs/gherkin/reference/) ## 撰寫測試 這邊不難看出撰寫的邏輯,這邊會看到步驟及描述就是用來對應我們程式碼的方式 ```typescript= // cypress/e2e/google.ts import { When, Then, And } from "@badeball/cypress-cucumber-preprocessor"; When("I visit google.com", () => { cy.visit('https://google.com'); }); And("I type Cypress in the box", () => { cy.get('.gLFyf').type("CypressTest") }); And("I click the search button", () => { cy.get('.CqAVzb > center > .gNO89b').click() }); Then("I should see a search result page", () =>{ cy.url().should('include', '/search') }); ``` ## 環境設定 完整撰寫後測試腳本後目前尚未無法直接執,這邊有兩個問題需要處理 ### 1. `Cypress`測試UI找不到檔案 預設測試檔案為`cypress/e2e/**/*.cy.{js,jsx,ts,tsx}`因此在測試畫面不會顯示`*.feature`的檔案 ![](https://i.imgur.com/eZSPeXw.png) 這邊比較簡單處理只需要前往設定檔`cypress.config.js`在對應的測試設定檔上調整檔案格式即可 ```javascript= // cypress.config.js // ... e2e: { specPattern: "**/*.feature", // ...其它設定 } // ... ``` 回到測試UI就可以看到檔案了 ![](https://i.imgur.com/e1OsjMF.png) 不過此時很開心的點進去會得到第二個錯誤畫面,其問題就是第二點描述的 ![](https://i.imgur.com/cV03BQV.png) ### 2. 程式不知道怎麼運行`*.feature` 這邊就要使用`Webpack`來幫我們做些處理,步驟比較多不過跟著我的節奏往下走就會了 首先安裝[@cypress/webpack-preprocessor](https://github.com/cypress-io/cypress/tree/master/npm/webpack-preprocessor)插件 ```shell= npm install --save-dev @cypress/webpack-preprocessor ``` :::info :bulb: 因為套件需要相依以下套件 * @babel/core * @babel/preset-env * babel-loader * webpack 如果尚未安裝改成以下指令 ```shell= npm install --save-dev @babel/core @babel/preset-env babel-loader webpack ``` ::: 安裝完成後接下來調整設定檔`cypress.config.js`加入前處理的流程,這邊直接附上完整代碼 ```javascript= const { defineConfig } = require("cypress"); const webpack = require('@cypress/webpack-preprocessor') module.exports = defineConfig({ e2e: { specPattern: "**/*.feature", setupNodeEvents(on, config) { const options = { webpackOptions: { resolve: { extensions: [".ts", ".js"], }, module: { rules: [ { test: /\.feature$/, use: [ { loader: "@badeball/cypress-cucumber-preprocessor/webpack", options: config, }, ], }, ], }, }, }; on("file:preprocessor", webpack(options)); return config; }, }, }); ``` 之後就可以透過UI進行測試流程了,結果如下圖可以發現左側結構變成我們撰寫的描述名稱,這樣不僅可以測試也可以很明確的知道哪一個行為開始出錯 ![](https://i.imgur.com/qO2Ccyz.png) 最後在附上檔案結構提供參考 ![](https://i.imgur.com/ylSAMxg.png) # 結論 Cucumber的加入如果單單專注在測試上面或許不是絕對必要的,因為前一篇[一起玩 Cypress(1) - 初探及快速建立](/OttG8UPkQE6ZuMUHrTVWZg)跟著實作後其實已經可以執行相關測試作業,Cucumber的導入個人感覺比較像是專案管理上的插件,管理人員透過撰寫描述文件可以清楚定義功能的每一步驟,後續開發人員可針對這些步驟撰寫對應的測試代碼,縮小雙方對於功能上的認知差異又可以變成日後的測試準則。 <br/> --- 相關參考來源: [BDD/TDD差別是什麼? 手把手用 Cucumber 實作示範BDD](https://tw.alphacamp.co/blog/bdd-tdd-cucumber-behaviour-driven-development) [Cucumber 入門筆記 (BDD自動化測試框架)](https://hackmd.io/@onejar99/BJ9LkkBNH#BDD) <style> code > span{ color: red;} </style>