Cypress:创建一个数组的it测试foreach元素



我有一个字符串数组,它们是指向同一网站不同页面的链接;对于这些网页中的每一个,我都会对其进行几次测试,并对每个页面迭代页面的不同HTML块(所有页面都有相同的块id(。

例如,我有10页描述了10个不同的城市;所有页面都有9个相同id的html块(它们都来自同一个模板(。我检查每个id中是否有几个单词。

我确实做到了;我需要做的是为每个元素创建一个it测试。我会尽量解释得更好。

主对象中有一系列数组,所以我有一个urls对象,比如:

urls: {
cities: [...],
secondArr: [...],
thirdArr: [...]
}

我对urls.cities阵列感兴趣。

这是城市阵列中的一个对象:

urls.cities: [{
city: "Miami"
discipline: "no-discipline"
type: "main"
url: "https://myWebsite.com/miami/"
}, 
...]

我做了一些类似的事情:main.test.js

it('should retrieve generated pages', () => {
[...]
// executing tests for cities
urls.cities.forEach(elem => {
cy.visit(elem.url)
let ids = idsInAllPages   // there's a const idsInAllPages = ['id1', 'id2', ...] on top of the code
ids.forEach(id => {
// i get the webelement matching the id, with cypress
cy.get(id).then(webElem => {
checkAllWebElementsOfCityUrl(webElem, elem, id)
})
})
})
})

checkAllWebElementsOfCityUrl()函数中,我做了一些事情,包括一个forEach循环来测试每个html块代码(如果需要,我可以添加代码,无论如何解释起来都有点长,因为我从JSON文件中提取单词进行检查,并将它们与html块内的内容进行比较(。

一切都很好,但我的问题是它是一个单独的it('...')块:因此,如果发现错误,则不会完成所有后续测试。

因此,我需要创建数组的it测试forEach元素。

类似的东西

it('should retrieve generated pages', () => {
[...]
// executing tests for cities
urls.cities.forEach(elem => {
it('should test a city', () => {
cy.visit(elem.url)
let ids = idsInAllPages
ids.forEach(id => {
cy.get(id).then(webElem => {
webpageshelp.checkAllWebElementsOfCityUrl(webElem, elem, id)
})
})
})
})
})

但这段代码不起作用,它完全跳过了内部循环的it测试。有什么办法吗?

更新:

我以前没有提到它,但我发现上面的代码是有效的。我的问题是,由于我必须从一个在线XML文件中检索url列表并将其转换为一个对象(如上所述的对象urls(,所以我将所有代码封装在一个请求中,然后是一个.then(),如

cy.request('https://myWebsite.com/urlslist.xml').then(
urls => {
urls.cities.forEach(elem => {
it('should test a city', () => {
cy.visit(elem.url)
})
})
})

使用想要检索文件的任何内容更改cy.request,即使使用cy.task,也总是会出现.then()块。

使用before()块的NOR可能会有所帮助,因为没有任何方法可以将数据带到before()块之外和describe()块(而不是it()块(内部。

我终于找到了一个解决方案,我会把这个页面贴下来。

我终于找到了一个解决方案:

自2021年4月12日起,柏树添加了一个实验性支持,可以在规范文件(*.spec.js*.test.js或任何测试文件(开始之前执行代码。

点击此处了解更多信息。

有趣的是这个选项:experimentalInteractiveRunEvents,它启用代码的before:spec执行。

您需要在您的cypress.js文件中添加选项

{
"...": "...",
...,
"experimentalInteractiveRunEvents": true
}

然后,在/plugins/index.js文件中,我添加了

module.exports = (on, config) => {
on('...', ...),
// executes function before running the test file - EXPERIMENTAL
on('before:spec', async () => {
let data = await webpageshelp.retrieveAndConvertXMLToJSON()
return fs.writeFileSync('data.json', data)
})
}

async/await函数是在另一个js文件中定义的函数,它下载XML文件并将其转换为JSON:

async function retrieveAndConvertXMLToJSON() {
const http = axios.create({ baseURL: 'http://myWebsite.com' })
try {
const { data } = await http.get('/myfile.xml')
let jdata = convert.xml2js(data, { compact: true, spaces: 4 })
let rawUrls = []
jdata.urlset.url.forEach(url => {
rawUrls.push(url.loc._text)
})
return JSON.stringify(rawUrls)
} catch (error) {
throw err
}
}

关于url.loc.text的逻辑是由于xml配置;xml2js是一个将xml转换为json的插件。

此时,在主mytest.test.js文件中使用

const rawUrls = require('../../../data.json')

在文件顶部,然后是

describe('my tests', () => {
// some more work with my urls
let urls = filterUrls(rawUrls)    // a function that removes unuseful urls
urls.cities.forEach(elem => {
it(`TEST for city ${elem.city} and discipline ${elem.discipline}`, () => {
console.log('yayyy', elem)
})
})
})

VOILA,它跑了!

唯一的缺点是文件下载只发生一次,当你在运行cypress open后点击测试文件时;因此,如果您只是更改代码或使用刷新按钮重新启动测试,它将不会再次下载该文件。你必须关闭浏览器,然后再次点击你的测试,但这对我来说是可以接受的,因为在线文件不会经常更改。

最新更新