我有一个代码,其中某些测试在CI环境中始终会失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过Mocha中的测试?
我有一个代码,其中某些测试在CI环境中始终会失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过Mocha中的测试?
Answers:
您可以通过在describe或it块的前面放置一个x或在它的后面放置一个x来跳过测试.skip
。
xit('should work', function (done) {});
describe.skip('features', function() {});
您还可以通过在测试上放置一个来运行单个.only
测试。例如
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
在这种情况下,仅功能部件2块将运行。
似乎没有办法以编程方式跳过测试,但是您可以在beforeEach
语句中进行某种形式的检查,并且仅在设置了标志的情况下才运行测试。
beforeEach(function(){
if (wrongEnvironment){
runTest = false
}
}
describe('feature', function(){
if(runTest){
it('should work', function(){
// Test would not run or show up if runTest was false,
}
}
}
beforeEach
调用执行,摩卡记录匿名函数(“钩子”)未来的使用中,当describe
调用执行,摩卡立即执行传递给它的匿名函数。因此,在if (runTest)
执行时间之前,该beforeEach
钩子将不会运行。
有一种未记录的以编程方式跳过测试的方式:
// test.js
describe('foo', function() {
before(function() {
this.skip();
});
it('foo', function() {
// will not run
console.log('This will not be printed');
});
});
运行:
$ mocha test.js
foo
- foo
0 passing (9ms)
1 pending
describe
为已跳过(即,中的所有测试describe
都已跳过)。
此答案确实适用于ES6。
代替:
describe('your describe block', () => {
你要:
(condition ? describe : describe.skip)('your describe block', () => {
如果条件为假,则有条件地跳过describe块中的所有测试。
或者,代替:
it('your it block', () => {
你要:
(condition ? it : it.skip)('your it block', () => {
如果条件为假,则有条件地跳过一个测试。
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
那么你可以使用它: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
对于您所描述的相同情况,我使用从Mocha跳过运行时的方法。这是来自docs的复制粘贴:
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
如您所见,它会根据环境跳过测试。我自己的情况是if(process.env.NODE_ENV === 'continuous-integration')
。
if (/* skipTestCondition */) return this.skip();
-编辑:作品:D
describe.skip
或it.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
或it.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
这取决于您要如何以编程方式跳过测试。如果可以在运行任何测试代码之前确定跳过的条件,则可以根据条件调用it
或it.skip
根据需要调用。例如,如果环境变量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!");
});
});
尽管我的第一个示例将测试标记为正式跳过(又称“待定”),但我刚刚显示的方法将避免执行实际测试,但不会将测试标记为正式跳过。他们将被标记为通过。如果您绝对希望跳过它们,那么我不知道除了访问测试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之类的标签。要排除这些测试,您可以在package.json中定义一个特定的“ ci目标”,并使用--grep
和--invert
参数,例如:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
您可以使用我的软件包mocha-assume来以编程方式跳过测试,但只能从测试外部进行。您可以这样使用它:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-assume仅在myAssumption
is 时运行您的测试true
,否则它将it.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... */
});
});
});
以这种方式使用它,可以避免级联失败。假设"Does something cool"
在someAssumption不成立的情况下测试总是会失败的-但是这个假设已经在(中Tests that verify someAssuption is always true"
)中进行了测试。
因此,测试失败不会为您提供任何新信息。实际上,它甚至是假阳性的:测试没有失败是因为“有些酷”没有用,而是因为没有满足测试的前提条件。与mocha-assume
您经常可以避免这种误报。
beforeAll
不能保证在收集所有测试之前运行该挂钩。实际上,它很可能仅在之后运行,但在这种情况下,assuming(someAssumption)
它已经收到了初始(未定义)值。还需要将该部分包装在一个函数中以实现所需的效果。
我们可以编写一个很好的clean wrapper函数来有条件地运行测试,如下所示:
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();
});
假设我的测试描述包含字符串“ foo”,我想跳过参数化测试,我可以这样做:
// Skip parametrized test if description contains the string "foo"
(test.description.indexOf("foo") === -1 ? it : it.skip)("should test something", function (done) {
// Code here
});
// Parametrized tests
describe("testFoo", function () {
test({
description: "foo" // This will skip
});
test({
description: "bar" // This will be tested
});
});
就您而言,我相信如果您想检查环境变量,则可以使用NodeJS:
process.env.ENV_VARIABLE
例如(警告:我还没有测试这段代码!),也许是这样的:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
您可以将ENV_VARIABLE设置为您要键入的值,然后使用该值跳过或运行测试。(仅供参考,NodeJS的process.env的文档位于:https : //nodejs.org/api/process.html#process_process_env)
我不会完全相信此解决方案的第一部分,我找到并测试了答案,它非常适合通过以下资源基于简单条件跳过测试:https : //github.com/mochajs/mocha/issues / 591
希望这可以帮助!:)
这并不是真正使用mocha的功能,而是对其进行了调整以获得我想要的行为。
我想在量角器式摩卡测试中跳过所有后续的“是”,而其中一个“失败”。这是因为一旦旅程测试的一个步骤失败了,几乎可以肯定其余的都会失败,并且如果他们使用浏览器等待元素出现在页面等上,则可能花费很长时间并占用构建服务器。
当仅运行标准Mocha测试(而不是量角器)时,可以通过将“ skipSubsequent”标志附加到测试的父项(描述)来使用全局beforeEach和afterEach钩子来实现,如下所示:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
当尝试使用量角器进行摩卡时,“ this”的范围已更改,并且上面的代码不起作用。您最终收到一条错误消息,例如“错误调用done()”,并且量角器暂停。
相反,我最终得到了下面的代码。这不是最漂亮的方法,但是最终用this.skip()替换了其余测试功能的实现。如果/当mocha的内部版本随更高版本更改时,这可能会停止工作。
通过调试和检查mocha的内部结构,通过反复试验找出了问题所在……当测试失败时,这有助于使浏览器测试套件更早完成。
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 test/ --grep <pattern>
@danielstjules 在这里回答时,有一种跳过测试的方法。这个主题的@author复制了github.com mochajs讨论的答案,但是没有可用版本的mocha的信息。
我正在使用grunt-mocha-test模块将摩卡测试功能集成到我的项目中。跳到最后一个(现在)版本-0.12.7带this.skip()实现的摩卡版本2.4.5。
所以,在我的package.json中
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
然后
npm install
这让我对这个钩子感到满意:
describe('Feature', function() {
before(function () {
if (!Config.isFeaturePresent) {
console.log('Feature not configured for that env, skipping...');
this.skip();
}
});
...
it('should return correct response on AB', function (done) {
if (!Config.isABPresent) {
return this.skip();
}
...
请不要。构建基础架构应承认在整个环境中无法始终如一地工作的测试。当配置项构建的运行测试数量与本地运行数量不同时,这可能会令人迷惑。
同样,它也增加了可重复性。如果在服务器和本地服务器上运行不同的测试,则我可以使测试在开发中失败并通过CI,反之亦然。没有强制功能,我无法快速,准确地纠正失败的构建。
如果必须关闭环境之间的测试,而不是有条件地运行测试,请标记测试并使用过滤器以消除在某些构建目标中不起作用的测试。这样,每个人都知道发生了什么事,并且缓和了他们的期望。它还使每个人都知道测试框架中存在不一致之处,并且有人可能会找到一种使它们再次正常运行的解决方案。如果您只是使测试静音,他们甚至可能都不知道存在问题。
this.skip()
以编程方式跳过测试。答案的其余部分已经过时,摩卡V3 +