これを行う良い方法はありますか?コンテンツスクリプトとしてウェブサイトとやり取りし、localstorageを使用してデータを保存する拡張機能を書いています。この動作をテストするために使用できるツール、フレームワークなどはありますか?JavaScriptをテストするための一般的なツールがいくつかあることに気づきましたが、それらは拡張機能をテストするのに十分なパワーですか?単体テストが最も重要ですが、他のタイプのテスト(統合テストなど)にも興味があります。
これを行う良い方法はありますか?コンテンツスクリプトとしてウェブサイトとやり取りし、localstorageを使用してデータを保存する拡張機能を書いています。この動作をテストするために使用できるツール、フレームワークなどはありますか?JavaScriptをテストするための一般的なツールがいくつかあることに気づきましたが、それらは拡張機能をテストするのに十分なパワーですか?単体テストが最も重要ですが、他のタイプのテスト(統合テストなど)にも興味があります。
回答:
はい、既存のフレームワークはかなり便利です。
最近、すべてのテストをアプリケーションに埋め込まれた「テスト」ページに配置しましたが、物理的に入力しないとアクセスできません。
たとえば、私は下にアクセスできるページ内のすべてのテストを持っているでしょう chrome-extension://asdasdasdasdad/unittests.html
テストは、 localStorage
などに。コンテンツスクリプトにアクセスするには、理論的にはテストページに埋め込まれたIFRAMEを使用してテストできますが、これらはより統合レベルのテストです。単体テストでは、実際のページから抽象化して、 localStorageへのアクセスと同様に、それらに依存しないでください。
ページを直接テストする場合は、拡張機能を調整して新しいタブを開くことができます(chrome.tab.create({"url": "someurl"})。新しいタブごとに、コンテンツスクリプトを実行する必要があります。あなたのコードがそれがすべきことをしたことをチェックするためのあなたのテストフレームワーク
私が思いついたいくつかのChromeの拡張機能に取り組んでsinon-chrome
使用してユニット・テストを実行することを可能にするプロジェクトmocha
、nodejs
およびphantomjs
。
基本的に、それはすべてのシノンモックを作成します chrome.*
APIの、事前定義されたjson応答を配置できます。
次に、ノードのvm.runInNewContext
背景ページを使用してスクリプトをロードし、phantomjs
レンダリングポップアップ/オプションページ。
そして最後に、必要な引数を使用してChrome APIが呼び出されたと主張します。
例
を見てみましょう:ボタンバッジに開いているタブの数を表示するシンプルなクロム拡張があるとします。
背景ページ:
chrome.tabs.query({}, function(tabs) {
chrome.browserAction.setBadgeText({text: String(tabs.length)});
});
テストするには、次のものが必要です。
chrome.tabs.query
2つのタブなど、定義済みの応答を返す。chrome.*
APIをいくつかの環境にコードスニペットは次のとおりです。
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'});
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
を変更してコードを実行するだけです。
Chromeの既存のツールについて:
Chrome開発者ツールには、ローカルストレージ用のリソースのセクションがあります。
開発者ツール>リソース>ローカルストレージ
そこでlocalstorageの変更を確認してください。
console.profileを使用してパフォーマンスをテストし、ランタイムコールスタックを監視できます。
バックグラウンドページ/スクリプトなしでメッセージパッシングなしでコンテンツスクリプトとローカルストレージを一緒に使用している場合、ローカルストレージにはそのサイトからのみアクセスできます。したがって、これらのページをテストするには、これらのタブにテストスクリプトを挿入する必要があります。
Seleniumは拡張機能の「表示」を制御できないため、Selenium Webドライバーを使用して、プレインストールされた拡張機能とpyautoguiがインストールされた新しいブラウザーインスタンスを開始できることがわかりました。クリックした後、スクリーンショットを作成して「期待される」スクリーンショットと比較し、95%の類似性を期待できます(異なるブラウザーでは数ピクセルへのマークアップの移動が許容されるため)。
以前の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リリースを含めました。もちろん、プロダクション用の拡張機能をビルドするときは、テストケースも省略します。
コマンドラインでテストを実行する方法は確認していません。これは、自動展開ツールには便利です。