译文来自npm官网:https://www.npmjs.com/package/cypress-cucumber-preprocessor#cypress-configuration
使用Cypress测试时,cypress-cucumber-preprocessor 提供使用Feature文件。
你可以按照以下文档,或者你喜欢在实例上进行黑客攻击,你可以看一下: https://github.com/TheBrainFamily/cypress-cucumber-example
目录
- 开始
- 安装
- Cypress 配置
- 配置
- 如何管理测试
- 单个的Feature文件
- 多个Feature文件
- 测试步骤定义
- 创建测试步骤
- 可重复使用的测试步骤
- 如何写测试用例
- Cucumber的表达
- Given/When/Then 功能
- 自定义参数类型的解析
- Before和After钩子
- 背景部分
- 文件共享
- 智能标记
- 如何运行测试
- 运行标记的测试用例
- 输出
- 支持的编辑器
- Webstorm
- Intellij IDEA
- Visual Studio Code
开始
安装
使用下边的命令安装插件:
npm install --save-dev cypress-cucumber-preprocessor
Cypress 配置
添加下边代码在cypress/plugins/index.js
文件中:
const cucumber = require('cypress-cucumber-preprocessor').default
module.exports = (on, config) => {
on('file:preprocessor', cucumber())
}
在Cypress的配置文件cypress.json
中添加支持的Feature文件
{
"testFiles": "**/*.feature"
}
配置
确保使用cosmiconfig 去创建插件的配置,例如,将以下代码添加到package.json
文件中:
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
}
配置选择
选择 | 默认值 | 描述 |
---|---|---|
commonPath |
nonGlobalStepDefinitions = true,则路径为cypress/integration/common ;nonGlobalStepDefinitions = false,则路径为cypress/support/step_definitions
|
默认的路径文件中包含所有共有的测试步骤 |
nonGlobalStepDefinitions | false | 同上 |
step_definitions | cypress/support/step_definitions |
包含测试步骤的文件路径 |
如何管理测试
-
单个feature文件
在cypress/integration/
文件夹下创建一个新的feature文件,例如: cypress/integration/Google.feature
@facus 标记不是必须的,但是希望你注意到这个标记,在以后,使用这个标记会大大提高你的测试效率。
Feature: The Facebook
I want to open a social network page
@focus
Scenario: Opening a social network page
Given I open Google page
Then I see "google" in the title
-
多个feature文件
当用headless运行cypress测试时,测试执行速度慢,这个发生的原因是因为Cypress默认的会在每个feature文件之前重新打开浏览器。在运行测试之前,cypress-cucumber-preprocessor 提供了打包所有feature文件的选项,因此降低了测试执行的时间。
你可以利用这一点来创建feature文件,你可以选择在根目录cypress/integrations
下只有一个feature文件,或者是每一个目录下只有一个Feature文件。
或者是你也可以添加支持的feature文件在Cypress的配置文件cypress.json
中,如下所示:
{
"testFiles": "**/*.{feature,features}"
}
然后可以运行多个feature文件的测试,使用命令:
cypress run --spec **/*.features
-
测试步骤定义 (这是一个推荐的方法)
测试步骤的创建
.feature
文件将使用与.feature
文件同名的js文件中的步骤。如果要将包含步骤定义的javascript文件分解为不同的关注点,则可以使用其他名称。
为了更容易理解,所以假设feature文件在cypress/integration/Google.feature
,如上所示,预处理器将读取cypress/integration/Google/
里的所有文件,如cypress/integration/Google/google.js
(或者同一路径下的任何其他的 .js 文件)
import { Given } from "cypress-cucumber-preprocessor/steps";
const url = 'https://google.com'
Given('I open Google page', () => {
cy.visit(url)
})
这是一个很好的地方去放置before/beforeEach/after/afterEach 钩子相关的一些特定特性,This is incredibly hard to get right with pure cucumber.
可重复使用的测试步骤
我们也可以有一个方法去创建可重用的测试步骤,把他们放在 cypress/integration/common/
。例如:cypress/integration/common/i_see_string_in_the_title.js
import { Then } from "cypress-cucumber-preprocessor/steps";
Then(`I see {string} in the title`, (title) => {
cy.title().should('include', title)
})
这是一个很好的地方去放置全局的 before/beforeEach/after/afterEach 钩子。
如何写测试用例
-
Cucumber 的表达
当你使用Cucumber来描述你的feature文件,请使用下边文件作为参考: https://docs.cucumber.io/cucumber/cucumber-expressions/
-
Given/When/Then 功能
因为Given/When/Then是全局变量,请使用以下示例,确保编辑器可以直接导入他们。
/* global Given, When, Then */
-
定义参数类型的解析
感谢 @Oltodo, 现在我们可以使用自定义参数类型的解析。这里是示例, 以及使用的feature文件。
-
Before 和 After 钩子
cypress-cucumber-preprocessor 支持两种钩子,一种是Mocha的 before/beforeEach/after/afterEach
钩子,一种是 Cucumber的 Before
and After
钩子。
Cucumber钩子完全支持标记如cucumber js文件中描述的一样,所以他们可以基于场景标记进行有条件的选择。使用Mocha钩子,这是可能实现的。
Cucumber 的Before钩子会在Mocha的before和beforeEach钩子完成之后运行,Cucumber 的After钩子会在Mocha的afterEach和after执行之前运行。示例如下:
const {
Before,
After,
Given,
Then
} = require("cypress-cucumber-preprocessor/steps");
// this will get called before each scenario
Before(() => {
beforeCounter += 1;
beforeWithTagCounter = 0;
});
// this will only get called before scenarios tagged with @foo
Before({ tags: "@foo" }, () => {
beforeWithTagCounter += 1;
});
Given("My Step Definition", () => {
// ...test code here
})
注意: 为了避免与Mocha 的before和after钩子名字的混淆,Cucumber 的钩子不会导出到全局变量,所以他们需要显示导入,如上边的例子所示。
-
背景部分
在feature文件中添加背景部分可以在每一个测试之前运行这些步骤。例如,你有一个计数器,需要在每个测试之前重置,我们可以创建一个步骤去重置计数器。
let counter = 0;
Given("counter has been reset", () => {
counter = 0;
});
When("counter is incremented", () => {
counter += 1;
});
Then("counter equals {int}", value => {
expect(counter).to.equal(value);
});
Feature: Background Section
Background:
Given counter has been reset
Scenario: Basic example #1
When counter is incremented
Then counter equals 1
Scenario: Basic example #2
When counter is incremented
When counter is incremented
Then counter equals 2
-
文件共享
可以使用cy.as()
重命名,来实现文件在两个步骤文件之间的共享。更多的信息请查看: https://docs.cypress.io/api/commands/as.html, 例如:
Given('I go to the add new item page', () => {
cy.visit('/addItem');
});
When('I add a new item', () => {
cy.get('input[name="addNewItem"]').as('addNewItemInput');
cy.get('@addNewItemInput').type('My item');
cy.get('button[name="submitItem"]').click();
})
Then('I see new item added', () => {
cy.get('td:contains("My item")');
});
Then('I can add another item', () => {
expect(cy.get('@addNewItemInput').should('be.empty');
});
-
智能标记
开始的测试时没有任何的标记。之后可以在你想要等开发修复完问题集中关注的测试用例前加上标记@focus 。例如:
Feature: Smart Tagging
Scenario: This scenario should not run if @focus is on another scenario
Then this unfocused scenario should not run
@focus
Scenario: This scenario is focused and should run
Then this focused scenario should run
@this-tag-affects-nothing
Scenario: This scenario should also not run
Then this unfocused scenario should not run
@focus
Scenario: This scenario is also focused and also should run
Then this focused scenario should run
如何运行测试
以通常的方式去启动Cypress,例如:
./node_modules/.bin/cypress open
点击列表中的.feature
文件,你会看到神奇地事情发生!
-
运行有标记的测试
你可以通过标记来选择哪些测试用例需要去运行。请记住,我们使用的是最新的语法,如:'not @foo and (@bar or @zap)'
。为了使用标记初始化测试用例,你需要运行cypress并且传递标记的环境变量。例如:
./node_modules/.bin/cypress-tags run -e TAGS='not @foo and (@bar or @zap)'
请注意:我们使用自己的Cypress-tags 来提高速度,更多详细的示例请: https://github.com/TheBrainFamily/cypress-cucumber-example。
-
限定一个feature文件的子集
你可以使用全局表达去选择哪一个feature文件应该被包含。例如:
./node_modules/.bin/cypress-tags run -e GLOB='cypress/integration/**/*.feature'
-
输出
cypress-cucumber-preprocessor可以在运行feature文件的时候生成一个 cucumber.json
文件输出。这是分开的,除了在cypress中配置Mocha报告。
这些文件可以和其他任何一个cucumber报告生成器一起使用,下边两个都很好: https://github.com/jenkinsci/cucumber-reports-plugin 和 https://github.com/wswebcreation/multiple-cucumber-html-reporter
默认的输出,会写在文件cypress/cucumber-json
中,而且一个Feature文件生成一个。这个习惯是可以配置的,使用 cosmiconfig 去为插件创建一个配置,to create a configuration for the plugin, 请参考上边的步骤定义讨论,并且将下边的内容添加到package.json
文件中,更改默认值。
"cypress-cucumber-preprocessor": {
"cucumberJson": {
"generate": true,
"outputFolder": "cypress/cucumber-json",
"filePrefix": "",
"fileSuffix": ".cucumber"
}
}
Cucumber 的.json 配置
选项 | 默认值 | 描述 |
---|---|---|
outputFolder | cypress/cucumber-json |
输出文件的地址 |
filePrefix |
'' (no prefix)
|
每一个feature文件根据名字生成一个单独的json文件. 如果指定,则每一个生成的json文件将以此作为前缀 |
fileSuffix | .cucumber |
为每一个生成的文件添加后缀名 |
generate | false |
标记生成 cucumber.json 文件还是不生成 |
支持的编辑器
-
WebStorm
如果你想要使用WebStorm解析你的步骤,请使用大写:Given/When/Then
方法名来代替小写 given/when/then。 注意:只有WebStorm 2019.2或者更新的版本才能使用解析在step_definitions文件之外的步骤。
-
Intellij IDEA
Intellij IDEA 社区版不支持 cucumber 使用 javascript,但是终极版可以提供和WebStorm同样的级别的步骤解析的支持。
为了确保能够解决
为了能够在Intellij IDEA 终极版编辑器中解析cucumber步骤,你需要下载和授权JetBrains Cucumber JS plugin。在 WebStorm,这个插件已经绑定在授权版本中。
-
Visual Studio Code
使用VSCode解析cucumber步骤,需要下载扩展插件:Cucumber (Gherkin) Full Support。而且你需要告诉扩展工具你的Feature和测试步骤文件的路径, 像这里描述的。
注意,和WebStorm不同, WebStorm可以正确的匹配步骤的多个实现,但是VSCode当前只能解析第一个他在对应路径下匹配的实现。
TypeScript支持
-
有 Webpack
可以使用Webpack加载程序处理的功能文件(TypeScript 支持)。想知道如何做,请看这里: cypress-cucumber-webpack-typescript-example
-
没有 Webpack
如果你想使用TypeScript,添加下边的代码在plugins/index.js
文件中,而且安装tsify, npm install tsify
。我默认你已经安装了TypeScript。
const cucumber = require("cypress-cucumber-preprocessor").default;
const browserify = require("@cypress/browserify-preprocessor");
module.exports = (on) => {
const options = browserify.defaultOptions;
options.browserifyOptions.plugin.unshift(['tsify']);
// Or, if you need a custom tsconfig.json for your test files:
// options.browserifyOptions.plugin.unshift(['tsify', {project: 'path/to/other/tsconfig.json'}]);
on("file:preprocessor", cucumber(options));
};
之后在你的.ts文件中需要确保要么要求/导入步骤定义的函数,或者声明他们为全局的。
declare const Given, When, Then;
// OR
import { Given, Then, When } from "cypress-cucumber-preprocessor/steps";
在这里可以查看一下示例: https://github.com/TheBrainFamily/cypress-cucumber-typescript-example/