Bagaimana cara menguji ekstensi chrome?

154

Apakah ada cara yang baik untuk melakukan ini? Saya sedang menulis ekstensi yang berinteraksi dengan situs web sebagai skrip konten dan menyimpan data menggunakan penyimpanan lokal. Apakah ada alat, kerangka kerja, dll. Yang dapat saya gunakan untuk menguji perilaku ini? Saya menyadari ada beberapa alat umum untuk menguji javascript, tetapi apakah mereka cukup kuat untuk menguji ekstensi? Pengujian unit adalah yang paling penting, tetapi saya juga tertarik pada jenis pengujian lain (seperti pengujian integrasi).

swampsjohn
sumber
8
Saya baru saja menulis jawaban kanonik yang membahas pengujian unit dan pengujian integrasi untuk ekstensi browser di semua browser, bukan hanya Chrome. Lihat jawaban untuk "Menguji ekstensi peramban" .
Rob W

Jawaban:

111

Ya, kerangka kerja yang ada cukup berguna ..

Di masa lalu baru-baru ini, saya telah menempatkan semua tes saya pada halaman "tes" yang tertanam ke dalam aplikasi tetapi tidak dapat dijangkau kecuali diketik secara fisik.

Sebagai contoh, saya akan memiliki semua tes di halaman yang dapat diakses di chrome-extension://asdasdasdasdad/unittests.html

Tes akan memiliki akses ke localStoragedll. Untuk mengakses skrip konten, secara teori Anda dapat mengujinya melalui IFRAME yang tertanam di halaman pengujian Anda, namun ini adalah pengujian tingkat integrasi yang lebih, pengujian unit akan mengharuskan Anda untuk mengabstraksi yang jauh dari halaman nyata sehingga Anda jangan bergantung pada mereka, demikian juga dengan akses ke Penyimpanan lokal.

