框架
WebdriverIO 執行器內建支援 Mocha、Jasmine 和 Cucumber.js。您也可以將其與第三方開放原始碼框架整合,例如 Serenity/JS。
若要將 WebdriverIO 與測試框架整合,您需要一個可在 NPM 上取得的轉接器套件。請注意,轉接器套件必須安裝在與 WebdriverIO 相同的目錄中。因此,如果您是全域安裝 WebdriverIO,請務必也全域安裝轉接器套件。
將 WebdriverIO 與測試框架整合後,您就可以在您的規格檔或步驟定義中使用全域 browser
變數來存取 WebDriver 執行個體。請注意,WebdriverIO 也會負責執行個體化和結束 Selenium 工作階段,因此您不必自己執行。
使用 Mocha
首先,從 NPM 安裝轉接器套件
- npm
- Yarn
- pnpm
npm install @wdio/mocha-framework --save-dev
yarn add @wdio/mocha-framework --dev
pnpm add @wdio/mocha-framework --save-dev
預設情況下,WebdriverIO 提供一個內建的斷言程式庫,您可以立即開始使用
describe('my awesome website', () => {
it('should do some assertions', async () => {
await browser.url('https://webdriverio.dev.org.tw')
await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO')
})
})
WebdriverIO 支援 Mocha 的 BDD
(預設)、TDD
和 QUnit
介面。
如果您喜歡以 TDD 樣式撰寫規格,請將組態中 mochaOpts
屬性的 ui
設定為 tdd
。現在,您的測試檔案應如下所示撰寫
suite('my awesome website', () => {
test('should do some assertions', async () => {
await browser.url('https://webdriverio.dev.org.tw')
await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO')
})
})
如果您想要定義其他 Mocha 特定的設定,可以使用組態檔中的 mochaOpts
鍵來執行。所有選項的清單都可以在 Mocha 專案網站上找到。
注意: WebdriverIO 不支援在 Mocha 中已棄用的 done
回呼用法
it('should test something', (done) => {
done() // throws "done is not a function"
})
Mocha 選項
下列選項可以在您的 wdio.conf.js
中套用,以設定您的 Mocha 環境。注意:並非所有選項都受支援,例如,套用 parallel
選項會導致錯誤,因為 WDIO 測試執行器有其自己的平行執行測試方式。但是,下列選項受支援
require
當您想要新增或擴充某些基本功能時,require
選項會很有用 (WebdriverIO 框架選項)。
類型:string|string[]
預設:[]
compilers
使用指定的模組來編譯檔案。編譯器將會在 require 之前包含 (WebdriverIO 框架選項)。
類型:string[]
預設:[]
allowUncaught
傳播未捕捉的錯誤。
類型:boolean
預設:false
bail
在第一個測試失敗後中止。
類型:boolean
預設:false
checkLeaks
檢查是否有全域變數洩漏。
類型:boolean
預設:false
delay
延遲根套件執行。
類型:boolean
預設:false
fgrep
測試篩選條件的指定字串。
類型:string
預設:null
forbidOnly
標記為 only
的測試會讓套件失敗。
類型:boolean
預設:false
forbidPending
擱置的測試會讓套件失敗。
類型:boolean
預設:false
fullTrace
失敗時的完整堆疊追蹤。
類型:boolean
預設:false
global
在全域範圍中預期的變數。
類型:string[]
預設:[]
grep
測試篩選條件的指定正規表示式。
類型:RegExp|string
預設:null
invert
反轉測試篩選條件比對。
類型:boolean
預設:false
retries
重試失敗測試的次數。
類型:number
預設:0
timeout
逾時臨界值 (以毫秒為單位)。
類型:number
預設:30000
使用 Jasmine
首先,從 NPM 安裝轉接器套件
- npm
- Yarn
- pnpm
npm install @wdio/jasmine-framework --save-dev
yarn add @wdio/jasmine-framework --dev
pnpm add @wdio/jasmine-framework --save-dev
然後,您可以透過在組態中設定 jasmineOpts
屬性來設定您的 Jasmine 環境。所有選項的清單都可以在 Jasmine 專案網站上找到。
Jasmine 選項
下列選項可以在您的 wdio.conf.js
中套用,以使用 jasmineOpts
屬性來設定您的 Jasmine 環境。如需這些組態選項的詳細資訊,請查看 Jasmine 文件。
defaultTimeoutInterval
Jasmine 作業的預設逾時間隔。
類型:number
預設:60000
helpers
相對於 spec_dir 的檔案路徑 (和全域模式) 陣列,在 jasmine 規格之前包含。
類型:string[]
預設:[]
requires
當您想要新增或擴充某些基本功能時,requires
選項會很有用。
類型:string[]
預設:[]
random
是否要隨機化規格執行順序。
類型:boolean
預設:true
seed
用作隨機化基礎的種子。Null 會導致種子在執行開始時隨機決定。
類型:Function
預設:null
failSpecWithNoExpectations
如果規格未執行任何預期,是否讓規格失敗。依預設,未執行任何預期的規格會報告為通過。將此設定為 true 會將此類規格報告為失敗。
類型:boolean
預設:false
oneFailurePerSpec
是否要讓規格只發生一個預期失敗。
類型:boolean
預設:false
specFilter
用於篩選規格的函數。
類型:Function
預設:(spec) => true
grep
只執行符合此字串或正規表示式的測試。(僅適用於未設定自訂 specFilter
函數的情況)
類型:string|Regexp
預設:null
invertGrep
如果為 true,它會反轉符合的測試,並且只執行與 grep
中使用的表示式不符的測試。(僅適用於未設定自訂 specFilter
函數的情況)
類型:boolean
預設:false
使用 Cucumber
首先,從 NPM 安裝轉接器套件
- npm
- Yarn
- pnpm
npm install @wdio/cucumber-framework --save-dev
yarn add @wdio/cucumber-framework --dev
pnpm add @wdio/cucumber-framework --save-dev
如果您想要使用 Cucumber,請將 framework
屬性設定為 cucumber
,方法是將 framework: 'cucumber'
新增至組態檔。
Cucumber 的選項可以使用 cucumberOpts
在組態檔中提供。請在此處查看選項的完整清單這裡。
若要快速開始使用 Cucumber,請查看我們的 cucumber-boilerplate
專案,其中包含您開始使用所需的所有步驟定義,而且您會立即開始撰寫功能檔案。
Cucumber 選項
您可以在 wdio.conf.js
中使用 cucumberOpts
屬性來設定您的 Cucumber 環境,以下是一些可用的選項:
cucumberOpts
,例如用於篩選測試的自訂 tags
,可以透過命令列指定。方法是使用 cucumberOpts.{選項名稱}="值"
的格式。
例如,如果您只想執行標記為 @smoke
的測試,您可以使用以下命令
# When you only want to run tests that hold the tag "@smoke"
npx wdio ./wdio.conf.js --cucumberOpts.tags="@smoke"
此命令會將 cucumberOpts
中的 tags
選項設定為 @smoke
,確保只會執行具有此標籤的測試。
backtrace
顯示錯誤的完整回溯追蹤。
類型:Boolean
預設:true
requireModule
在需要任何支援檔案之前,先要求模組。
類型:string[]
預設:[]
範例
cucumberOpts: {
requireModule: ['@babel/register']
// or
requireModule: [
[
'@babel/register',
{
rootMode: 'upward',
ignore: ['node_modules']
}
]
]
}
failFast
在第一次失敗時中止執行。
類型:boolean
預設:false
name
只執行名稱與運算式相符的場景(可重複)。
類型:RegExp[]
預設:[]
require
在執行功能之前,先要求包含您的步驟定義的檔案。您也可以指定一個 glob 來指向您的步驟定義。
類型:string[]
預設值:[]
範例
cucumberOpts: {
require: [path.join(__dirname, 'step-definitions', 'my-steps.js')]
}
import
您的支援程式碼所在的 ESM 路徑。
類型:String[]
預設值:[]
範例
cucumberOpts: {
import: [path.join(__dirname, 'step-definitions', 'my-steps.js')]
}
strict
如果有任何未定義或待處理的步驟,則失敗。
類型:boolean
預設:false
tags
只執行標籤與運算式相符的功能或場景。請參閱 Cucumber 文件 以取得更多詳細資訊。
類型:String
預設值:``
timeout
步驟定義的逾時時間(毫秒)。
類型:Number
預設:30000
retry
指定重試失敗測試案例的次數。
類型:Number
預設:0
retryTagFilter
只重試標籤與運算式相符的功能或場景(可重複)。此選項需要指定 '--retry'。
類型:RegExp
language
您的功能檔案的預設語言
類型:String
預設值:en
order
以已定義/隨機的順序執行測試
類型:String
預設值:defined
format
要使用的格式化程式的名稱和輸出檔案路徑。WebdriverIO 主要只支援將輸出寫入檔案的 格式化程式。
類型:string[]
formatOptions
要提供給格式化程式的選項
類型:object
tagsInTitle
將 cucumber 標籤新增至功能或場景名稱
類型:Boolean
預設:false
請注意,這是一個 @wdio/cucumber-framework 特定的選項,而不是 cucumber-js 本身所識別的選項
ignoreUndefinedDefinitions
將未定義的定義視為警告。
類型:Boolean
預設:false
請注意,這是一個 @wdio/cucumber-framework 特定的選項,而不是 cucumber-js 本身所識別的選項
failAmbiguousDefinitions
將含糊不清的定義視為錯誤。
類型:Boolean
預設:false
請注意,這是一個 @wdio/cucumber-framework 特定的選項,而不是 cucumber-js 本身所識別的選項
tagExpression
只執行標籤與運算式相符的功能或場景。請參閱 Cucumber 文件 以取得更多詳細資訊。
類型:String
預設值:``
請注意,此選項未來將被棄用。請改用 tags
設定屬性
profile
指定要使用的設定檔。
類型:string[]
預設:[]
請注意,設定檔中僅支援特定值(worldParameters、name、retryTagFilter),因為 cucumberOpts
優先。此外,當使用設定檔時,請確保 cucumberOpts
中未宣告提及的值。
在 cucumber 中略過測試
請注意,如果您想使用 cucumberOpts
中可用的常規 cucumber 測試篩選功能來略過測試,您將會對功能中設定的所有瀏覽器和裝置執行此操作。為了能夠僅針對特定功能組合略過場景,而不需要在沒有必要的情況下啟動會話,webdriverio 為 cucumber 提供了以下特定標籤語法
@skip([條件])
其中條件是功能屬性及其值的可選組合,當全部符合時,會導致略過標記的場景或功能。當然,您可以在場景和功能中新增多個標籤,以在幾個不同的條件下略過測試。
您也可以使用 '@skip' 註解來略過測試,而無需變更 `tagExpression'。在這種情況下,略過的測試將會顯示在測試報告中。
以下是一些此語法的範例
@skip
或@skip()
:將永遠略過標記的項目@skip(browserName="chrome")
:測試將不會針對 chrome 瀏覽器執行。@skip(browserName="firefox";platformName="linux")
:將會略過在 linux 上的 firefox 執行中的測試。@skip(browserName=["chrome","firefox"])
:標記的項目將會針對 chrome 和 firefox 瀏覽器略過。@skip(browserName=/i.*explorer/)
:將會略過與 regexp 相符的瀏覽器功能(例如iexplorer
、internet explorer
、internet-explorer
等)。
匯入步驟定義協助程式
為了使用步驟定義協助程式(例如 Given
、When
或 Then
)或 hook,您應該從 @cucumber/cucumber
匯入它們,例如:
import { Given, When, Then } from '@cucumber/cucumber'
現在,如果您已經將 Cucumber 用於其他與 WebdriverIO 無關的測試類型,而您為這些測試類型使用了特定版本,則您需要從 WebdriverIO Cucumber 套件匯入 e2e 測試中的這些協助程式,例如:
import { Given, When, Then } from '@wdio/cucumber-framework'
這可確保您在 WebdriverIO 框架內使用正確的協助程式,並允許您為其他類型的測試使用獨立的 Cucumber 版本。
發佈報告
Cucumber 提供了一項功能,可將您的測試執行報告發佈到 https://reports.cucumber.io/
,這可以透過在 cucumberOpts
中設定 publish
標記或設定 CUCUMBER_PUBLISH_TOKEN
環境變數來控制。但是,當您使用 WebdriverIO
進行測試執行時,此方法有一個限制。它會為每個功能檔案分別更新報告,因此難以檢視合併的報告。
為了克服此限制,我們在 @wdio/cucumber-framework
中引入了一個基於 Promise 的方法,稱為 publishCucumberReport
。此方法應在 onComplete
hook 中呼叫,這是呼叫它的最佳位置。publishCucumberReport
需要輸入儲存 cucumber 訊息報告的報告目錄。
您可以透過在 cucumberOpts
中設定 format
選項來產生 cucumber message
報告。強烈建議您在 cucumber message
格式選項中提供動態檔案名稱,以防止覆寫報告,並確保準確記錄每個測試執行。
在使用此功能之前,請確保設定以下環境變數
- CUCUMBER_PUBLISH_REPORT_URL:您要發佈 Cucumber 報告的 URL。如果未提供,則會使用預設 URL 'https://messages.cucumber.io/api/reports'。
- CUCUMBER_PUBLISH_REPORT_TOKEN:發佈報告所需的授權權杖。如果未設定此權杖,則該功能將會結束,而不會發佈報告。
以下是實作所需的設定和程式碼範例
import { v4 as uuidv4 } from 'uuid'
import { publishCucumberReport } from '@wdio/cucumber-framework';
export const config = {
// ... Other Configuration Options
cucumberOpts: {
// ... Cucumber Options Configuration
format: [
['message', `./reports/${uuidv4()}.ndjson`],
['json', './reports/test-report.json']
]
},
async onComplete() {
await publishCucumberReport('./reports');
}
}
請注意,./reports/
是儲存 cucumber message
報告的目錄。
使用 Serenity/JS
Serenity/JS 是一個開放原始碼框架,旨在使複雜軟體系統的接受和迴歸測試更快、更具協作性且更易於擴展。
對於 WebdriverIO 測試套件,Serenity/JS 提供
- 增強的報告 - 您可以使用 Serenity/JS 作為任何內建 WebdriverIO 框架的替代品,以產生深入的測試執行報告和專案的動態文件。
- 劇本模式 API - 為了讓您的測試程式碼在不同專案和團隊之間具有可攜性和可重複使用性,Serenity/JS 提供了一個可選的 抽象層,建立在原生 WebdriverIO API 之上。
- 整合函式庫 - 對於遵循劇本模式的測試套件,Serenity/JS 還提供了可選的整合函式庫,幫助您編寫 API 測試、管理本機伺服器、執行斷言等等!
安裝 Serenity/JS
要將 Serenity/JS 新增到現有的 WebdriverIO 專案,請從 NPM 安裝以下 Serenity/JS 模組
- npm
- Yarn
- pnpm
npm install @serenity-js/{core,web,webdriverio,assertions,console-reporter,serenity-bdd} --save-dev
yarn add @serenity-js/{core,web,webdriverio,assertions,console-reporter,serenity-bdd} --dev
pnpm add @serenity-js/{core,web,webdriverio,assertions,console-reporter,serenity-bdd} --save-dev
進一步了解 Serenity/JS 模組
@serenity-js/core
@serenity-js/web
@serenity-js/webdriverio
@serenity-js/assertions
@serenity-js/console-reporter
@serenity-js/serenity-bdd
設定 Serenity/JS
要啟用與 Serenity/JS 的整合,請依照以下方式設定 WebdriverIO
- TypeScript
- JavaScript
import { WebdriverIOConfig } from '@serenity-js/webdriverio';
export const config: WebdriverIOConfig = {
// Tell WebdriverIO to use Serenity/JS framework
framework: '@serenity-js/webdriverio',
// Serenity/JS configuration
serenity: {
// Configure Serenity/JS to use the appropriate adapter for your test runner
runner: 'cucumber',
// runner: 'mocha',
// runner: 'jasmine',
// Register Serenity/JS reporting services, a.k.a. the "stage crew"
crew: [
// Optional, print test execution results to standard output
'@serenity-js/console-reporter',
// Optional, produce Serenity BDD reports and living documentation (HTML)
'@serenity-js/serenity-bdd',
[ '@serenity-js/core:ArtifactArchiver', { outputDirectory: 'target/site/serenity' } ],
// Optional, automatically capture screenshots upon interaction failure
[ '@serenity-js/web:Photographer', { strategy: 'TakePhotosOfFailures' } ],
]
},
// Configure your Cucumber runner
cucumberOpts: {
// see Cucumber configuration options below
},
// ... or Jasmine runner
jasmineOpts: {
// see Jasmine configuration options below
},
// ... or Mocha runner
mochaOpts: {
// see Mocha configuration options below
},
runner: 'local',
// Any other WebdriverIO configuration
};
export const config = {
// Tell WebdriverIO to use Serenity/JS framework
framework: '@serenity-js/webdriverio',
// Serenity/JS configuration
serenity: {
// Configure Serenity/JS to use the appropriate adapter for your test runner
runner: 'cucumber',
// runner: 'mocha',
// runner: 'jasmine',
// Register Serenity/JS reporting services, a.k.a. the "stage crew"
crew: [
'@serenity-js/console-reporter',
'@serenity-js/serenity-bdd',
[ '@serenity-js/core:ArtifactArchiver', { outputDirectory: 'target/site/serenity' } ],
[ '@serenity-js/web:Photographer', { strategy: 'TakePhotosOfFailures' } ],
]
},
// Configure your Cucumber runner
cucumberOpts: {
// see Cucumber configuration options below
},
// ... or Jasmine runner
jasmineOpts: {
// see Jasmine configuration options below
},
// ... or Mocha runner
mochaOpts: {
// see Mocha configuration options below
},
runner: 'local',
// Any other WebdriverIO configuration
};
進一步了解
產生 Serenity BDD 報告和即時文件
Serenity BDD 報告和即時文件由 Serenity BDD CLI 產生,這是一個 Java 程式,由 @serenity-js/serenity-bdd
模組下載和管理。
要產生 Serenity BDD 報告,您的測試套件必須
- 透過呼叫
serenity-bdd update
來下載 Serenity BDD CLI,它會在本地快取 CLIjar
- 透過依照設定說明註冊
SerenityBDDReporter
來產生中繼 Serenity BDD.json
報告 - 當您要產生報告時,呼叫
serenity-bdd run
來調用 Serenity BDD CLI
所有 Serenity/JS 專案範本使用的模式都依賴於使用
- 一個
postinstall
NPM 腳本來下載 Serenity BDD CLI npm-failsafe
來執行報告產生程序,即使測試套件本身失敗也一樣(這正是您最需要測試報告的時候...)。rimraf
作為一種便利的方法來移除先前執行遺留的任何測試報告
{
"scripts": {
"postinstall": "serenity-bdd update",
"clean": "rimraf target",
"test": "failsafe clean test:execute test:report",
"test:execute": "wdio wdio.conf.ts",
"test:report": "serenity-bdd run"
}
}
若要進一步了解 SerenityBDDReporter
,請參閱
使用 Serenity/JS 劇本模式 API
劇本模式是一種創新的、以使用者為中心的方法,用於編寫高品質的自動化接受測試。它引導您有效地使用抽象層,幫助您的測試情境捕捉您領域的業務術語,並鼓勵您的團隊養成良好的測試和軟體工程習慣。
預設情況下,當您註冊 @serenity-js/webdriverio
作為您的 WebdriverIO framework
時,Serenity/JS 會設定一個預設的 演員陣容,其中每個演員都可以
這應該足以幫助您開始將遵循劇本模式的測試情境引入到現有的測試套件,例如
import { actorCalled } from '@serenity-js/core'
import { Navigate, Page } from '@serenity-js/web'
import { Ensure, equals } from '@serenity-js/assertions'
describe('My awesome website', () => {
it('can have test scenarios that follow the Screenplay Pattern', async () => {
await actorCalled('Alice').attemptsTo(
Navigate.to(`https://webdriverio.dev.org.tw`),
Ensure.that(
Page.current().title(),
equals(`WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO`)
),
)
})
it('can have non-Screenplay scenarios too', async () => {
await browser.url('https://webdriverio.dev.org.tw')
await expect(browser)
.toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO')
})
})
若要進一步了解劇本模式,請查看