cypress标准化开发---cucumber的高效利用

2024-02-03 09:20

本文主要是介绍cypress标准化开发---cucumber的高效利用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

待到秋来九月八,我花开后百花杀

  • 与Cucumber配合的标准化开发流程
  • 如何巧妙地使用cucumber建立功能丰富的feature文件
    • 测试前预处理步骤定义
    • 如何编写测试
    • 自定义参数类型解析
    • 数据表参数类型使用
    • Before 和 After 的 hooks
    • Background 场景前处理
    • 智能标记
  • 如何运行测试
    • 常规运行方式
    • 通过npx指令工具运行
    • 无头模式运行(Headless)
    • 限制指定feature文件运行
    • 执行特征标签的场景
    • 运行时操作cypress.json配置文件
  • 测试运行错误报告及测试日志的生成
    • mochawesome自定义报告生成器
    • Cucumber 报告生成器

与Cucumber配合的标准化开发流程

我们从官方网站中发现,cypress入门编程以及大多数初学cypress开发者,秉持跟随官网的方式编写测试实现,然而事实中,在无头模式下运行cypress测试时,执行时间会变得非常臃肿,这是因为默认情况下cypress会在每个如下编程的功能之间重新启动浏览器。

describe('My First Test', () => {it('Does not do much!', () => {expect(true).to.equal(true)})
})

配合使用cucumber插件,通过cucumber预处理器,提供在运行测试之前捆绑所有功能的选项,从而减少执行时间。
您可以通过创建.features文件来实现这一点。你可以选择在目录cypress/integrations的根目录中或每个目录中创建唯一一个,且只有一个。
您还必须在 Cypress 配置中添加对 .features文件的支持

{" testFiles " : " **/*.{feature,features} " 
}

当你想要运行测试文件时,

cypress run --spec **/*.features

如果你在配置中忽略了.js文件,那么你可以直接运行测试:

{"ignoreTestFiles": "*.js"," testFiles " : " **/*.{feature,features} " 
}
cypress run

如何巧妙地使用cucumber建立功能丰富的feature文件

测试前预处理步骤定义

当在package.json文件中配置了nonGlobalStepDefinitions选项,那么你可以在测试文件中的编写在测试运行中需要全局使用,或是预处理的步骤。
配置:

"cypress-cucumber-preprocessor": {"nonGlobalStepDefinitions": true
}

例如:你在cypress/integration/common目录下增加了.js文件,并写入了:

before(() => {cy.log("This will run once before all tests, you can use this to for example start up your server, if that's your thing");
});

那么,当运行测试时就会在每个测试文件执行之前运行:
请添加图片描述
这是放置与该特定功能相关的before/beforeEach/after/afterEach的好地方。

如何编写测试

Cucumber使用https://docs.cucumber.io/cucumber/cucumber-expressions/来解析您的 .feature 文件,请使用该文件作为您的参考。

.js文件中你需要使用到,Given/When/Then 函数,你可以使用IDE直接导入它们,或者如下所示:

/* global Given, When, Then */

对于.featrue文件你可以使用直接释义的方式编写测试,例如:

  Scenario:Play an A on my pianoGiven I set down before the pianoWhen I press the 1st key of my pianoAnd piano input keyThen I should hear an A sound

同时,也可以直接使用中文进行编写:

  Scenario:在我的钢琴上按下AGiven 我在钢琴前坐下When 我按下了我钢琴的第一个按键And 钢琴输入了按键Then 我应该听到一个A的声音

同时需要编写同名的.js文件,实现每个scenario的具体功能:

Given("I set down before the piano", () => {console.log(I set down before the piano’);
});
When("I press the 1st key of my piano", () => {console.log(I press the 1st key of my piano’);
});
And("piano input key", () => {console.log(‘piano input key’);
});
Then("I should hear an A sound", () => {expect(string).to.equal(I should hear an A sound’);
});

自定义参数类型解析

我们现在可以使用自定义参数类型解析。这是一个带有相关.feature 文件的示例
.feature 文件:

  Scenario: Play an A on my pianoWhen I press the 1st key of my pianoThen I should hear an A soundScenario: Play an E on my pianoWhen I press the 26th key of my pianoThen I should hear an E sound

.js文件:

const notes = ["A", "B", "C", "D", "E", "F", "G"];defineParameterType({name: "note",regexp: new RegExp(notes.join("|")),
});defineParameterType({name: "ordinal",regexp: /(\d+)(?:st|nd|rd|th)/,transformer(s) {return parseInt(s, 10);},
});let keySound = null;When("I press the {ordinal} key of my piano", (number) => {keySound = notes[(number - 1) % 7];
});Then("I should hear a(n) {note} sound", (note) => {expect(note).to.equal(keySound);
});

