我正在尝试确定是否可以有条件地跳过测试套件中的测试it()
并处理其异步特性。
我已经在赛普拉斯文档https://docs.cypress.io/guides/core-concepts/conditional-testing.html中阅读了有关条件测试的信息,并在https://mochajs.org/上了解了mochajs文档。
我的目的是检查网站上是否显示错误,如果没有,请跳过测试。否则,继续进行断言。
我要在赛普拉斯进行测试的来自mochajs的代码段为:
it('should only test in the correct environment', function() {
if (/* check test environment */) {
// make assertions
} else {
this.skip();
}
});
所以我在赛普拉斯拥有的是:
it('shows the list', function() {
if (queryFailed()) {
this.skip();
} else {
cy.get('.list')
.should('be.visible')
}
请注意,我将it()
中的箭头功能更改为function()
,以便可以使用this
。
queryFailed()
是用于检查查询是否成功的功能。
function queryFailed() {
cy.get('.spin')
.then($container => {
const htmlLoaded = $container[0].innerHTML;
if (htmlLoaded.indexOf('List') !== -1) {
return false;
}
if (htmlLoaded.indexOf('error') !== -1) {
return true;
}
cy.wait(1000);
queryFailed();
});
}
简而言之,如果我正在等待的div
元素的内容为“错误”,那么我知道查询失败,因此我返回true,否则返回false。
我在调试后的测试中看到的是,即使条件运行良好,JS的异步特性也将在else
语句中同时执行if
语句中的代码。既然所有的东西都经过测试,那么最终输出就好像根本没有任何条件。
有没有更好的方法来处理JS的异步功能?
答案 0 :(得分:3)
Cypress现在还提供了一个库@cypress/skip-test,该库可以通过以下方式提供更多控件:
cy.skipOn
cy.onlyOn
isOn
DISCLOSE:我与Cypress没有关联。
答案 1 :(得分:2)
感谢您的详细说明! 我为您的第一个问题提供了解决方案
我正在尝试确定是否能够有条件地跳过测试套件中的测试it()并处理其异步特性。
使用环境变量,我向您报告了我的解决方案(实际上是在我的管道中使用)。
if (!Cypress.env("SKIP_E2E_TESTS")) {
it(...);
}
在我的package.json
文件中,我有一个看起来像这样的脚本
"test": "CYPRESS_SKIP_E2E_TESTS=true npm-run-all --parallel --silent test:unit test:cypress",
我的目标与您的目标相同,我想在某些情况下禁用某些测试(本例中为CI管道)。
因此,将整个测试置于条件中,而不要进行条件测试。
让我知道是否需要更多帮助
答案 2 :(得分:2)
我认为您已经快到了,但是您需要异步回调模式来代替同步if () {...} else {...}
模式。
it('shows the list', function() {
const whenFailed = function() {
this.skip()
}
const whenSucceeded = function() {
cy.get('.list').should('be.visible')
}
queryFailed(whenFailed, whenSucceeded);
}
function queryFailed(whenFailed, whenSucceeded) {
cy.get('.spin')
.then($container => {
const htmlLoaded = $container[0].innerHTML;
if (htmlLoaded.indexOf('List') !== -1) {
whenSucceeded();
return;
}
if (htmlLoaded.indexOf('error') !== -1) {
whenFailed();
return;
}
cy.wait(1000);
queryFailed(whenFailed, whenSucceeded);
});
}
但是,我注意到对queryFailed()
的递归调用,看来您正在手动重试旋转容器的内容。
Cypress内置了重试功能,因此您要做的就是确定结果可能要花费的最长时间(例如20秒),并且一旦所需的内容到达或测试失败,它将结束该命令。如果在20秒内完全没有发生,那么
此外,您应该控制微调框正在等待的任何操作的成功/失败(例如,通过XHR获取列表)。因此,您应该将测试分为两项-一种是成功,另一种是失败。
context('when the list loading succeeds' function() {
it('shows the list', function() {
// Mock XHR success here
cy.contains('.spin', 'List', { timeout: 20000 });
cy.get('.list').should('be.visible');
})
it('does not show an error message', function() {
...
})
})
context('when the list loading fails' function() {
it('does not show the list', function() {
// Mock XHR failure here
cy.contains('.spin', 'error', { timeout: 20000 });
cy.get('.list').should('not.be.visible');
})
it('shows an error message', function() {
...
})
})
这有点粗糙,因为我不知道确切的HTML预期或微调器正在等待什么,但是您可以看到这种模式更加整洁并以受控方式测试所有路径。
答案 3 :(得分:0)
我使用的是@NoriSte的答案的改编版本,该版本仍在注册测试,但已跳过:
const maybeDescribe = Cypress.env('SOME_ENV_VAR') ? describe : describe.skip
maybeDescribe('Test suite', function() { /* ... */ })
然后类似地,在CI上,我想跳过测试:
export CYPRESS_SOME_ENV_VAR=
$(npm bin)/cypress run
我的源代码控制cypress.json
定义了SOME_ENV_VAR
,所以当我在本地运行时,不会跳过测试。
答案 4 :(得分:-1)
例如,Cypress Real World App,a payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows包含一些用于在CI中有条件地运行测试的工作流,以及用于移动视口的已更改工作流。
此外,从赛普拉斯v4.8.0开始,某些Test Configurations可以应用于套件或个人测试。
例如:
plotArea: {
dataLabel: {
visible: false
},
dataPointStyle: {
"rules":
[
{
"dataContext": {"idTurnover": {"min": 0}},
"properties": {
"color":"sapUiChartPaletteSemanticBad"
},
"displayName":"Loss"
},
{
"dataContext": {"idTurnover": {"max": 0}},
"properties": {
"color":"sapUiChartPaletteSemanticGood"
},
"displayName":"Profit"
}
],
"others":
{
"properties": {
"color": "sapUiChartPaletteSequentialHue1"
},
"displayName":"Cost"
}
}
},