プログラムでモカのテストをスキップする方法は?


142

特定のテストがCI環境で常に失敗するコードがあります。環境条件によって無効にしたい。

ランタイム実行中にプログラムでモカのテストをスキップする方法は?


3
プログラムでテストをスキップすることはthis.skip()mochajs.org /#inclusive- testsと@z​​atzikyの以下の回答で説明されています。モカv3以降では、残りの回答は廃止されます
Patrick、

1
describe.skip( 'description'、()=> {})/ describe.only( 'description'、()=> {})/ it.skip( 'description'、()=> {})/ it。 only( 'description'、()=> {})
Jun711

受け入れられた答えはありますか?
Paul Rooney

回答:


168

記述またはブロックの前にxを配置するか、.skip後にa を配置することで、テストをスキップできます。

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,
         }
    }
}

8
ソリューションでの2回目の試行は機能しません。実行の順序が思ったとおりではないためです。ときにbeforeEach呼び出しが実行は、モカは記録のために無名関数(「フック」)未来の際、使用describeコール実行、モカはすぐにそれに渡された匿名関数を実行します。したがって、if (runTest)実行されるまでに、beforeEach フックは実行されません。
Louis

22
この回答には27の賛成票がありますか?プログラムでテストをスキップすることについての質問なので、「。skip」または「.only」を追加しても役に立ちません。次に、他の答えがそれを行う方法を教えているという事実にもかかわらず、OPがやりたいことを行うことはできないと明確に述べています。
Graeme Perrow

3
機能しません。質問に対する回答ではありません。代わりに@Gajusの応答を参照してください
NorTicUs

1
この回答には、ここでは質問されなかった別の質問のメリットがあります。ここで何かを変更する力はありません。this.skip()の回答を参照してください。
Andrew Martinez

3
これは質問の答えにはなりません
Ingo Renner

109

プログラムでテストをスキップする、文書化されていない方法があります。

// 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

これはhttps://github.com/mochajs/mocha/issues/1901で説明されています


13
読者は、これにより全体describeがスキップされたとマークされる(つまり、のすべてのテストdescribeがスキップされる)ことを知りたいと思うかもしれません。
Louis

Mochaの「保留中のテスト」のドキュメント:mochajs.org/#pending-tests
lasec0203

describe.skip( 'description'、()=> {})/ describe.only( 'description'、()=> {})/ it.skip( 'description'、()=> {})/ it。 only( 'description'、()=> {})
Jun711

私はなぜこの種の答えが賛成されているのか理解していません。これはハックです。
chenop

2
実際のドキュメントmochajs.org/#inclusive-tests、それは決してハックではありませんが、ランタイム設定に基づいていくつかのテストを除外する正しい方法です。つまり、元の質問の質問に正確に答えます。ありがとう@xavdid
WowPress.host

41

この回答はES6では機能します。

の代わりに:

describe('your describe block', () => {

あなたが欲しい:

(condition ? describe : describe.skip)('your describe block', () => {

これは、条件が偽の場合、条件付きで記述ブロック内のすべてのテストをスキップします。

または、代わりに:

it('your it block', () => {

あなたが欲しい:

(condition ? it : it.skip)('your it block', () => {

これは、条件がfalseの場合、条件付きで1つのテストをスキップします。


4
私はあなたが提案しているものを手に入れますが、最初にこのようなコンテキスト記述を定義する必要があります。 const contextualDescribe = shouldAvoidTests ? describe.skip : describe それからそれを使うことができます: contextualDescribe('your it block', () => {
Ser

3
@Ser 1行に取得するには、私はこのようなものを使用:(condition ? describe : describe.skip)('your describe block', () => {
joshden

これを非同期にする方法は?非同期操作であるredisフラグに基づいてスキップ条件を調べる必要があります(機能フラグはredisに格納します)。
Patrick Finnigan、

しばらく前にこのような必要があったので、非同期コールバックの完了後に呼び出された関数にすべてのモカの
要素を

以前はこのテクニックを使用していましたが、今では失敗します。単純に書いてみてください(it)('my test', () => {})
cyrf

33

あなたが説明しているのと同じシナリオで、Mochaからのランタイムスキップを使用します。それはドキュメントからのコピーペーストです:

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')です。


2
同意しました!たぶん早期復帰でワンライナーになれるのでしょうか?Like:if (/* skipTestCondition */) return this.skip();
-edit

12

テストをスキップするには、describe.skipまたはを使用しますit.skip

describe('Array', function() {
  it.skip('#indexOf', function() {
    // ...
  });
});

使用できるテストを含めるdescribe.onlyか、it.only


describe('Array', function() {
  it.only('#indexOf', function() {
    // ...
  });
});

詳しくはhttps://mochajs.org/#inclusive-testsをご覧ください


6

プログラムでテストをスキップする方法によって異なります。テストコードを実行する前にスキップの条件を決定できる場合は、条件に基づいて、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!");
    });

});

3

これが「プログラムによるスキップ」に該当するかどうかはわかりませんが、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"
}

これは、テストをスキップする方法の1つです。小さな例が本当に役立つでしょう。しかし、私はあなたが共有したリンクが最初に例があることに間違いなく同意します。@martin
クリシュナプラビン

2

私のパッケージmocha-assumeを使用して、プログラムでテストをスキップできますが、テストの外部からのみです。次のように使用します。

assuming(myAssumption).it("does someting nice", () => {});

Mocha-assumeはがの場合にのみテストを実行し、そうでない場合myAssumptiontrue(を使用して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、あなたは、多くの場合、このような偽陽性を回避することができます。


これは本当にクールで、プロジェクトが放棄されているようで悲しいです...
ビクターシュレーダー

@VictorSchröderええと、誰も使っていないような印象を受けました。時間があれば、今後数週間でそれを改善することを検討するかもしれません。githubで問題を開いて、何を見たいか教えていただけますか?
David Tanzer

私はまだそれを使っていません、@ David Tanzer、私はあなたのアイデアが本当にクールだと思いました。私は自分でテストの準備と条件付きスキップをかなり行っていると思います。この種のインターフェースはもっと読みやすくなっています。私はまだ試してみる必要がありますが、いくつかの仮定をチェーンし、仮定として非同期関数をサポートできるようにするのはクールだと思います。多分これはすでにサポートされているので、チェックしていません。
VictorSchröder

1
ただし、この回答の2番目の例には問題があります。beforeAllフックは、すべてのテストが収集される前に実行することが保証されていません。実際には、後で実行される可能性が非常に高いですが、この場合、assuming(someAssumption)は、最初の(未定義の)値を既に受け取ってはずです。目的の効果を実現するには、その部分を関数でラップすることも必要です。
VictorSchröder

2

次のように、条件付きでテストを実行するためのすっきりとしたクリーンなラッパー関数を作成できます。

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();
});

これは、ここで紹介する最もエレガントなソリューションだと思います。これは、より複雑なロジックを実行するために簡単に拡張でき、この方法でスキップされたテストがテストレポートでスキップされたものとしてマークされるという追加のボーナスがあります
Joshua Evans

0

テストの説明に「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をキー入力の対象に設定し、その値を使用して、テストをスキップまたは実行できます。(FYI NodeJSのprocess.envのドキュメントはこちら:https ://nodejs.org/api/process.html#process_process_env )

私はこのソリューションの最初の部分を完全に信用しません、私は答えを見つけてテストしました、そしてこのリソースを通して単純な条件に基づいてテストをスキップするために完全に機能しました:https : //github.com/mochajs/mocha/issues / 591

お役に立てれば!:)


0

これは実際にはモカの機能を使用しているのではなく、微調整を行って希望する動作を実現しています。

分度器モカテストで後続の「it's」をスキップしたかったのですが、1つの「it」が失敗しました。これは、ジャーニーテストの1つのステップが失敗すると、残りが失敗することはほぼ確実であり、ブラウザを使用している場合、要素がページに表示されるのを待つなど、ビルドサーバーに時間がかかる可能性があるためです。

標準のモカテスト(分度器ではない)を実行するだけの場合、グローバルなbeforeEachフックとafterEachフックを使用して、次のようにテストの親(説明)に 'skipSubsequent'フラグを付加することでこれを実現できます。

    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()に置き換えてしまいます。これはおそらく、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'
    }
});


-2

@danielstjulesがここに答えたようにでたように、テストをスキップする方法があります。このトピックの@作成者は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();
        }

        ...

-2

しないでください。環境全体で一貫して機能しないテストは、ビルドインフラストラクチャによってそのように認識される必要があります。また、CIビルドでローカルとは異なる数のテストを実行すると、混乱を招く可能性があります。

また、それは再現性を台無しにします。サーバーとローカルで異なるテストを実行すると、テストがdevで失敗し、CIで合格するか、またはその逆になります。強制機能はなく、失敗したビルドを迅速かつ正確に修正する方法はありません。

条件付きで実行するテストではなく、環境間でテストをオフにする必要がある場合は、テストにタグを付け、フィルターを使用して、特定のビルドターゲットで機能しないテストを排除します。そうすれば、誰もが何が起こっているのかを理解し、期待を和らげることができます。また、テストフレームワークに不整合があることを全員に知らせます。また、誰かが適切に実行するためのソリューションを持っている可能性があります。テストをミュートするだけでは、問題があることさえ知らないかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.