数据表参数类型使用

Cucumber支持使用数据表的形式编写测试,你可以像示例中一样使用它:

Feature: Being a plugin handling DataTable scenarioAs a cucumber cypress plugin which handles DataTablesI want to allow people to write DataTable scenarios and run it in cypressScenario: DataTableWhen I add all following numbers:| number | another number || 1      | 2              || 3      | 4              |Then I verify the datatable result is equal to 10Scenario: New line characterGiven I have a table with "<foo>" and "<bar>"Examples:| foo      | bar      || foo\nfoo | bar\nbar |
let sum = 0;When("I add all following numbers:", (dataTable) => {//你可以通过对象调用表的行和列console.log("a, ", dataTable.rawTable.slice(1))sum = dataTable.rawTable.slice(1).reduce((rowA, rowB) =>rowA.reduce((a, b) => parseInt(a, 10) + parseInt(b, 10)) +rowB.reduce((a, b) => parseInt(a, 10) + parseInt(b, 10)));//你也可以直接打印表console.log(dataTable);
});Then("I verify the datatable result is equal to {int}", (result) => {expect(sum).to.equal(result);
});Given("I have a table with "([^"]*)" and "([^"]*)"", (foo,bar) => {
//你也可以通过直接访问属性一样访问每个的元素,它可以按照列名,循环运行该Scenario,直到使用完每一行的元素console.log(foo);console.log(bar);
});

Before 和 After 的 hooks

Cucumber 支持 Mocha的 before/beforeEach/after/afterEach hooks,你可以在cypress/integration/common中编写这些测试前预处理步骤,但它会在每一个.featrue文件的所有测试前运行它,如果你不想在每个测试文件都运行预处理步骤,那么,Cucumber也带有自己支持的 BeforeAfter hooks,你只需要在同名的.js文件中编写即可。

Hooks用于在每个场景之前和之后设置和拆除环境。有关传递给Hooks的参数规范,请参阅API 参考:https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/api_reference.md。多个Before Hooks按照它们定义的顺序执行。多个After Hooks以它们定义的相反顺序执行。

同时它也支持指定标签的Scenario前执行。

// 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;
});

更多关于Hooks的用法请参考:
https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/hooks.md

Background 场景前处理

将Background 添加到您.featrue文件前将使您能够在每个场景之前运行。例如,我们有一个需要在每个场景之前重置的计数器。我们可以创建一个给定的步骤来重置计数器。

Feature: Background SectionBackground:Given counter has been resetScenario: Basic example #1When counter is incrementedThen counter equals 1Scenario: Basic example #2When counter is incrementedWhen counter is incrementedThen counter equals 2
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);
});

智能标记

在不设置任何标记的情况下也可以启动测试。在开发或修复bug时,你想要重点关注的scenario,你可以将@focus之类的标签,放在您想要关注的scenario上。
例如:

Feature: Smart TaggingAs a cucumber cypress plugin which handles TagsI want to allow people to select tests to run if focusedSo they can work more efficiently and have a shorter feedback loopScenario: This scenario should not run if @focus is on another scenarioThen this unfocused scenario should not run@focusScenario: This scenario is focused and should runThen this focused scenario should run@this-tag-affects-nothingScenario: This scenario should also not runThen this unfocused scenario should not run@focusScenario: This scenario is also focused and also should runThen this focused scenario should run

如何运行测试

常规运行方式

按照通常的方式运行 Cypress,例如:

./node_modules/.bin/cypress open

单击规格列表中​​的一个.feature文件,就可以看到神奇的事情发生了!

通过npx指令工具运行

在cypress文件所在目录下运行:

npx cypress open

单击规格列表中​​的一个.feature文件,就可以看到神奇的事情发生了!

无头模式运行(Headless)

./node_modules/.bin/cypress run


在cypress文件所在目录下运行:

npx cypress run

限制指定feature文件运行

 npx cypress run --spec cypress/integration/文件夹/文件名.feature

执行特征标签的场景

您可以使用标签来选择应该让cypress运行哪个测试。为了使用标签初始化测试,您必须运行 cypress 并传递 TAGS 环境变量。

 ./node_modules/.bin/cypress-tags run -e TAGS= ' not @foo and (@bar or @zap) '

请注意:这里使用的 cypress-tags 包装器来加快速度。这个包装器从本地模块调用 cypress 可执行文件,如果没有找到,它会回退到全局安装的。