Jika Anda ingin menguji halaman secara langsung, Anda dapat mengatur ekstensi Anda untuk membuka tab baru (chrome.tab.create ({"url": "someurl"}). Untuk setiap tab baru, skrip konten Anda harus dijalankan dan Anda dapat menggunakan kerangka kerja pengujian Anda untuk memeriksa apakah kode Anda telah melakukan apa yang seharusnya dilakukan.

Adapun kerangka kerja, JsUnit atau Jasmine yang lebih baru harus bekerja dengan baik.

Kinlan
sumber
1
Anda benar, menguji halaman nyata tidak termasuk dalam pengujian unit. Saya seharusnya membuat pertanyaan saya lebih luas. Tapi itu masih sesuatu yang ingin saya uji, terutama karena struktur situs web html bisa berubah kapan saja. Saya telah memodifikasi pertanyaan.
swampsjohn
1
Saya akan menguji melalui IFrames di halaman unit test Anda. Skrip konten masih harus diaktifkan (jika Anda mengaktifkan skrip untuk berjalan di iFrame)
Kinlan
3
Ekstensi sampel proksi memiliki beberapa tes yang hanya mengecoh potongan-potongan API Chrome yang diperlukan: code.google.com/chrome/extensions/samples.html#chrome.proxy .. Juga kolega kami Boris menggunakan QUnit untuk pengujian lapisan "model" -nya
Paul Irish
63

Bekerja pada beberapa ekstensi chrome saya datang dengan sinon-chromeproyek yang memungkinkan untuk menjalankan tes unit menggunakan mocha, nodejsdan phantomjs.

Pada dasarnya, ini menciptakan sinon tiruan dari semua chrome.*API di mana Anda dapat menempatkan respons json yang telah ditentukan.

Selanjutnya, Anda memuat skrip Anda menggunakan simpul vm.runInNewContextuntuk halaman latar belakang dan phantomjsuntuk membuat halaman popup / opsi.

Dan akhirnya, Anda menegaskan bahwa api chrome dipanggil dengan argumen yang diperlukan.

Mari kita ambil contoh:
Asumsikan kita memiliki ekstensi krom sederhana yang menampilkan jumlah tab yang dibuka di lencana tombol.

halaman latar belakang:

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

Untuk mengujinya kita perlu:

  1. tiru chrome.tabs.queryuntuk mengembalikan respons yang telah ditentukan, misalnya dua tab.
  2. menyuntikkan chrome.*api mocked kami ke beberapa lingkungan
  3. jalankan kode ekstensi kami di lingkungan ini
  4. menegaskan bahwa lencana tombol sama dengan '2'

Cuplikan kode adalah sebagai berikut:

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

Sekarang kita bisa membungkusnya menjadi describe..itfungsi moka dan lari dari terminal:

$ mocha

background page
  ✓ should display opened tabs count in button badge

1 passing (98ms)

Anda dapat menemukan contoh lengkapnya di sini .

Selain itu, sinon-chrome memungkinkan untuk memicu acara chrome dengan respons yang telah ditentukan, misalnya

chrome.tab.onCreated.trigger({url: 'http://google.com'});
vitalet
sumber
Tautan untuk contoh ini tampaknya sudah mati - dapatkah Anda memperbaruinya?
Raisen
1
Tautan yang diperbarui ke contoh. Juga sinon-chrome sekarang dipindahkan ke github.com/acvetkov dan akan segera ada contoh baru
vitalet
3

Meskipun sinon.jstampaknya bekerja dengan baik, Anda juga bisa menggunakan Jasmine biasa dan mengejek panggilan balik Chrome yang Anda butuhkan. Contoh:

Mengejek

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

Uji

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

Cukup modifikasi default SpecRunner.htmluntuk menjalankan kode Anda.

serv-inc
sumber
2

Tentang alat yang sudah ada di Chrome:

  1. Di alat pengembang chrome, ada bagian untuk Sumber Daya Untuk penyimpanan lokal.

    Alat Pengembang> Sumber Daya> Penyimpanan Lokal

    Lihat perubahan penyimpanan lokal di sana.

  2. Anda dapat menggunakan console.profile untuk menguji kinerja dan menonton stack time run time.

  3. untuk fileSystem Anda dapat menggunakan URL ini untuk memeriksa apakah file Anda di-upload atau tidak: filesystem: chrome-extension: /// temporary /

Jika Anda menggunakan skrip konten dan penyimpanan lokal bersama tanpa halaman latar belakang / skrip dan tanpa pesan, penyimpanan lokal akan dapat diakses dari situs itu saja. Jadi, untuk menguji halaman-halaman itu, Anda harus menyuntikkan skrip pengujian Anda di tab tersebut.

Nafis Ahmad
sumber
1
Tidak bekerja untuk saya, tapi itu membuat saya lebih lanjut dalam javascript saya. +1 untuk itu.
mobibob
Untuk fileSystem Anda dapat menggunakan: filesystem: chrome-extension: // <yourextension-id> / temporary /
Nafis Ahmad
1

Saya menemukan bahwa saya dapat menggunakan driver web Selenium untuk memulai contoh browser baru dengan ekstensi yang sudah diinstal sebelumnya dan pyautogui untuk klik - karena Selenium tidak dapat mendorong "tampilan" ekstensi. Setelah klik, Anda dapat membuat tangkapan layar dan membandingkannya dengan yang 'diharapkan', mengharapkan 95% kemiripan (karena pada browser yang berbeda itu adalah gerakan markup yang dapat diterima hingga beberapa piksel).

Vitaly Zdanevich
sumber
0

Untuk mengonfirmasi beberapa jawaban sebelumnya, Jasmine tampaknya bekerja dengan baik dengan ekstensi Chrome. Saya menggunakan versi 3.4.0.

Anda dapat menggunakan mata - mata Jasmine untuk dengan mudah membuat tes ganda untuk berbagai API. Tidak perlu membuat sendiri dari awal. Sebagai contoh:

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

  });

});

Beberapa detail lebih lanjut, jika itu membantu:

Seperti disebutkan dalam jawaban lain, saya membuat halaman HTML sebagai bagian dari ekstensi browser saya yang menjalankan tes saya. Halaman HTML termasuk perpustakaan Jasmine, ditambah kode JavaScript ekstensi saya, ditambah suite pengujian saya. Tes dijalankan secara otomatis dan hasilnya diformat untuk Anda. Tidak perlu membuat pelari uji atau formatter hasil. Cukup ikuti instruksi instalasi , dan gunakan HTML yang didokumentasikan di sana untuk membuat halaman test runner Anda, dan sertakan suite pengujian Anda di halaman tersebut juga.

Saya tidak berpikir Anda bisa mengambil kerangka Jasmine secara dinamis dari host lain, jadi saya hanya memasukkan rilis Jasmine dalam ekstensi saya. Saya akan menghilangkannya dan juga kasus pengujian saya ketika saya membangun ekstensi untuk produksi, tentu saja.

Saya belum melihat cara menjalankan tes di baris perintah. Itu akan berguna untuk alat penyebaran otomatis.

Jon A
sumber