我有一个数据驱动的赛普拉斯代码,如下所示。 我正在尝试根据“数据”变量的值动态生成测试。
let data:QuestionData[];
describe("Add data to admin", ()=>{
before(async ()=>{
data = await promisify(cy.task("readCSV",csvFile));
});
data.forEach((val,index)=>{
it(`Should add val ${val}`, ()=>{
console.log(index);
})
})
});
我的“readCSV”方法只是读取 csv 并解析数据。
当我运行上面的代码时,我收到此错误 -> 无法读取未定义的属性(读取“forEach”)。
原因是“data.forEach”在变量初始化之前运行。 如果我在“before”挂钩内写入“console.log”,我可以看到数据可用。 但是为什么数据变量在 BEFORE HOOK 之外不可用? 如果我访问“it”块内的“data”变量并用于lood,我的代码就可以工作。 但我希望动态生成测试。
如何在 cypress.io 中解决此问题?
尝试将箭头功能更改为普通功能,它可能会扰乱上下文:https://mochajs.org/#arrow-functions
cy.task() 不返回 Promise 吗?对 Promise 调用 promisify() 应该会抛出错误。即使如此,promisify() 也不会返回 Promise,它返回一个返回 Promise 的函数。
问题是 Cypress 试图在任何命令运行之前使用
data
(包括 cy.task()
块中的 before()
)。 Cypress 通过运行测试文件的 javascript 来构建测试队列,然后它运行测试队列。
Cypress 有 Before Run API 来解决这个问题。
(注意在`cypress.config.js'中设置
experimentalInteractiveRunEvents:true
选项以使用此功能)。
您可以从此切换
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
readCSV(csvFile) {
// code to read the CSV
},
})
到此
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('before:run', () => {
// code to read the CSV
})
第一个问题是如何传递
csvFile
参数。如果您通过环境变量设置它,则可以从 config.env
读取它,或者如果始终使用相同的文件名,则可以硬编码。
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('before:run', () => {
const csvFile = config.env.csvFile;
// code to read the CSV
})
第二个问题是如何将数据发送到测试。最简单的方法是将其放入另一个环境变量中。
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('before:run', () => {
const csvFile = config.env('csvFile')
// code to read the CSV
config.env('data', data)
})
然后测试在测试的顶部同步读取它。
Cypress.env()
将在 it()
或 before()
区块之外运行。
let data = Cypress.env('data')
data.forEach((val, index) => {
it(`Should add val ${val}`, () => {
// testing each data item
})
})
另一种方法将
require
或 import
CSV 作为字符串并使用纯 JavaScript 对其进行解析。
假设以逗号分隔的值行,类似于
const csvString = require('../fixtures/my-data.csv')
const lines = csvString.split(csvString, '\n')
const data = lines.map(line => line.split(','))
data.forEach((val, index) => {
it(`Should add val ${val}`, () => {
// testing each data item
})
})