或者你可以直接在配置文件中指定标签,在运行 cypress 测试运行程序时使用标签来跳过或忽略特定的测试/场景(您无法像上面的示例那样传递参数以进行执行)

诀窍在于在 cypress.json 配置文件中添加带有“TAGS”子属性的“env”属性。它看起来像这样:

{"env": {"TAGS": "not @ignore"},//rest of configuration options"baseUrl": "yourBaseUrl","ignoreTestFiles": "*.js",
}

然后,在使用 cypress 测试运行程序运行测试时,任何标有 @ignore 标签的场景都将被跳过

运行时操作cypress.json配置文件

当从命令行运行cypress或是通过shell脚本运行时,你可以传递一个–config标志,用来临时更改配置:

cypress open --config pageLoadTimeout=30000,baseUrl=https://myapp.com

或是

cypress run --config integrationFolder=tests,videoUploadOnPasses=false

对于更复杂的配置对象,您可能需要考虑传递一个由单引号括起来的 JSON.stringified对象。

cypress open --config '{"watchForFileChanges":false,"testFiles":["**/*.js","**/*.ts"]}'

或是,直接指定使用其他配置文件

cypress run --config-file ../cypress.json

测试运行错误报告及测试日志的生成

cypress支持创建您自己的自定义报告器或使用任何类型的第三方报告器,这里列举无需安装任何工具下可使用的两种报告生成形式。

mochawesome自定义报告生成器

因为 Cypress 建立在 Mocha 之上,这意味着任何为 Mocha 构建的报告器都可以与 Cypress 一起使用。

可以通过相对或绝对路径加载自定义 Mocha 报告器。这些可以在您的配置文件中指定(cypress.json默认情况下)或通过命令行指定。

配置文件

{"reporter": "mochawesome"
}

命令行

cypress run --reporter mochawesome

你还可以通过reporterOption来控制你希望对自定义报告的选项的定义:

配置文件

{"reporter": "mochawesome","reporterOptions": {"reportDir": "cypress/results","overwrite": false,"html": false,"json": true}
}

命令行

cypress run --reporter mochawesome \--reporter-options reportDir="cypress/results",overwrite=false,html=false,json=true

这样,每当运行一个.feature测试文件时,就会在cypress/results目录下生成一个类似mochawesome_001.json测试报告。

如果你希望所有生成的测试报告可以放在一个.json文件中,你可以使用merge命令,例如:

npx mochawesome-merge "cypress/results/*.json" > mochawesome.json

它会将该目录下的所有.json文件合并成一个文件
通过以下命令,还可以生成方便阅读的html文件:

npx mochawesome-report-generator mochawesome.json

请添加图片描述
如果你希望了解更多,测试日志报告的生成,可以参考:
https://docs.cypress.io/guides/tooling/reporters

Cucumber 报告生成器

每次运行.feature时会输出产生cucumber.json。这与 Cypress 中配置的任何 Mocha 报告器是分开的,并且是它们的补充。
这些文件旨在用于与许多可用的 Cucumber 报告生成器一起配合使用。适用于https://github.com/jenkinsci/cucumber-reports-plugin(在Jenkins上发布漂亮的Cucumber报告)和https://github.com/wswebcreation/multiple-cucumber-html-reporter

请添加图片描述
默认情况下,输出被写入文件夹cypress/cucumber-json,并且每个feature文件生成一个json文件。
此行为是可配置的。使用cosmiconfig为插件创建配置,请参阅上面的预处理步骤定义章节并将以下内容添加到 package.json 中的 cypress-cucumber-preprocessor 部分以将其关闭或更改默认值:

  "cypress-cucumber-preprocessor": {"cucumberJson": {"generate": true,"outputFolder": "cypress/cucumber-json","filePrefix": "","fileSuffix": ".cucumber"}}

Cucumber.json 配置选项

OptionDefault valueDescription
outputFoldercypress/cucumber-json要将文件写入的文件夹
filePrefix'' (no prefix)根据feature文件的名称为每个feature生成单独的json文件。如果指定,所有生成的文件名都将以此选项作为前缀
fileSuffix.cucumber要添加到每个生成的文件名的后缀
generatefalse标记是否输出cucumber.json

这篇关于cypress标准化开发---cucumber的高效利用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/673673

相关文章

在Golang中实现定时任务的几种高效方法

《在Golang中实现定时任务的几种高效方法》本文将详细介绍在Golang中实现定时任务的几种高效方法,包括time包中的Ticker和Timer、第三方库cron的使用,以及基于channel和go... 目录背景介绍目的和范围预期读者文档结构概述术语表核心概念与联系故事引入核心概念解释核心概念之间的关系

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件