如何解决赛普拉斯:为数组的每个元素创建一个它测试
我有一个字符串数组,它们是指向同一网站不同页面的链接;对于这些网页中的每一个,我都对其进行了多次测试,并且对于每个页面,我在页面的不同 HTML 块上进行迭代(所有页面都具有相同的块 ID)。
例如,我有 10 页描述了 10 个不同的城市;所有页面都有 9 个具有相同 id 的相同 html 块(它们都来自同一个模板)。我检查每个 ID 中是否有几个词。
我确实做到了;我需要做的是为每个元素创建一个它测试。我会尽量解释得更好。
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,id)
})
})
})
})
})
但是这段代码不起作用,它完全跳过了它内部循环的测试。 有什么办法吗?
更新:
我之前没有提到过,但我发现上面的代码有效。
我的问题是,由于我必须从在线 XML 文件中检索 urls 列表并将其转换为对象(上面描述的对象 urls
),我将所有代码包装在一个请求中,然后是一个 {{1 }},喜欢
.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
块结束,即使使用 .then()
。
nor 使用 cy.task
块会有所帮助,因为没有任何方法可以将数据带出 before()
块和 before()
块内部(不是 describe()
块).
解决方法
我终于找到了解决办法:
自 2021 年 4 月 12 日起,cypress 添加了一项实验性支持,可在您的规范文件(*.spec.js
、*.test.js
或任何您的测试文件)启动之前执行代码。
更多信息here。
有趣的是这个选项: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 是一个 plugin,用于将 xmls 转换为 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
后单击测试文件时;因此,如果您只是更改代码或使用刷新按钮重新启动测试,则不会再次下载该文件。您必须关闭浏览器并再次单击您的测试,但这对我来说是可以接受的,因为在线文件不会如此频繁地更改。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。