框架
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.node.org.cn')
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.node.org.cn')
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
当您想要添加或扩展一些基本功能(WebdriverIO 框架选项)时,require
选项很有用。
类型: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.{optionName}="value"
格式来实现。
例如,如果您只想运行标记为 @smoke
的测试,可以使用以下命令:
# When you only want to run tests that hold the tag "@smoke"
npx wdio ./wdio.conf.js --cucumberOpts.tags="@smoke"
此命令将 cucumberOpts
中的 tags
选项设置为 @smoke
,确保仅执行带有此标签的测试。
回溯
显示错误的完整回溯。
类型:Boolean
默认值:true
requireModule
在加载任何支持文件之前加载模块。
类型:string[]
默认值:[]
示例
cucumberOpts: {
requireModule: ['@babel/register']
// or
requireModule: [
[
'@babel/register',
{
rootMode: 'upward',
ignore: ['node_modules']
}
]
]
}
failFast
在第一次失败时中止运行。
类型:boolean
默认值:false
name
仅执行名称与表达式匹配的场景(可重复)。
类型:RegExp[]
默认值:[]
require
在执行特性文件之前加载包含您的步骤定义的文件。您还可以为您的步骤定义指定一个通配符。
类型: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([condition])
其中 condition 是功能属性及其值的可选组合,当全部匹配时,会导致标记的场景或特性文件被跳过。当然,您可以向场景和特性文件添加多个标签,以在多种不同条件下跳过测试。
您还可以使用“@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/)
:匹配正则表达式的浏览器功能将被跳过(例如iexplorer
、internet explorer
、internet-explorer
等)。
导入步骤定义助手
为了使用步骤定义助手(如 Given
、When
或 Then
)或钩子,您应该从 @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
钩子中调用,这是调用它的最佳位置。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 生成,这是一个由 @serenity-js/serenity-bdd
模块下载和管理的 Java 程序。
要生成 Serenity BDD 报告,您的测试套件必须
- 下载 Serenity BDD CLI,通过调用
serenity-bdd update
,它会将 CLIjar
缓存到本地 - 生成中间 Serenity BDD
.json
报告,通过根据 配置说明 注册SerenityBDDReporter
- 当您想生成报告时调用 Serenity BDD CLI,通过调用
serenity-bdd run
所有 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.node.org.cn`),
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.node.org.cn')
await expect(browser)
.toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js | WebdriverIO')
})
})
要了解更多关于剧本模式的信息,请查看