2015-08-25 68 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中運行這個特定的測試,但會在其他瀏覽器中運行它。