web-dev-qa-db-ja.com

Karma / Jasmineの個々のテストを条件付きで無視する

PhantomJSでは失敗するが、他のブラウザーでは失敗しないテストがいくつかあります。

監視タスクでPhantomJSを使用してこれらのテストを無視したいので(新しいブラウザーウィンドウがフォーカスを取得せず、perfが少し高速になります)、標準のテストタスクとCIパイプラインでは、allChrome、Firefoxなどで実行するテスト...

私はfoo.spec.dont-use-phantom.jsのようなファイル命名規則を検討し、Karma構成内のファイル命名規則を除外しましたが、これは、論理的なdescribeから分離して、失敗した個々のテストを個別のファイルに分離する必要があることを意味しますブロックし、奇妙な命名規則を持つより多くのファイルを持っていることは一般的に悪いでしょう。

要するに:

JasmineやKarmaを拡張し、何らかの形でannotate特定の構成でのみ実行する個々のテストを拡張する方法はありますか?

21
Zach Lysobey

これと私の経験を共有できます。

私たちの環境では、さまざまなブラウザーとさまざまなテクノロジーで実行されるいくつかのテストがあります。すべてのプラットフォームとブラウザで常に同じスイートを実行するために、カルマ(helper.js)に読み込まれたヘルパーファイルがあり、いくつかの機能検出関数がグローバルに読み込まれています。

つまり.

function isFullScreenSupported(){
  // run some feature detection code here
}

これにも Modernizr を使用できます。

テストでは、次のようにif/elseブロックで物事をラップします。

it('should work with fullscreen', function(){
  if(isFullScreenSupported()){
    // run the test
  }
  // don't do anything otherwise
});

または非同期テストの場合

it('should work with fullscreen', function(done){
  if(isFullScreenSupported()){
    // run the test
    ...
    done();
  } else {
    done();
  }
});

少し冗長ですが、直面しているシナリオの時間を節約できます。

場合によっては、ユーザーエージェントスニッフィングを使用して、特定のブラウザーの種類またはバージョンを検出できます。これは悪い習慣ですが、実際には他の方法がない場合もあります。

7
MarcoL

Jasmineはpending()関数をサポートしています。

仕様本体のどこかでpending()を呼び出すと、期待に関係なく、仕様は保留中としてマークされます。

pending()をテストで直接呼び出すか、テストから呼び出される他の関数で呼び出すことができます。

function skipIfCondition() {
  pending();
}

function someSkipCheck() {
  return true;
}

describe("test", function() {
  it("call pending directly by condition", function() {
    if (someSkipCheck()) {
      pending();
    }

    expect(1).toBe(2);
  });

  it("call conditionally skip function", function() {
    skipIfCondition();

    expect(1).toBe(3);
  });

  it("is executed", function() {
    expect(1).toBe(1);
  });

});

ここでの作業例: http://plnkr.co/edit/JZtAKALK9wi5PdIkbw8r?p=preview

私はそれが最も純粋な解決策だと思います。テスト結果では、終了したテストとスキップされたテストの数を確認できます。

27
milanlempera

私が見る最も簡単な解決策は、グローバル関数describeおよびitをオーバーライドして、3番目のオプション引数を受け入れるようにすることです。 suite/specを実行する必要があります。オーバーライドするとき、この3番目のオプションの引数がtrueに解決するかどうかを確認する必要があり、解決する場合は、xdescribe/xit(またはddescribe/iitを呼び出します。 Jasmineのバージョンによって異なります)。これは、元のdescribe/itの代わりに、スイート/仕様をスキップするJasmineの方法です。このブロックはテストの前に実行する必要がありますが、ジャスミンがページに含まれた後です。 Karmaでは、このコードをファイルに移動し、_karma.conf.js_のテストファイルの前に含めるだけです。コードは次のとおりです。

_(function (global) {

  // save references to original methods
  var _super = {
    describe: global.describe,
    it: global.it
  };

  // override, take third optional "disable"
  global.describe = function (name, fn, disable) {
    var disabled = disable;
    if (typeof disable === 'function') {
      disabled = disable();
    }

    // if should be disabled - call "xdescribe" (or "ddescribe")
    if (disable) {
      return global.xdescribe.apply(this, arguments);
    }

    // otherwise call original "describe"
    return _super.describe.apply(this, arguments);
  };

  // override, take third optional "disable"
  global.it = function (name, fn, disable) {
    var disabled = disable;
    if (typeof disable === 'function') {
      disabled = disable();
    }

    // if should be disabled - call "xit" (or "iit")
    if (disable) {
      return global.xit.apply(this, arguments);
    }

    // otherwise call original "it"
    return _super.it.apply(this, arguments);
  };

}(window));
_

そして使用例:

_describe('foo', function () {

  it('should foo 1 ', function () {
    expect(true).toBe(true);
  });

  it('should foo 2', function () {
    expect(true).toBe(true);
  }); 

}, true); // disable suite

describe('bar', function () {

  it('should bar 1 ', function () {
    expect(true).toBe(true);
  });

  it('should bar 2', function () {
    expect(true).toBe(true);
  }, function () {
    return true; // disable spec
  });

}); 
_

実際の例を参照

私はまた、つまずきました この問題 アイデアは、チェーンメソッド.when()describeおよびitに追加することでした。上記と同じです。見た目は良くなりますが、実装が少し難しくなります。

_describe('foo', function () {

  it('bar', function () {
    // ...
  }).when(anything);      

}).when(something);
_

この2番目のアプローチに本当に興味がある場合は、もう少し試して、チェーン.when()を実装してみてください。

更新:

Jasmineは3番目の引数をタイムアウトオプションとして使用します( docsを参照 )。したがって、私のコードサンプルはこの機能を置き換えていますが、これは大丈夫ではありません。私は@milanlemperaが好きで、@ MarcoCIの回答はより良く、私のものはちょっとハッキーで直感的ではないようです。 Jasmineのデフォルト機能との互換性を損なわないように、すぐにソリューションを更新しようとします。

10

これを試して。私は自分のプロジェクトでこのソリューションを使用しています。

it('should do something', function () {
    if (!/PhantomJS/.test(window.navigator.userAgent)) {
        expect(true).to.be.true;
    }
});

これは、PhantomJSでこの特定のテストを実行しませんが、他のブラウザーで実行します。

1
Marcin Rapacz