譯文來(lái)自npm官網(wǎng):https://www.npmjs.com/package/cypress-cucumber-preprocessor#cypress-configuration
使用Cypress測(cè)試時(shí),cypress-cucumber-preprocessor 提供使用Feature文件。
你可以按照以下文檔,或者你喜歡在實(shí)例上進(jìn)行黑客攻擊,你可以看一下: https://github.com/TheBrainFamily/cypress-cucumber-example
目錄
- 開(kāi)始
- 安裝
- Cypress 配置
- 配置
- 如何管理測(cè)試
- 單個(gè)的Feature文件
- 多個(gè)Feature文件
- 測(cè)試步驟定義
- 創(chuàng)建測(cè)試步驟
- 可重復(fù)使用的測(cè)試步驟
- 如何寫(xiě)測(cè)試用例
- Cucumber的表達(dá)
- Given/When/Then 功能
- 自定義參數(shù)類(lèi)型的解析
- Before和After鉤子
- 背景部分
- 文件共享
- 智能標(biāo)記
- 如何運(yùn)行測(cè)試
- 運(yùn)行標(biāo)記的測(cè)試用例
- 輸出
- 支持的編輯器
- Webstorm
- Intellij IDEA
- Visual Studio Code
開(kāi)始
安裝
使用下邊的命令安裝插件:
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 去創(chuàng)建插件的配置,例如,將以下代碼添加到package.json文件中:
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": true
}
配置選擇
| 選擇 | 默認(rèn)值 | 描述 |
|---|---|---|
| commonPath |
nonGlobalStepDefinitions = true,則路徑為cypress/integration/common;nonGlobalStepDefinitions = false,則路徑為cypress/support/step_definitions
|
默認(rèn)的路徑文件中包含所有共有的測(cè)試步驟 |
| nonGlobalStepDefinitions | false | 同上 |
| step_definitions | cypress/support/step_definitions |
包含測(cè)試步驟的文件路徑 |
如何管理測(cè)試
-
單個(gè)feature文件
在cypress/integration/文件夾下創(chuàng)建一個(gè)新的feature文件,例如: cypress/integration/Google.feature
@facus 標(biāo)記不是必須的,但是希望你注意到這個(gè)標(biāo)記,在以后,使用這個(gè)標(biāo)記會(huì)大大提高你的測(cè)試效率。
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
-
多個(gè)feature文件
當(dāng)用headless運(yùn)行cypress測(cè)試時(shí),測(cè)試執(zhí)行速度慢,這個(gè)發(fā)生的原因是因?yàn)镃ypress默認(rèn)的會(huì)在每個(gè)feature文件之前重新打開(kāi)瀏覽器。在運(yùn)行測(cè)試之前,cypress-cucumber-preprocessor 提供了打包所有feature文件的選項(xiàng),因此降低了測(cè)試執(zhí)行的時(shí)間。
你可以利用這一點(diǎn)來(lái)創(chuàng)建feature文件,你可以選擇在根目錄cypress/integrations下只有一個(gè)feature文件,或者是每一個(gè)目錄下只有一個(gè)Feature文件。
或者是你也可以添加支持的feature文件在Cypress的配置文件cypress.json中,如下所示:
{
"testFiles": "**/*.{feature,features}"
}
然后可以運(yùn)行多個(gè)feature文件的測(cè)試,使用命令:
cypress run --spec **/*.features
-
測(cè)試步驟定義 (這是一個(gè)推薦的方法)
測(cè)試步驟的創(chuàng)建
.feature文件將使用與.feature文件同名的js文件中的步驟。如果要將包含步驟定義的javascript文件分解為不同的關(guān)注點(diǎn),則可以使用其他名稱(chēng)。
為了更容易理解,所以假設(shè)feature文件在cypress/integration/Google.feature,如上所示,預(yù)處理器將讀取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)
})
這是一個(gè)很好的地方去放置before/beforeEach/after/afterEach 鉤子相關(guān)的一些特定特性,This is incredibly hard to get right with pure cucumber.
可重復(fù)使用的測(cè)試步驟
我們也可以有一個(gè)方法去創(chuàng)建可重用的測(cè)試步驟,把他們放在 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)
})
這是一個(gè)很好的地方去放置全局的 before/beforeEach/after/afterEach 鉤子。
如何寫(xiě)測(cè)試用例
-
Cucumber 的表達(dá)
當(dāng)你使用Cucumber來(lái)描述你的feature文件,請(qǐng)使用下邊文件作為參考: https://docs.cucumber.io/cucumber/cucumber-expressions/
-
Given/When/Then 功能
因?yàn)镚iven/When/Then是全局變量,請(qǐng)使用以下示例,確保編輯器可以直接導(dǎo)入他們。
/* global Given, When, Then */
-
定義參數(shù)類(lèi)型的解析
感謝 @Oltodo, 現(xiàn)在我們可以使用自定義參數(shù)類(lèi)型的解析。這里是示例, 以及使用的feature文件。
-
Before 和 After 鉤子
cypress-cucumber-preprocessor 支持兩種鉤子,一種是Mocha的 before/beforeEach/after/afterEach 鉤子,一種是 Cucumber的 Before and After 鉤子。
Cucumber鉤子完全支持標(biāo)記如cucumber js文件中描述的一樣,所以他們可以基于場(chǎng)景標(biāo)記進(jìn)行有條件的選擇。使用Mocha鉤子,這是可能實(shí)現(xiàn)的。
Cucumber 的Before鉤子會(huì)在Mocha的before和beforeEach鉤子完成之后運(yùn)行,Cucumber 的After鉤子會(huì)在Mocha的afterEach和after執(zhí)行之前運(yùn)行。示例如下:
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 的鉤子不會(huì)導(dǎo)出到全局變量,所以他們需要顯示導(dǎo)入,如上邊的例子所示。
-
背景部分
在feature文件中添加背景部分可以在每一個(gè)測(cè)試之前運(yùn)行這些步驟。例如,你有一個(gè)計(jì)數(shù)器,需要在每個(gè)測(cè)試之前重置,我們可以創(chuàng)建一個(gè)步驟去重置計(jì)數(shù)器。
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()重命名,來(lái)實(shí)現(xiàn)文件在兩個(gè)步驟文件之間的共享。更多的信息請(qǐng)查看: 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');
});
-
智能標(biāo)記
開(kāi)始的測(cè)試時(shí)沒(méi)有任何的標(biāo)記。之后可以在你想要等開(kāi)發(fā)修復(fù)完問(wèn)題集中關(guān)注的測(cè)試用例前加上標(biāo)記@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
如何運(yùn)行測(cè)試
以通常的方式去啟動(dòng)Cypress,例如:
./node_modules/.bin/cypress open
點(diǎn)擊列表中的.feature文件,你會(huì)看到神奇地事情發(fā)生!
-
運(yùn)行有標(biāo)記的測(cè)試
你可以通過(guò)標(biāo)記來(lái)選擇哪些測(cè)試用例需要去運(yùn)行。請(qǐng)記住,我們使用的是最新的語(yǔ)法,如:'not @foo and (@bar or @zap)'。為了使用標(biāo)記初始化測(cè)試用例,你需要運(yùn)行cypress并且傳遞標(biāo)記的環(huán)境變量。例如:
./node_modules/.bin/cypress-tags run -e TAGS='not @foo and (@bar or @zap)'
請(qǐng)注意:我們使用自己的Cypress-tags 來(lái)提高速度,更多詳細(xì)的示例請(qǐng): https://github.com/TheBrainFamily/cypress-cucumber-example。
-
限定一個(gè)feature文件的子集
你可以使用全局表達(dá)去選擇哪一個(gè)feature文件應(yīng)該被包含。例如:
./node_modules/.bin/cypress-tags run -e GLOB='cypress/integration/**/*.feature'
-
輸出
cypress-cucumber-preprocessor可以在運(yùn)行feature文件的時(shí)候生成一個(gè) cucumber.json 文件輸出。這是分開(kāi)的,除了在cypress中配置Mocha報(bào)告。
這些文件可以和其他任何一個(gè)cucumber報(bào)告生成器一起使用,下邊兩個(gè)都很好: https://github.com/jenkinsci/cucumber-reports-plugin 和 https://github.com/wswebcreation/multiple-cucumber-html-reporter
默認(rèn)的輸出,會(huì)寫(xiě)在文件cypress/cucumber-json中,而且一個(gè)Feature文件生成一個(gè)。這個(gè)習(xí)慣是可以配置的,使用 cosmiconfig 去為插件創(chuàng)建一個(gè)配置,to create a configuration for the plugin, 請(qǐng)參考上邊的步驟定義討論,并且將下邊的內(nèi)容添加到package.json文件中,更改默認(rèn)值。
"cypress-cucumber-preprocessor": {
"cucumberJson": {
"generate": true,
"outputFolder": "cypress/cucumber-json",
"filePrefix": "",
"fileSuffix": ".cucumber"
}
}
Cucumber 的.json 配置
| 選項(xiàng) | 默認(rèn)值 | 描述 |
|---|---|---|
| outputFolder | cypress/cucumber-json |
輸出文件的地址 |
| filePrefix |
'' (no prefix)
|
每一個(gè)feature文件根據(jù)名字生成一個(gè)單獨(dú)的json文件. 如果指定,則每一個(gè)生成的json文件將以此作為前綴 |
| fileSuffix | .cucumber |
為每一個(gè)生成的文件添加后綴名 |
| generate | false |
標(biāo)記生成 cucumber.json 文件還是不生成 |
支持的編輯器
-
WebStorm
如果你想要使用WebStorm解析你的步驟,請(qǐng)使用大寫(xiě):Given/When/Then 方法名來(lái)代替小寫(xiě) given/when/then。 注意:只有WebStorm 2019.2或者更新的版本才能使用解析在step_definitions文件之外的步驟。
-
Intellij IDEA
Intellij IDEA 社區(qū)版不支持 cucumber 使用 javascript,但是終極版可以提供和WebStorm同樣的級(jí)別的步驟解析的支持。
為了確保能夠解決
為了能夠在Intellij IDEA 終極版編輯器中解析cucumber步驟,你需要下載和授權(quán)JetBrains Cucumber JS plugin。在 WebStorm,這個(gè)插件已經(jīng)綁定在授權(quán)版本中。
-
Visual Studio Code
使用VSCode解析cucumber步驟,需要下載擴(kuò)展插件:Cucumber (Gherkin) Full Support。而且你需要告訴擴(kuò)展工具你的Feature和測(cè)試步驟文件的路徑, 像這里描述的。
注意,和WebStorm不同, WebStorm可以正確的匹配步驟的多個(gè)實(shí)現(xiàn),但是VSCode當(dāng)前只能解析第一個(gè)他在對(duì)應(yīng)路徑下匹配的實(shí)現(xiàn)。
TypeScript支持
-
有 Webpack
可以使用Webpack加載程序處理的功能文件(TypeScript 支持)。想知道如何做,請(qǐng)看這里: cypress-cucumber-webpack-typescript-example
-
沒(méi)有 Webpack
如果你想使用TypeScript,添加下邊的代碼在plugins/index.js文件中,而且安裝tsify, npm install tsify。我默認(rèn)你已經(jīng)安裝了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文件中需要確保要么要求/導(dǎo)入步驟定義的函數(shù),或者聲明他們?yōu)槿值摹?/p>
declare const Given, When, Then;
// OR
import { Given, Then, When } from "cypress-cucumber-preprocessor/steps";
在這里可以查看一下示例: https://github.com/TheBrainFamily/cypress-cucumber-typescript-example/