隨著時間越長,專案總會越寫越多功能,可是如果每次重構後都要人工測試,會花費很多不必要的時間。所以為了往後能安心的重構程式,我想要一個可以方便 debug 且使用簡易的 UI Testing Framework。參考了許多架構後,決定要使用 cypress + cucumber 來寫測試。

Cypress 的好處是對於開發者非常友善,開發時在 chrome 瀏覽器模擬,且有變更都會自動觸發 reload,大大減少每次重跑的繁瑣動作,且每個步驟的紀錄都會視覺化的呈現在左方,Debug 時還可隨時搭配 chrome dev tool,真的是開發者的救星呀~如果要搭配 CI 的話,他也有 headless 模式啟用 electron 來跑模擬,出來的 log 也是非常漂亮還會順便錄影!

Cucumber 的好處是他可以寫可讀性高的測試情境,讀寫上很直覺,搭配不同 tag 的功能,可以把測試情境分類的很清楚。

接著我們就來介紹怎麼結合 cypress 和 cucumber 吧~

安裝 cypress + cucumber

專案內安裝 cypress

1
npm install cypress --save-dev

package.json 加上啟動 cpress 指令並執行 npm run cypress:open

1
2
3
4
5
{
"scripts": {
"cypress:open": "cypress open"
}
}

若啟動成功會自動建立測試情境,確定安裝完成後,可刪掉範例。

npm run cypress:open

關掉 cypress 視窗,接下來我們安裝 cucumber plugin

1
npm install --save-dev cypress-cucumber-preprocessor

cypress/plugins/index.js 設置 plugin

1
2
3
4
5
const cucumber = require('cypress-cucumber-preprocessor').default

module.exports = (on, config) => {
on('file:preprocessor', cucumber())
}

cypress.json 設置測試檔案位置

1
2
3
{
"testFiles": "**/*.feature"
}

package.json 設置 cucumber 的情境預設非 global,這樣可以區分是否要用 global 的情境。

1
2
3
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
},

把原本 cypress/integration, cypress/fixtures 資料夾的檔案都刪除,就可以開始寫一個測試囉~

寫一個測試

新增 cypress/integration/Google.feature

1
2
3
4
5
6
7
8
# language: zh-TW
功能: Google
* 前往 Google 首頁

@Google
場景: 前往 Google 首頁
假設 前往 Google 網址
那麼 看到標題包含 "Google"

@Google 這個 tag 是讓你能將測試做分類,這樣之後要跑測試的時候,可以指定執行特定類別。

新增 cypress/integration/Google/google.js

1
2
3
4
5
6
7
import { Given } from "cypress-cucumber-preprocessor/steps";

const url = 'https://google.com'

Given('前往 Google 網址', () => {
cy.visit(url)
})

若是放在自訂的資料夾內,則情境不會被共用,下面示範將看到標題這個結果放在 global 的情況。

新增 cypress/integration/common/i_see_string_in_the_title.js

1
2
3
4
5
import { Then } from "cypress-cucumber-preprocessor/steps";

Then(`看到標題包含 {string}`, (title) => {
cy.title().should('include', title)
})

這樣我們就放好 global 的情境囉~其他情境若是要共用的話就可以不用再寫一次。

測試~跑起來吧!

因為剛剛有使用 tag 的功能,所以我們可以把 npm script 改成指定執行特定標籤,package.json 修改如下。

1
2
3
"scripts": {
"cypress:open": "cypress open -e TAGS=@Google"
},

再次執行 npm run cypress:open。跳出 cypress 視窗後,點選 Google.feature 開始測試,成功就會出現下面的畫面囉~

npm run cypress:open

今天的練習放在 Github,下回見~

Reference