有条件地忽略Karma/Jasmine的个别测试

Zac*_*bey 21 jasmine karma-runner karma-jasmine

我有一些测试在PhantomJS中失败但在其他浏览器中失败.

我希望在我的监视任务中使用PhantomJS时忽略这些测试(因此新的浏览器窗口不需要关注并且perf更快一点),但在我的标准测试任务和我的CI管道中,我想要所有的测试在Chrome,Firefox等中运行...

我已经考虑了一个文件命名约定,比如foo.spec.dont-use-phantom.js我的Karma配置中的那些,但是这意味着我必须将失败的各个测试分离到他们自己的文件中,将它们与逻辑describe块分开并拥有更多文件奇怪的命名约定通常会很糟糕.

简而言之:

有没有办法可以扩展Jasmine和/或Karma并以某种方式注释单个测试只能运行某些配置?

mil*_*era 27

Jasmine支持待定功能.

如果您在规范体中的任何地方调用函数挂起,则无论期望如何,规范都将标记为挂起.

您可以直接在测试中调用pending,也可以在test中调用的其他函数中调用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);
  });

});
Run Code Online (Sandbox Code Playgroud)

这里的工作示例:http://plnkr.co/edit/JZtAKALK9wi5PdIkbw8r?p = preview

我认为这是最纯粹的解决方案.在测试结果中,您可以看到完成和跳过测试的计数.它通过条件对替代测试体提供更多信息.

  • 这种方法不适用于量角器,因为规范将被标记为失败https://github.com/angular/protractor/issues/2454 (3认同)

Mic*_*nov 10

最简单的解决方案,我看到的是覆盖全局的功能describe,并it让他们接受第三个可选参数,它必须是一个布尔值或返回一个布尔函数-说当前的套房/规格是否应该执行.当重写时,我们应该检查这第三个可选参数是否解析true,如果是,那么我们调用xdescribe/ xit(或ddescribe/ iit取决于Jasmine版本),这是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));
Run Code Online (Sandbox Code Playgroud)

用法示例:

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

}); 
Run Code Online (Sandbox Code Playgroud)

在这里查看一个工作示例

我也偶然发现了这个问题,其中的想法是.when()describe和添加链式方法it,这与我上面描述的几乎相同.它可能看起来更好但实现起来有点困难.

describe('foo', function () {

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

}).when(something);
Run Code Online (Sandbox Code Playgroud)

如果你真的对第二种方法感兴趣,我会很乐意再多玩一下并尝试实现链.when().

更新:

Jasmine使用第三个参数作为超时选项(请参阅docs),因此我的代码示例正在替换此功能,这是不行的.我更喜欢@milanlempera和@MarcoCI更好的答案,我觉得有点hacky而且不直观.我会尽快更新我的解决方案,以免破坏与Jasmine默认功能的兼容性.


Mar*_*coL 7

我可以分享我的经验.

在我们的环境中,我们有几个测试运行不同的浏览器和不同的技术.为了在所有平台和浏览器上始终运行相同的套件,我们在karma(helper.js)中加载了一个辅助文件,其中一些功能检测功能全局加载.

function isFullScreenSupported(){
  // run some feature detection code here
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用Modernizr.

在我们的测试中,然后我们将if/else块包装在如下的块中:

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

或者进行异步测试

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

虽然它有点冗长,但它可以为您所面临的场景节省时间.

在某些情况下,您可以使用用户代理嗅探来检测特定的浏览器类型或版本 - 我知道这是不好的做法,但有时实际上没有其他办法.