如何以编程方式跳过摩卡测试?

Gaj*_*jus 117 mocha.js

我有一个代码,其中某些测试将始终在CI环境中失败.我想根据环境条件禁用它们.

如何在运行时执行期间以编程方式跳过mocha中的测试?

KJ3*_*KJ3 153

您可以通过在describe或it块前面放置一个x或在.skip其后放置一个来跳过测试.

xit('should work', function (done) {});

describe.skip('features', function() {});
Run Code Online (Sandbox Code Playgroud)

您也可以通过测试来运行单个.only测试.例如

describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只有特征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,
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案如何有27个赞成?问题是以编程方式跳过测试,因此添加".skip"或".only"没有帮助.然后它明确表示你不能做OP想要做的事情,尽管其他答案告诉你如何去做. (18认同)
  • 您对解决方案的第二次尝试将无效,因为执行顺序与您认为的顺序不同.当执行`beforeEach`调用时,Mocha*记录*future*使用的*匿名函数("hook"),当`describe`调用执行时,Mocha*立即*执行传递给它的匿名函数.因此,当执行`if(runTest)`时,`beforeEach`*hook*将不会运行. (8认同)
  • 这个答案对于这里没有提出的另一个问题有其优点。我没有权力改变这里的任何事情。请参阅 this.skip() 答案。 (5认同)
  • 无法正常工作,无法解决问题,请参阅@Gajus的回复 (3认同)
  • 这不能回答问题 (3认同)
  • 投票,这不能回答问题。 (2认同)

Gaj*_*jus 95

有一种无记录的以编程方式跳过测试的方法:

// test.js

describe('foo', function() {
  before(function() {
    this.skip();
  });

  it('foo', function() {
    // will not run
    console.log('This will not be printed');
  });
});
Run Code Online (Sandbox Code Playgroud)

运行:

$ mocha test.js


  foo
    - foo


  0 passing (9ms)
  1 pending
Run Code Online (Sandbox Code Playgroud)

这将在https://github.com/mochajs/mocha/issues/1901中讨论.

  • 读者可能想知道这标志着整个`describe`被跳过(即`describe`中的所有测试都被跳过). (9认同)
  • 多数民众赞成.您也可以跳过特定的测试. (3认同)
  • 实际文档 https://mochajs.org/#inclusive-tests ,无论如何,这都不是黑客,而是根据运行时设置排除某些测试的正确方法。即它准确地回答了原来的问题。谢谢@xavdid (3认同)
  • 如果您在这里并且正在使用 **Jest**,希望它以同样的方式支持 `this.skip()`,我会为您节省一些时间 - 但事实并非如此。 (3认同)

dan*_*y74 34

这个答案适用于ES6.

代替:

describe('your describe block', () => {
Run Code Online (Sandbox Code Playgroud)

你要:

(condition ? describe : describe.skip)('your describe block', () => {
Run Code Online (Sandbox Code Playgroud)

如果条件为假,这有条件地跳过描述块中的所有测试.

或者,而不是:

it('your it block', () => {
Run Code Online (Sandbox Code Playgroud)

你要:

(condition ? it : it.skip)('your it block', () => {
Run Code Online (Sandbox Code Playgroud)

如果条件为假,这有条件地跳过一次测试.

  • 我得到你的建议,但你首先需要定义一个*contextual*这样的描述:`const contextualDescribe = shouldAvoidTests?describe.skip:describe`然后你可以使用它:`contextualDescribe('你的阻止',()=> {` (4认同)
  • @Ser为了获得单行,我使用了这样的东西:`(condition?describe:describe.skip)('你的描述块',()=> {` (3认同)

Ami*_*.io 32

我使用摩卡运行时跳过与您描述的相同的场景.它是来自文档的复制粘贴:

it('should only test in the correct environment', function() {
  if (/* check test environment */) return this.skip();

  // make assertions
});
Run Code Online (Sandbox Code Playgroud)

如您所见,它会根据环境跳过测试.我自己的条件是if(process.env.NODE_ENV === 'continuous-integration').

  • 这是一个比其他解决方案简单得多的解决方案.+1 (4认同)
  • 同意!也许可以通过提前归还成为一名班轮?就像:`if(/ * skipTestCondition * /)返回this.skip();`-编辑:Works:D (2认同)

Lou*_*uis 6

这取决于您希望以编程方式跳过测试.如果在运行任何测试代码之前可以确定跳过的条件,那么您可以根据条件调用itit.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!");
    });

});
Run Code Online (Sandbox Code Playgroud)

如果您要检查的条件只能在测试时确定,则会更复杂一些.如果您不想访问任何严格来说不是测试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!");
    });

});
Run Code Online (Sandbox Code Playgroud)

虽然我的第一个例子是将测试标记为正式跳过(也称为"待定"),但我刚才显示的方法将避免执行实际测试,但测试不会被标记为正式跳过.它们将被标记为已通过.如果您绝对想要跳过它们,我不知道是否有任何方法无法访问未正确说出测试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!");
    });

});
Run Code Online (Sandbox Code Playgroud)


lfe*_*445 6

跳过测试,使用describe.skipit.skip

describe('Array', function() {
  it.skip('#indexOf', function() {
    // ...
  });
});
Run Code Online (Sandbox Code Playgroud)

包括您可以使用的测试describe.onlyit.only

describe('Array', function() {
  it.only('#indexOf', function() {
    // ...
  });
});
Run Code Online (Sandbox Code Playgroud)

有关更多信息,访问https://mochajs.org/#inclusive-tests

  • 问题是如何仅在设置了某些环境变量(或在运行时可检测到的其他条件)时跳过测试 (2认同)

mar*_*tin 5

我不确定这是否符合“程序化跳过”的条件,但为了有选择地跳过我们 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"
}
Run Code Online (Sandbox Code Playgroud)


dcr*_*r24 5

我们可以编写一个漂亮的干净包装函数来有条件地运行测试,如下所示:

function ifConditionIt(title, test) {
  // Define your condition here
  return condition ? it(title, test) : it.skip(title, test);
}
Run Code Online (Sandbox Code Playgroud)

然后可以在您的测试中需要并使用它,如下所示:

ifConditionIt('Should be an awesome test', (done) => {
  // Test things
  done();
});
Run Code Online (Sandbox Code Playgroud)