我有一个代码,其中某些测试在CI环境中总是失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过mocha测试?
我有一个代码,其中某些测试在CI环境中总是失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过mocha测试?
当前回答
这取决于您希望如何以编程方式跳过测试。如果在运行任何测试代码之前可以确定跳过的条件,那么您可以直接调用它或它。根据需要,根据条件跳过。例如,如果环境变量ONE被设置为任何值,这将跳过一些测试:
var conditions = {
"condition one": process.env["ONE"] !== undefined
// There could be more conditions in this table...
};
describe("conditions that can be determined ahead of time", function () {
function skip_if(condition, name, callback) {
var fn = conditions[condition] ? it.skip: it;
fn(name, callback);
};
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
如果您想要检查的条件只能在测试时确定,那就有点复杂了。如果你不想访问任何严格来说不是测试API的部分,那么你可以这样做:
describe("conditions that can be determined at test time", function () {
var conditions = {};
function skip_if(condition, name, callback) {
if (callback.length) {
it(name, function (done) {
if (conditions[condition])
done();
else
callback(done);
});
}
else {
it(name, function () {
if (conditions[condition])
return;
callback();
});
}
};
before(function () {
conditions["condition one"] = true;
});
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
虽然我的第一个例子是将测试标记为正式跳过(又名“pending”),但我刚才展示的方法只是避免执行实际的测试,但测试不会标记为正式跳过。他们将被标记为通过。如果你真的想跳过它们,我不知道有什么方法可以访问不是测试API的部分:
describe("conditions that can be determined at test time", function () {
var condition_to_test = {}; // A map from condition names to tests.
function skip_if(condition, name, callback) {
var test = it(name, callback);
if (!condition_to_test[condition])
condition_to_test[condition] = [];
condition_to_test[condition].push(test);
};
before(function () {
condition_to_test["condition one"].forEach(function (test) {
test.pending = true; // Skip the test by marking it pending!
});
});
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
其他回答
我不确定这是否可以称为“程序性跳过”,但是为了有选择性地跳过我们CI环境中的某些特定测试,我使用了Mocha的标记功能(https://github.com/mochajs/mocha/wiki/Tagging)。 在describe()或it()消息中,可以添加@no-ci这样的标记。要排除这些测试,可以在包中定义特定的“ci目标”。使用——grep和——invert参数,如下:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
这并不是真正使用摩卡的功能,而是调整它以获得我想要的行为。
我想在量角器摩卡测试中跳过所有后续的“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'
}
});
这个答案确实适用于ES6。
而不是:
describe('your describe block', () => {
你想要的:
(condition ? describe : describe.skip)('your describe block', () => {
如果条件为假,这将有条件地跳过描述块中的所有测试。
或者,代替:
it('your it block', () => {
你想要的:
(condition ? it : it.skip)('your it block', () => {
如果条件为假,则有条件地跳过一个测试。
我们在测试环境中有一些不可靠的测试,有时会使用以下方法关闭这些测试:
mocha --config ./config/parallelrc.cjs --parallel --jobs 3 -- tests/spec/**/index.js -g @flaky -i
我们在测试描述中标记flaky测试@flaky,并设置特殊的-g规则,这意味着mocha只运行带有@flaky标签的测试,接下来使用-i -它意味着反转,因此mocha只运行测试而不是@flaky。
所以,我认为这对你很有用)
可根据情况使用, 例如,声明一个var,当条件失败时,使用this.skip();
注意skip()在箭头函数中不起作用
let shouldRun: boolean;
before(function(){
if ($('#nsErrorIframe').isDisplayed()) {
driver.switchToFrame($('#nsErrorIframe'));
if ($('.ns-error-wrapper').isDisplayed()) {
console.log('PAGE IS NOT AVAILABLE');
shouldRun = false;
if ( shouldRun === false) {
this.skip();
}
}
}
});