Come testare le estensioni di Chrome?


154

C'è un buon modo per farlo? Sto scrivendo un'estensione che interagisce con un sito Web come uno script di contenuto e salva i dati utilizzando localstorage. Esistono strumenti, framework, ecc. Che posso utilizzare per testare questo comportamento? Mi rendo conto che ci sono alcuni strumenti generici per testare javascript, ma sono sufficientemente potenti per testare un'estensione? Il test unitario è molto importante, ma sono anche interessato ad altri tipi di test (come i test di integrazione).


8
Ho appena scritto una risposta canonica che affronta i test unitari e i test di integrazione per le estensioni del browser in tutti i browser, non solo Chrome. Vedi la risposta a "Test delle estensioni del browser" .
Rob W,

Risposte:


111

Sì, i framework esistenti sono piuttosto utili ..

Nel recente passato, ho inserito tutti i miei test in una pagina di "test" incorporata nell'applicazione ma non raggiungibile se non digitata fisicamente.

Ad esempio, avrei tutti i test in una pagina accessibile sotto chrome-extension://asdasdasdasdad/unittests.html

I test avrebbero accesso a localStorageecc. Per accedere agli script dei contenuti, in teoria potresti testare che attraverso IFRAME incorporati nella tua pagina di test, tuttavia questi sono più test a livello di integrazione, i test unitari ti richiederebbero di estrarre questo dalle pagine reali in modo che tu non dipendere da loro, allo stesso modo con l'accesso a localStorage.

Se vuoi testare direttamente le pagine, puoi orchestrare la tua estensione per aprire nuove schede (chrome.tab.create ({"url": "someurl"}). Per ognuna delle nuove schede il tuo script di contenuto dovrebbe essere eseguito e puoi usare il framework di test per verificare che il codice abbia fatto ciò che dovrebbe fare.

Per quanto riguarda i framework, JsUnit o il più recente Jasmine dovrebbero funzionare bene.


1
Hai ragione, testare pagine reali non rientra nel test unitario. Avrei dovuto ampliare la mia domanda. Ma è ancora qualcosa che vorrei testare, soprattutto perché la struttura html del sito Web potrebbe cambiare in qualsiasi momento. Ho modificato la domanda.
Swampsjohn,

1
Verificherei ancora tramite IFrame nella pagina di test dell'unità. Gli script di contenuto devono comunque essere
attivati

3
L'estensione di esempio proxy ha alcuni test che deridono solo le parti delle API di Chrome necessarie: code.google.com/chrome/extensions/samples.html#chrome.proxy .. Anche il nostro collega Boris ha usato QUnit per i test il suo livello "modello": github.com/borismus/Question-Monitor-for-Stack-Exchange/tree/…
Paul Irish

63

Lavorando su diverse estensioni di Chrome ho ideato un sinon-chromeprogetto che consente di eseguire unit test usando mocha, nodejse phantomjs.

Fondamentalmente, crea simulazioni sinon di tutte le chrome.*API in cui è possibile inserire qualsiasi risposta json predefinita.

Successivamente, carichi gli script usando il nodo vm.runInNewContextper la pagina di sfondo e phantomjsper la pagina popup / opzioni di rendering.

E infine, affermi che Chrome API è stato chiamato con gli argomenti necessari.

Facciamo un esempio:
supponiamo di avere una semplice estensione di Chrome che mostra il numero di schede aperte nel badge del pulsante.

pagina di sfondo:

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

Per provarlo abbiamo bisogno di:

  1. finto chrome.tabs.queryper restituire una risposta predefinita, ad esempio due schede.
  2. iniettare la nostra chrome.*api derisa in un ambiente
  3. esegui il nostro codice di estensione in questo ambiente
  4. asserire che il badge pulsante è uguale a "2"

Lo snippet di codice è il seguente:

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

Ora possiamo avvolgerlo nelle describe..itfunzioni di moka ed eseguire dal terminale:

$ mocha

background page
  ✓ should display opened tabs count in button badge

1 passing (98ms)

Puoi trovare l'esempio completo qui .

Inoltre, sinon-chrome consente di attivare qualsiasi evento chrome con risposta predefinita, ad es

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

Il link per l'esempio sembra essere morto - potresti aggiornarlo?
Raisen,

1
Link aggiornato all'esempio. Anche sinon-chrome è ora spostato su github.com/acvetkov e presto ci saranno nuovi esempi
vitalets

3

Mentre sinon.jssembra funzionare alla grande, puoi anche usare semplicemente Jasmine e deridere i callback di Chrome di cui hai bisogno. Esempio:

finto

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

Basta modificare il valore predefinito SpecRunner.htmlper eseguire il codice.


2

Informazioni sullo strumento già esistente in Chrome:

  1. Nello strumento di sviluppo di Chrome, è presente una sezione Risorse per l'archiviazione locale.

    Strumenti per gli sviluppatori> Risorse> Archiviazione locale

    Vedi i cambiamenti di localstorage lì.

  2. È possibile utilizzare console.profile per testare le prestazioni e guardare lo stack delle chiamate in fase di esecuzione.

  3. per fileSystem È possibile utilizzare questo URL per verificare che il file sia caricato o meno: filesystem: chrome-extension: /// temporary /

Se si utilizzano script di contenuto e archiviazione locale insieme senza pagina / script di sfondo e senza passaggio di messaggi, l'archiviazione locale sarà accessibile solo da quel sito. Quindi, per testare quelle pagine, devi iniettare il tuo script di test in quelle schede.


1
Non ha funzionato per me, ma mi ha portato oltre nel mio javascript. +1 per quello.
mobibob,

Per fileSystem Puoi usare: filesystem: chrome-extension: // <yourextension-id> / temporary /
Nafis Ahmad

1

Ho scoperto che posso usare il driver web Selenium per avviare una nuova istanza del browser con estensione preinstallata e pyautogui per i clic, perché Selenium non può guidare la "visualizzazione" dell'estensione. Dopo i clic è possibile creare schermate e confrontarle con quelle "previste", aspettandosi il 95% di somiglianza (perché su browser diversi è accettabile il markup di alcuni pixel).


0

Per confermare un paio di risposte precedenti, Jasmine sembra funzionare bene con le estensioni di Chrome. Sto usando la versione 3.4.0.

Puoi usare le spie Jasmine per creare facilmente doppi di test per le varie API. Non c'è bisogno di crearne uno tuo da zero. Per esempio:

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

  });

});

Qualche dettaglio in più, se aiuta:

Come menzionato in un'altra risposta, ho creato una pagina HTML come parte dell'estensione del browser che esegue i miei test. La pagina HTML include la libreria Jasmine, oltre al codice JavaScript della mia estensione, oltre alla mia suite di test. I test vengono eseguiti automaticamente e i risultati sono formattati per te. Non è necessario creare un test runner o un formattatore dei risultati. Basta seguire le istruzioni di installazione e utilizzare l'HTML documentato lì per creare la pagina del runner di test e includere anche la suite di test nella pagina.

Non penso che puoi recuperare dinamicamente il framework Jasmine da un altro host, quindi ho appena incluso la versione Jasmine nella mia estensione. Lo ometterò e anche i miei casi di test quando creerò la mia estensione per la produzione, ovviamente.

Non ho esaminato come eseguire i miei test dalla riga di comando. Sarebbe utile per gli strumenti di distribuzione automatizzata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.