我有一个代码,其中某些测试在CI环境中总是失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过mocha测试?
我有一个代码,其中某些测试在CI环境中总是失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过mocha测试?
当前回答
这并不是真正使用摩卡的功能,而是调整它以获得我想要的行为。
我想在量角器摩卡测试中跳过所有后续的“it’s”,但有一个“it’s”失败了。这是因为一旦旅程测试的一个步骤失败,几乎可以肯定其他步骤也会失败,并且可能需要很长时间,如果他们使用浏览器等待元素出现在页面上等,可能会占用构建服务器。
当只是运行标准摩卡测试(不是量角器)时,这可以通过全局beforeEach和afterEach钩子来实现,在测试的父(描述)上附加一个' skipfollow '标志,如下所示:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
当尝试使用量角器和摩卡时,“this”的范围发生了变化,上面的代码不起作用。你最终会得到一个错误消息,比如'error calling done()',量角器会停止。
相反,我最终得到了下面的代码。不是最漂亮的,但它最终用this.skip()替换了其余测试函数的实现。如果/当摩卡的内部结构在后续版本中发生变化时,这可能会停止工作。
这是通过调试和检查摩卡内部的一些试验和错误发现的……不过,当测试失败时,有助于更快地完成浏览器测试套件。
beforeEach(function() {
var parentSpec = this.currentTest.parent;
if (!parentSpec.testcount) {
parentSpec.testCount = parentSpec.tests.length;
parentSpec.currentTestIndex = 0;
} else {
parentSpec.currentTestIndex = parentSpec.currentTestIndex + 1;
}
if (parentSpec.skipSubsequent) {
parentSpec.skipSubsequent = false;
var length = parentSpec.tests.length;
var currentIndex = parentSpec.currentTestIndex;
for (var i = currentIndex + 1; i < length; i++) {
parentSpec.tests[i].fn = function() {
this.skip();
};
}
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
});
其他回答
使用Mocha的skip()函数
它可以用来静态地禁用测试或整个套件,也可以在运行时动态地跳过它。
下面是一个运行时用法的例子:
it('should only test in the correct environment', function() {
if (/* check test environment */) {
// make assertions
} else {
this.skip();
}
});
我们可以编写一个整洁的包装器函数来有条件地运行测试,如下所示:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
然后可以在您的测试中要求并按以下方式使用:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
您可以使用我的包mocha-assume以编程方式跳过测试,但只能从测试之外跳过。你可以这样使用它:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-assume只会在myAssumption为真时运行你的测试,否则它会跳过它(使用它。skip)并传递一个好的消息。
下面是一个更详细的例子:
describe("My Unit", () => {
/* ...Tests that verify someAssuption is always true... */
describe("when [someAssumption] holds...", () => {
let someAssumption;
beforeAll(() => {
someAssumption = /* ...calculate assumption... */
});
assuming(someAssumption).it("Does something cool", () => {
/* ...test something cool... */
});
});
});
以这种方式使用它,可以避免级联故障。当某些假设不成立时,测试“do something cool”总是会失败——但这个假设已经在上面测试过了(在验证某些假设总是正确的测试中)。
因此,测试失败不会给您任何新信息。事实上,它甚至是一个假阳性:测试失败并不是因为“一些很酷的东西”没有工作,而是因为测试的先决条件没有得到满足。使用摩卡,假设你经常可以避免这种误报。
请不要。在不同环境中不能一致工作的测试应该得到构建基础设施的承认。当CI构建运行的测试数量与本地构建不同时,可能会非常令人困惑。
它还破坏了重复性。如果不同的测试运行在服务器和本地,我可以有测试失败在开发和通过CI,反之亦然。没有强制功能,我无法快速准确地纠正失败的构建。
如果必须关闭环境之间的测试,而不是有条件地运行测试,请标记您的测试并使用过滤器来消除在某些构建目标中不起作用的测试。这样每个人都知道发生了什么,并降低他们的期望。它还让每个人都知道测试框架中存在不一致,并且有人可能有一个解决方案,可以使它们再次正常运行。如果你只是静音测试,他们可能甚至不知道有问题。
这并不是真正使用摩卡的功能,而是调整它以获得我想要的行为。
我想在量角器摩卡测试中跳过所有后续的“it’s”,但有一个“it’s”失败了。这是因为一旦旅程测试的一个步骤失败,几乎可以肯定其他步骤也会失败,并且可能需要很长时间,如果他们使用浏览器等待元素出现在页面上等,可能会占用构建服务器。
当只是运行标准摩卡测试(不是量角器)时,这可以通过全局beforeEach和afterEach钩子来实现,在测试的父(描述)上附加一个' skipfollow '标志,如下所示:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
当尝试使用量角器和摩卡时,“this”的范围发生了变化,上面的代码不起作用。你最终会得到一个错误消息,比如'error calling done()',量角器会停止。
相反,我最终得到了下面的代码。不是最漂亮的,但它最终用this.skip()替换了其余测试函数的实现。如果/当摩卡的内部结构在后续版本中发生变化时,这可能会停止工作。
这是通过调试和检查摩卡内部的一些试验和错误发现的……不过,当测试失败时,有助于更快地完成浏览器测试套件。
beforeEach(function() {
var parentSpec = this.currentTest.parent;
if (!parentSpec.testcount) {
parentSpec.testCount = parentSpec.tests.length;
parentSpec.currentTestIndex = 0;
} else {
parentSpec.currentTestIndex = parentSpec.currentTestIndex + 1;
}
if (parentSpec.skipSubsequent) {
parentSpec.skipSubsequent = false;
var length = parentSpec.tests.length;
var currentIndex = parentSpec.currentTestIndex;
for (var i = currentIndex + 1; i < length; i++) {
parentSpec.tests[i].fn = function() {
this.skip();
};
}
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
});