2010-05-19 204 views
125

有沒有一個很好的方法來做到這一點?我正在編寫一個擴展,作爲內容腳本與網站交互,並使用localstorage保存數據。是否有任何工具,框架等可用於測試此行爲?我意識到有一些用於測試JavaScript的通用工具,但那些測試擴展的功能是否足夠?單元測試是最重要的,但我也對其他類型的測試(如集成測試)感興趣。如何測試Chrome擴展?

+7

我剛寫過一個規範的答案,它解決了所有*瀏覽器中瀏覽器擴展的單元測試和集成測試問題,而不僅僅是Chrome。請參閱[對「測試瀏覽器擴展」的答案](http://stackoverflow.com/a/17370531/938089)。 – 2013-06-28 21:52:06

回答

93

是,現有的框架是非常有用的..

在最近的過去,我已經把那個被嵌入到應用程序,但無法到達,除非身體類型「測試」頁面上我的所有測試。

舉例來說,我會在訪問一個頁面中的所有測試下chrome-extension://asdasdasdasdad/unittests.html

測試將有機會獲得localStorage等用於訪問內容的腳本,在理論上可以測試,通過測試頁的IFRAME嵌入但是,這些是更多的集成級別測試,單元測試會要求您將其從實際頁面抽象出來,以便您不依賴它們,同樣可以訪問localStorage。

如果您想要直接測試頁面,您可以編排您的擴展以打開新標籤(chrome.tab.create({「url」:「someurl」})。對於每個新標籤,您的內容腳本應該運行你可以使用你的測試框架來檢查你的代碼做了它應該做的

至於框架,JsUnit或更近Jasmine應該正常工作

+1

你是對的,測試真實頁面不屬於單元測試。我應該提出更廣泛的問題。但它仍然是我想測試的東西,尤其是因爲網站的html結構可能會隨時更改。我修改了這個問題。 – swampsjohn 2010-05-24 19:39:02

+1

我會通過單元測試頁面中的IFrame進行測試。內容腳本應該仍然會觸發(如果您啓用腳本以在iFrame中運行) – Kinlan 2010-05-24 19:55:44

+2

代理示例擴展有一些測試,它們只是模擬必需的Chrome API的各個部分:http://code.google。 com/chrome/extensions/samples.html#chrome.proxy ..同樣我們的同事Boris使用QUnit來測試他的「模型」層:https://github.com/borismus/Question-Monitor-for-Stack-Exchange/樹/主/測試 – 2012-01-17 20:27:32

2

關於在Chrome中已經存在的工具:。

  1. 在c hrome開發人員工具,有資源的部分用於本地存儲。

    開發工具>資源>本地存儲

    見的localStorage那裏的變化。

  2. 您可以使用console.profile來測試性能並監視運行時調用堆棧。

  3. 的文件系統,您可以使用此URL來檢查您的文件上傳,編輯或不: 文件系統:鉻擴展:///臨時/

如果您是使用內容腳本和本地存儲沒有後臺頁面/腳本和沒有消息傳遞的情況下,只能從該站點訪問本地存儲。 因此,要測試這些頁面,您必須在這些選項卡中插入測試腳本。

+1

沒有爲我工作,但它確實讓我進一步沿着我的JavaScript。 +1。 – mobibob 2014-04-20 02:24:18

+0

對於fileSystem您可以使用: 文件系統:chrome-extension:// /temporary/ – 2014-04-20 04:35:25

47

工作幾個擴展我想出了sinon-chrome項目,允許使用mocha,nodejsphantomjs運行單元測試。

Basicaly,它創建所有chrome.* api的sinon mocks,您可以在其中放置任何預定義的json響應。

接下來,使用節點的vm.runInNewContext作爲背景頁面,使用phantomjs作爲渲染彈出窗口/選項頁面加載腳本。

最後,你斷言chrome api被調用了所需的參數。

讓我們舉個例子:
假設我們有一個顯示在按鈕徽章打開的標籤數簡單的Chrome擴展程序。

背景頁:

chrome.tabs.query({}, function(tabs) { 
    chrome.browserAction.setBadgeText({text: String(tabs.length)}); 
}); 

爲了測試它,我們需要:

  1. 模擬chrome.tabs.query返回預定義的響應,例如兩個選項卡。 。
  2. 注入我們的嘲笑鉻* API到一些環境
  3. 運行我們的擴展代碼在這種環境下
  4. 斷言,胸章等於「2」

的代碼片段是以下幾點:

var vm = require('vm'); 
var fs = require('fs'); 
var chrome = require('sinon-chrome'); 

// 1. mock `chrome.tabs.query` to return predefined response 
chrome.tabs.query.yields([ 
    {id: 1, title: 'Tab 1'}, 
    {id: 2, title: 'Tab 2'} 
]); 

// 2. inject our mocked chrome.* api into some environment 
var context = { 
    chrome: chrome; 
}; 

// 3. run our extension code in this environment 
var code = fs.readFileSync('src/background.js'); 
vm.runInNewContext(code, context); 

// 4. assert that button badge equals to '2' 
sinon.assert.calledOnce(chrome.browserAction.setBadgeText); 
sinon.assert.calledWithMatch(chrome.browserAction.setBadgeText, { 
    text: "2" 
}); 

現在,我們可以把它包裝成摩卡的describe..it功能,從終端上運行

$ mocha 

background page 
    ✓ should display opened tabs count in button badge 

1 passing (98ms) 

你可以找到完整的例子here

此外,sinon-chrome允許以預定義的響應觸發任何chrome事件,例如,

chrome.tab.onCreated.trigger({url: 'http://google.com'}); 
+0

聽起來不錯 - 我一定會給它一個旋轉! – jakabadambalazs 2015-02-07 16:49:58

+0

這個例子的鏈接似乎已經死了 - 你能否更新它? – Raisen 2015-12-07 20:55:33

+0

更新了示例鏈接。此外,sinon-chrome現在已移至https://github.com/acvetkov,並且很快就會有新的例子 – vitalets 2015-12-10 14:13:58

0

雖然sinon.js似乎工作的偉大,你也可以只使用普通的茉莉花和嘲笑你需要安裝Chrome回調。例如:

Mock

chrome = { 
    runtime: { 
    onMessage : { 
     addListener : function() {} 
    } 
    } 
} 

Test

describe("JSGuardian", function() { 

    describe("BlockCache", function() { 

    beforeEach(function() { 
     this.blockCache = new BlockCache(); 
    }); 

    it("should recognize added urls", function() { 
     this.blockCache.add("http://some.url"); 
     expect(this.blockCache.allow("http://some.url")).toBe(false); 
    }); 
} // ... etc 

只需修改默認SpecRunner.html來運行代碼。