Y at-il un bon moyen de le faire? J'écris une extension qui interagit avec un site Web en tant que script de contenu et enregistre les données en utilisant localstorage. Existe-t-il des outils, des cadres, etc. que je peux utiliser pour tester ce comportement? Je me rends compte qu'il existe des outils génériques pour tester javascript, mais sont-ils suffisamment puissants pour tester une extension? Les tests unitaires sont les plus importants, mais je suis également intéressé par d'autres types de tests (tels que les tests d'intégration).
Oui, les frameworks existants sont assez utiles ..
Dans un passé récent, j'ai placé tous mes tests sur une page "test" qui a été intégrée à l'application mais qui n'est pas accessible à moins d'être tapée physiquement.
Par exemple, j'aurais tous les tests dans une page accessible sous chrome-extension://asdasdasdasdad/unittests.html
Les tests auraient accès à localStorage
etc. Pour accéder aux scripts de contenu, en théorie, vous pourriez tester cela via des IFRAME intégrés dans votre page de test, mais ce sont des tests de niveau d'intégration plus, les tests unitaires vous obligeraient à résumer cela loin à partir de vraies pages afin que vous ne dépendiez pas d'eux, de même avec l'accès à localStorage.
Si vous souhaitez tester des pages directement, vous pouvez orchestrer votre extension pour ouvrir de nouveaux onglets (chrome.tab.create ({"url": "someurl"}). Pour chacun des nouveaux onglets, votre script de contenu doit s'exécuter et vous pouvez utiliser votre framework de test pour vérifier que votre code a fait ce qu'il devrait faire.
Quant aux frameworks, JsUnit ou le plus récent Jasmine devrait fonctionner correctement.
Travailler sur plusieurs extensions chrome que j'ai trouvées sinon-chrome
projet qui permet d'exécuter des tests unitaires en utilisant mocha
, nodejs
et phantomjs
.
Fondamentalement, il crée sinon des moqueries de tous chrome.*
API où vous pouvez mettre toutes les réponses json prédéfinies.
Ensuite, vous chargez vos scripts à l'aide de vm.runInNewContext
pour la page d'arrière-plan et phantomjs
pour la page popup/options de rendu.
Et enfin, vous affirmez que chrome api a été appelé avec les arguments nécessaires.
Prenons un exemple:
Supposons que nous ayons une simple extension chrome qui affiche le nombre d'onglets ouverts dans le badge du bouton.
page d'arrière-plan:
chrome.tabs.query({}, function(tabs) {
chrome.browserAction.setBadgeText({text: String(tabs.length)});
});
Pour le tester, nous avons besoin de:
chrome.tabs.query
pour renvoyer une réponse prédéfinie, par exemple deux onglets.chrome.*
api dans un environnementL'extrait de code est le suivant:
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"
});
Maintenant, nous pouvons l'envelopper dans le describe..it
fonctionne et s'exécute à partir du terminal:
$ mocha
background page
✓ should display opened tabs count in button badge
1 passing (98ms)
Vous pouvez trouver un exemple complet ici .
De plus, sinon-chrome permet de déclencher tout événement chrome avec une réponse prédéfinie, par ex.
chrome.tab.onCreated.trigger({url: 'http://google.com'});
À propos de l'outil déjà existant dans Chrome:
Dans l'outil de développement chrome, il y a une section pour les ressources pour le stockage local.
Outils pour les développeurs> Ressources> Stockage local
Voir les changements de stockage local là-bas.
Vous pouvez utiliser console.profile pour tester les performances et regarder la pile d'appels au moment de l'exécution.
Si vous utilisez le script de contenu et le stockage local ensemble sans page/script d'arrière-plan et sans transmission de message, le stockage local sera accessible à partir de ce site uniquement. Donc, pour tester ces pages, vous devez injecter votre script de test dans ces onglets.
Tandis que sinon.js
semble très bien fonctionner, vous pouvez aussi simplement utiliser du jasmin ordinaire et vous moquer des callbacks Chrome dont vous avez besoin. Exemple:
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
Modifiez simplement la valeur par défaut SpecRunner.html
pour exécuter votre code.
Pour confirmer quelques réponses précédentes, Jasmine semble bien fonctionner avec les extensions Chrome. J'utilise la version 3.4.0.
Vous pouvez utiliser Jasmine spies pour créer facilement des doubles de test pour les différentes API. Pas besoin de construire le vôtre à partir de zéro. Par exemple:
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);
});
});
Quelques détails supplémentaires, si cela peut vous aider:
Comme mentionné dans une autre réponse, j'ai créé une page HTML dans le cadre de mon extension de navigateur qui exécute mes tests. La page HTML comprend la bibliothèque Jasmine, plus le code JavaScript de mon extension, plus ma suite de tests. Les tests sont exécutés automatiquement et les résultats sont formatés pour vous. Pas besoin de construire un lanceur de test ou un formateur de résultats. Suivez simplement les instructions d'installation , et utilisez le code HTML documenté pour créer votre page de test runner, et incluez également votre suite de tests dans la page.
Je ne pense pas que vous puissiez récupérer le framework Jasmine de manière dynamique à partir d'un autre hôte, j'ai donc simplement inclus la version Jasmine dans mon extension. Je vais l'omettre et aussi mes cas de test lorsque je construirai mon extension pour la production, bien sûr.
Je n'ai pas regardé comment exécuter mes tests sur la ligne de commande. Ce serait pratique pour les outils de déploiement automatisé.
J'ai trouvé que je peux utiliser le pilote Web Selenium pour démarrer une nouvelle instance de navigateur avec l'extension préinstallée et pyautogui pour les clics - car Selenium ne peut pas lecteur "vue" de l'extension. Après les clics, vous pouvez faire des captures d'écran et les comparer avec celles "attendues", en attendant 95% de similitude (car sur différents navigateurs, il s'agit de mouvements de balisage acceptables pour quelques pixels).