Chrome拡張機能をテストする方法は?


154

これを行う良い方法はありますか?コンテンツスクリプトとしてウェブサイトとやり取りし、localstorageを使用してデータを保存する拡張機能を書いています。この動作をテストするために使用できるツール、フレームワークなどはありますか?JavaScriptをテストするための一般的なツールがいくつかあることに気づきましたが、それらは拡張機能をテストするのに十分なパワーですか?単体テストが最も重要ですが、他のタイプのテスト(統合テストなど)にも興味があります。


8
Chromeだけでなく、すべてのブラウザーにわたるブラウザー拡張機能の単体テストと統合テストに対処する標準的な回答を書いたところです。「ブラウザ拡張機能のテスト」への回答をご覧ください。
Rob W

回答:


111

はい、既存のフレームワークはかなり便利です。

最近、すべてのテストをアプリケーションに埋め込まれた「テスト」ページに配置しましたが、物理的に入力しないとアクセスできません。

たとえば、私は下にアクセスできるページ内のすべてのテストを持っているでしょう chrome-extension://asdasdasdasdad/unittests.html

テストは、 localStorageなどに。コンテンツスクリプトにアクセスするには、理論的にはテストページに埋め込まれたIFRAMEを使用してテストできますが、これらはより統合レベルのテストです。単体テストでは、実際のページから抽象化して、 localStorageへのアクセスと同様に、それらに依存しないでください。

ページを直接テストする場合は、拡張機能を調整して新しいタブを開くことができます(chrome.tab.create({"url": "someurl"})。新しいタブごとに、コンテンツスクリプトを実行する必要があります。あなたのコードがそれがすべきことをしたことをチェックするためのあなたのテストフレームワーク

フレームワークに関しては、JsUnitまたは最新のJasmineが正常に動作するはずです。


1
そうです、実際のページのテストは単体テストの対象にはなりません。私の質問をもっと広範にすべきだった。しかし、それは私がテストしたいものです、特にウェブサイトのhtml構造はいつでも変更される可能性があるためです。質問を変更しました。
swampsjohn

1
単体テストページのIFrameを使ってテストします。コンテンツスクリプトは引き続き起動するはずです(iFrameでスクリプトを実行できるようにした場合)
Kinlan

3
プロキシサンプル拡張機能には、必要なChrome APIの一部を模擬するいくつかのテストがあります:code.google.com/chrome/extensions/samples.html#chrome.proxy ..また、同僚のBorisはQUnitをテストに使用しました彼の「モデル」層:github.com/borismus/Question-Monitor-for-Stack-Exchange/tree/...
ポール・アイリッシュ

63

私が思いついたいくつかのChromeの拡張機能に取り組んでsinon-chrome使用してユニット・テストを実行することを可能にするプロジェクトmochanodejsおよびphantomjs

基本的に、それはすべてのシノンモックを作成します chrome.* APIの、事前定義されたjson応答を配置できます。

次に、ノードのvm.runInNewContext背景ページを使用してスクリプトをロードし、phantomjsレンダリングポップアップ/オプションページ。

そして最後に、必要な引数を使用してChrome APIが呼び出されたと主張します。


を見てみましょう:ボタンバッジに開いているタブの数を表示するシンプルなクロム拡張があるとします。

背景ページ:

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

テストするには、次のものが必要です。

  1. モック chrome.tabs.query2つのタブなど、定義済みの応答を返す。
  2. 私たちの嘲笑を注入する chrome.* APIをいくつかの環境に
  3. この環境で拡張コードを実行する
  4. ボタンのバッジが「2」に等しいと主張する

コードスニペットは次のとおりです。

const vm = require('vm');
const fs = require('fs');
const 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
const context = {
  chrome: chrome
};

// 3. run our extension code in this environment
const 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)

ここで完全な例を見つけることができます

さらに、sinon-chromeは、定義済みの応答で任意のchromeイベントをトリガーできます。

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

例のリンクは機能していないようです。更新していただけますか?
2015

1
例へのリンクを更新しました。また、sinon-chromeはgithub.com/acvetkovに移動され、すぐに新しい例が登場します
vitalets

3

sinon.jsうまく機能しているように見えますが、プレーンジャスミンを使用して、必要なChromeコールバックを模擬することもできます。例:

モック

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

テスト

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を変更してコードを実行するだけです。


2

Chromeの既存のツールについて:

  1. Chrome開発者ツールには、ローカルストレージ用のリソースのセクションがあります。

    開発者ツール>リソース>ローカルストレージ

    そこでlocalstorageの変更を確認してください。

  2. console.profileを使用してパフォーマンスをテストし、ランタイムコールスタックを監視できます。

  3. fileSystemの場合次のURLを使用して、ファイルがアップロードされているかどうかを確認できます:filesystem:chrome-extension:/// temporary /

バックグラウンドページ/スクリプトなしでメッセージパッシングなしでコンテンツスクリプトとローカルストレージを一緒に使用している場合、ローカルストレージにはそのサイトからのみアクセスできます。したがって、これらのページをテストするには、これらのタブにテストスクリプトを挿入する必要があります。


1
私にとってはうまくいきませんでしたが、それは私のJavaScriptでさらに進んでくれました。+1。
mobibob 2014

fileSystemの場合:filesystem:chrome-extension:// <yourextension-id> / temporary /
Ahmad

1

Seleniumは拡張機能の「表示」を制御できないため、Selenium Webドライバーを使用して、プレインストールされた拡張機能とpyautoguiがインストールされた新しいブラウザーインスタンスを開始できることがわかりました。クリックした後、スクリーンショットを作成して「期待される」スクリーンショットと比較し、95%の類似性を期待できます(異なるブラウザーでは数ピクセルへのマークアップの移動が許容されるため)。


0

以前の2つの答えを確認するために、JasmineはChrome拡張機能でうまく機能するようです。バージョン3.4.0を使用しています。

Jasmineスパイを使用して、さまざまなAPIのテストダブルを簡単に作成できます。独自にゼロから構築する必要はありません。例えば:

describe("Test suite", function() {

  it("Test case", function() {

    // Set up spies and fake data.
    spyOn(chrome.browserAction, "setPopup");
    spyOn(chrome.identity, "removeCachedAuthToken");
    fakeToken = "faketoken-faketoken-faketoken";
    fakeWindow = jasmine.createSpyObj("window", ["close"]);

    // Call the function under test.
    logout(fakeWindow, fakeToken);

    // Perform assertions.
    expect(chrome.browserAction.setPopup).toHaveBeenCalledWith({popup: ""});
    expect(chrome.identity.removeCachedAuthToken).toHaveBeenCalledWith({token: fakeToken});
    expect(fakeWindow.close.calls.count()).toEqual(1);

  });

});

それが役立つ場合、いくつかの詳細:

別の回答で述べたように、テストを実行するブラウザー拡張機能の一部としてHTMLページを作成しました。HTMLページには、Jasmineライブラリ、拡張機能のJavaScriptコード、およびテストスイートが含まれています。テストが自動的に実行され、結果がフォーマットされます。テストランナーや結果フォーマッターを構築する必要はありません。ただ、続くインストール手順を、およびHTMLを使用するテストランナーページを作成するために、そこを文書化し、同様のページにあなたのテストスイートが含まれています。

Jasmineフレームワークを別のホストから動的にフェッチできないと思うので、拡張機能にJasmineリリースを含めました。もちろん、プロダクション用の拡張機能をビルドするときは、テストケースも省略します。

コマンドラインでテストを実行する方法は確認していません。これは、自動展開ツールには便利です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.