How to test chrome extensions?
有没有办法做到这一点? 我正在编写一个与网站交互作为内容脚本的扩展程序,并使用localstorage保存数据。 是否有可用于测试此行为的工具,框架等? 我意识到有一些用于测试javascript的通用工具,但是那些足以测试扩展的能力吗? 单元测试是最重要的,但我也对其他类型的测试(例如集成测试)感兴趣。
是的,现有的框架非常有用..
在最近的过去,我已将所有测试放在嵌入到应用程序中的"测试"页面中,但除非是物理类型,否则无法访问。
例如,我可以在
测试可以访问
如果您想直接测试页面,可以编排扩展程序以打开新选项卡(chrome.tab.create({"url":"someurl"})。对于每个新选项卡,您的内容脚本应该运行并且您可以使用您的测试框架,以检查您的代码是否已完成应该执行的操作。
至于框架,JsUnit或更新的Jasmine应该可以正常工作。
在几个chrome扩展上工作时,我提出了
Basicaly,它创建了所有
接下来,使用节点的
最后,你断言chrome api是用所需的参数调用的。
我们来举个例子:
假设我们有简单的chrome扩展,显示按钮徽章中打开的标签数量。
背景页面:
1 2 3 | chrome.tabs.query({}, function(tabs) { chrome.browserAction.setBadgeText({text: String(tabs.length)}); }); |
为了测试它,我们需要:
代码段如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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" }); |
现在我们可以将它包装到mocha的
1 2 3 4 5 6 | $ mocha background page ? should display opened tabs count in button badge 1 passing (98ms) |
你可以在这里找到完整的例子。
此外,sinon-chrome允许触发任何具有预定义响应的chrome事件,例如
1 | chrome.tab.onCreated.trigger({url: 'http://google.com'}); |
关于Chrome中已有的工具:
在chrome开发人员工具中,有适用于本地存储的资源部分。
开发者工具>资源>本地存储
查看当地存储的变化。
您可以使用console.profile来测试性能并观察运行时调用堆栈。
文件系统:铬扩展:///临时/
如果您在没有后台页面/脚本且没有消息传递的情况下一起使用内容脚本和本地存储,则只能从该站点访问本地存储。
因此,要测试这些页面,您必须在这些选项卡中注入测试脚本。
虽然
嘲笑
1 2 3 4 5 6 7 | chrome = { runtime: { onMessage : { addListener : function() {} } } } |
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
只需修改默认
为了确认以前的几个答案,Jasmine似乎与Chrome扩展程序配合得很好。我使用的是3.4.0版本。
您可以使用Jasmine间谍轻松地为各种API创建测试双精度。无需从头开始构建自己的。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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版本。当然,当我为生产构建扩展时,我将省略它以及我的测试用例。
我没有看过如何在命令行执行我的测试。这对于自动部署工具来说非常方便。
我发现我可以使用Selenium web驱动程序启动带有预安装扩展的新浏览器实例和用于点击的pyautogui - 因为Selenium无法驱动扩展的"视图"。点击后,您可以制作屏幕截图并将其与"预期"的屏幕截图进行比较,期望95%的相似度(因为在不同的浏览器上,标记运动可以接受几个像素)。