Testing 如何测试Chrome扩展/Firefox WebExtension代码?

Testing 如何测试Chrome扩展/Firefox WebExtension代码?,testing,google-chrome-extension,sinon,firefox-addon-webextensions,Testing,Google Chrome Extension,Sinon,Firefox Addon Webextensions,由于Firefox强迫我这么做,我正在重写我的扩展以使用WebExtensionAPI,即Chrome的扩展API。我想进行自动化测试。到目前为止,我已经尝试过: 我有一个package.json以便npm将安装Dependencies: { “名称”:“扩展api测试”, “版本”:“0.0.1”, “脚本”:{ “测试”:“因果报应开始” }, “依赖性”:{ “因果报应”:“^1.3.0”, “karma firefox启动器”:“^1.0.0”, “卡玛摩卡”:“^1.3.0”, “ka

由于Firefox强迫我这么做,我正在重写我的扩展以使用WebExtensionAPI,即Chrome的扩展API。我想进行自动化测试。到目前为止,我已经尝试过:

我有一个
package.json
以便
npm
将安装Dependencies:

{
“名称”:“扩展api测试”,
“版本”:“0.0.1”,
“脚本”:{
“测试”:“因果报应开始”
},
“依赖性”:{
“因果报应”:“^1.3.0”,
“karma firefox启动器”:“^1.0.0”,
“卡玛摩卡”:“^1.3.0”,
“karma sinon chrome”:“^0.2.0”,
“摩卡咖啡”:“^3.1.2”,
“sinon chrome”:“^2.1.2”
}
}
我有一个
karma.conf.js
来设置测试运行程序:

module.exports=函数(配置){
config.set({
框架:['mocha','sinon chrome'],
文件:['test.js'],
记者:[点],
自动观察:错误,
浏览器:['Firefox'],
singleRun:是的,
并发:无限,
});
};
我有一些基本的测试:

description('我的挫败感',()=>{
它('在不使用API时工作',完成=>{
完成();
});
它('应该响应消息!',完成=>{
log(“消息测试启动”);
chrome.runtime.onMessage.addListener((消息、发送者、发送响应)=>{
console.log(“收到的消息”);
sendResponse(true);
});
chrome.runtime.sendMessage({},result=>{
log('收到对消息的响应');
完成();
});
});
它('应该打开一个选项卡!',完成=>{
log('tab test start');
chrome.tabs.create({
“活动”:正确,
“url”:”http://www.example.com/',
},选项卡=>{
log('创建了一个选项卡:',选项卡);
完成();
});
});
});
这当然是一个简化的测试用例。当我运行npm测试时,我得到(略缩写):

我尝试使用扩展API的测试都失败了。它没有说(例如,
chrome.runtime
没有定义(但如果我从karma.conf.js中删除
'sinon-chrome'
),它会说,所以我相信我已经设置了sinon。但是API从来没有做过任何事情,从来没有工作过。我想测试的代码都是关于通过这些API传递数据的(特别是作为消息,以跨越chrome/内容边界)。

根据sendMessage返回一个承诺。根据您的日志,您的成功处理程序

chrome.runtime.sendMessage({}, result => {
  console.log('received response to message');
  done();
});
与运行测试的主线程相比,未及时调用。您应该尝试向主线程添加睡眠

function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}
像这样

chrome.runtime.sendMessage({}, result => {
  console.log('received response to message');
});

sleep(500).then(() => {
  done();
});

只要sendMessage在500毫秒内返回,这应该可以工作。

除了原始问题中的所有设置之外,请认识到Sinon只提供API表面的存根/模拟:而不是伪API实现

为了让测试“起作用”,还必须声明模拟的行为;参见例如和。原始问题中的那种测试是“不可能的”,因为您主要测试的是伪造的实现,您还需要在测试中编写

一旦设置好sinon chrome,您就可以编写更像

chrome.tabs.executeScript.callsArg(2);
// ... call code under test ...    
assert(chrome.tabs.executeScript.calledOnce);

(这不是我真正想写的那种测试。)

不能对主要问题发表评论,但当你解决它时,请注意
运行时。sendMessage自Chrome 49以来,显然在所有版本的Firefox中都没有发送到它自己的页面/框架。我猜sinon提供了一个与真实API不太相似的伪API,实际上,sinon文档中的示例与您使用的直接调用完全不同。我不知道sinon,但无法说明这是否是唯一受支持的方法。请尝试在问题中添加sinon标记,以便sinon专家可以看到。您(删除)的答案有助于解释您的特定问题。您是否成功使用了真正的浏览器-/webextension api?不,我调整了测试策略。
chrome.tabs.executeScript.callsArg(2);
// ... call code under test ...    
assert(chrome.tabs.executeScript.calledOnce);