2022年1月31日 星期一

e2e 測試工具 Cypress 安裝及介紹


e2e測試(End-to-End testing)是模擬使用者的行為,實際打開瀏覽器操作頁面的測試方式,因此不限於vue, react的專案,e2e的測試可以反映出頁面在不同瀏覽器的執行情形。

Cypress便是其中一個常見工具,Cypress在安裝上簡單,語法採用 mocha 的句法、chai 的斷詞(expect, should, assert),撰寫的方式跟 unit test 相似。


安裝

進到想要測試的專案目錄內,使用 npm 安裝。(官網說明)

npm install cypress --save-dev

接著在目錄裡,建立先建立一個 cypress.json,內容放一個空物件,此時你可以直接執行下面的命令(官網說明):

npx cypress open

會發現多了一個 cypress/ 的資料夾,裡面有四個目錄:

  • integration: 主要的測試檔案
  • fixtures: 固定的資料
  • plugins: 主要有 on 定義全局的不同時間點的執行工作,以及 config 提供全局使用的參數,如常用的 env
  • support: 可提供自定義的指令、或引入擴充的指令,供撰寫測試檔案使用


Cypress.json 與環境變數(.env)

使用 cypress 都必須在專案的根目錄裡新增 cypress.json,如果直接放 {} 空物件,代表直接使用預設值。

下面是我的設定,從字面上不難理解設定的內容,第一個testFiles是測試的檔案名稱,接著各個目錄的路徑,video是 Boolean 決定是否錄製測試過程的影片,screenshotOnRunFailure也是 Boolean 是否在執行失敗時擷取畫面。

{
    "testFiles": "**/*.spec.js",
    "integrationFolder": "resources/cypress/integration",
    "componentFolder": "resources/cypress/components",
    "fixturesFolder": "resources/cypress/fixtures",
    "pluginsFile": "resources/cypress/plugins",
    "supportFile": "resources/cypress/support",
    "video": false,
    "screenshotOnRunFailure": false
}

除了cypress基本的設定,常常也需要讀取環境設定檔(.env),假設內容如下(官方說明):

APP_URL=https://chenuin.github.io/
USER_NAME=chenuin

plugins/index.js可以設定:

// plugins/index.js

require('dotenv').config();

module.exports = (on, config) => {
    config.baseUrl = process.env.APP_URL;

    config.env.USER_NAME = process.env.USER_NAME;

    return config;
}
測試檔案需要使用時,可以直接呼叫:
Cypress.config('baseUrl')
Cypress.env('USER_NAME')

打開GUI,點選上方的 Settings 可以看到設定的結果,上面的顏色可以區分目前的設定是讀取哪裡,像是 baseUrl 是紫色的 plugin,

因此,可以知道下面兩種寫法都可以達到相同的效果:

// plugins/index.js
config.baseUrl = process.env.APP_URL;


// cypress.json
{
    "baseUrl": "https://chenuin.github.io/"
}


執行

提供 GUI 介面操作

npx cypress open

無GUI,在 Terminal 上執行

npx cypress run


訪問頁面 visit

測試的第一步常常是先進入某一個頁面,通常專案內都在相同的Domain下,如果有設定 baseUrl,Cypress會直接將設定作為前綴,導到相應的頁面,在寫法上簡潔許多。

// https://chenuin.github.io/webpack/2021/08/08/webpack5-getting-started.html

cy.visit('/webpack/2021/08/08/webpack5-getting-started.html')

若未設定,需要傳入完整的路徑,或者cypress會嘗試在你的web server上找到對應位置的頁面。(官方說明)


intercept與fixtures的使用

使用 intercept 來監聽由頁面上請求(request)及回應(response),下面三者是相同的意思:

cy.intercept('/users/**')
cy.intercept('GET', '/users/**')
cy.intercept({
  method: 'GET',
  url: '/users/**',
})

你也可以為這個路由(route)新增別名(alias),除了方便辨識外,如果需要在request後執行的工作,可以使用下面的寫法:

cy.intercept('POST', '/users').as('createUser');

// once a request to create user responds, 'cy.wait' will resolve
cy.wait('@createUser')

GUI上可以看到這個 route 表格

執行此請求時會留下Log記錄,所有被監聽的路由會列在route表格,表格上可以看到所有route被呼叫的次數(表格最右側的數字),對應的別名(alias)是什麼。

上面 Stubbed 是代表回應(response)是否被取代了,這個是很好用的功能,例如:當我們將 users 這個請求的回應,取代為一個列表:

// requests to '/users' will be fulfilled
// with a body of list: ['John', 'Ben', 'Mary]

cy.intercept(
  '/users',
  ['John', 'Ben', 'Mary],
)

或者可以使用 fixture ,後面填寫 fixture/ 目錄裡的檔案名稱。

// requests to '/users' will be fulfilled
// with the contents of the "users.json" fixture

cy.intercept(
  '/users',
  { fixture: 'users.json' },
)
(官方說明)


ESLint設定

請在 .eslintrc.js 加上設定,不需要安裝任何套件:

module.exports = {
  extends: [
    'plugin:cypress/recommended',
  ],
};



沒有留言:

張貼留言