2015-08-25 40 views
13

我有一些在PhantomJS中失败的测试,但没有其他浏览器。有条件地忽略Karma/Jasmine的个别测试

我希望这些测试在我的watch任务中与PhantomJS一起运行时被忽略(所以新的浏览器窗口不需要关注并且perf有点快),但是在我的标准测试任务和我的CI管道中,我想所有测试在Chrome,火狐等运行...

,我认为是一个文件命名约定一样foo.spec.dont-use-phantom.js和不包括在我的噶配置,但是这意味着我将不得不分开将单个测试失败归入自己的文件,将它们从逻辑describe块中分离出来,并让更多带有奇怪命名约定的文件通常会被吸引。

简而言之:

有没有一种方法,我可以延长茉莉花和/或因果报应,不知何故注释单独测试只能使用特定配置下运行?

回答

6

我可以与我分享我的经验。

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

I.e.

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

虽然这是一个有点冗长,这将节省您的时间的那种你正面临的情景。

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

9

最简单的解决方案,我看到的是覆盖全局的功能describeit使他们接受第三个可选参数,它必须是一个布尔值或返回一个布尔函数 - 告诉电流是否套房/规格应该执行。当重写时,我们应该检查这个第三个可选参数是否解析为true,如果是,那么我们称之为xdescribe/xit(或ddescribe/iit取决于Jasmine版本),这是Jasmine的方法来跳过suite/spec,而不是原始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 
    }); 

}); 

See a working example here

我也偶然发现this issue其中的想法是加入链方法.when()describeit,这与我上面描述的几乎相同。它看起来更好,但实施起来有点困难。

describe('foo', function() { 

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

}).when(something); 

如果你是第二种方法很感兴趣,我会很乐意与它一点点玩,尝试实施连锁.when()

更新:

茉莉花使用第三个参数为超时选项(see docs),所以我的代码示例替换该功能,这是不正常。我喜欢@milanlempera和@MarcoCI更好的回答,我的似乎有点hacky和不直观。我会尝试尽快更新我的解决方案,不要打破Jasmine默认功能的兼容性。

+0

太好了。我用它来禁止fdescribe并适合构建env。只需重写fdescribe和fit并抛出异常。 –

15

茉莉花支持挂起功能。

如果您在规范正文的任何​​地方调用函数挂起,无论预期如何,规范都将被标记为挂起。

您可以直接在测试中或在测试中调用的其他函数中调用挂起。

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

我认为这是最纯粹的解决方案。在测试结果中,您可以看到完成测试和跳过测试的次数。这是更多的信息反对条件替代测试机构。

+1

此方法不适用于量角器,因为规范将被标记为失败https://github.com/angular/protractor/issues/2454 – LuckyStarr

1

试试这个。我在我的项目中使用此解决方案。

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

这将不会在PhantomJS中运行这个特定的测试,但会在其他浏览器中运行它。