由于Firefox迫使我,我正在重写我的扩展程序以使用WebExtension API,即Chrome的Extension API。我想进行自动化测试。到目前为止,我已经尝试过这个:
我有一个package.json
,以便npm
将安装依赖项:
{
"name": "extension-api-tests",
"version": "0.0.1",
"scripts": {
"test": "karma start"
},
"devDependencies": {
"karma": "^1.3.0",
"karma-firefox-launcher": "^1.0.0",
"karma-mocha": "^1.3.0",
"karma-sinon-chrome": "^0.2.0",
"mocha": "^3.1.2",
"sinon-chrome": "^2.1.2"
}
}
我有一个karma.conf.js
来设置该测试运行器:
module.exports = function(config) {
config.set({
frameworks: ['mocha', 'sinon-chrome'],
files: ['test.js'],
reporters: ['dots'],
autoWatch: false,
browsers: ['Firefox'],
singleRun: true,
concurrency: Infinity,
});
};
我有基本的测试:
describe('my frustration', () => {
it('works when it uses no APIs', done => {
done();
});
it('should respond to messages!', done => {
console.log('message test starting');
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log('received message');
sendResponse(true);
});
chrome.runtime.sendMessage({}, result => {
console.log('received response to message');
done();
});
});
it('should open a tab!', done => {
console.log('tab test starting');
chrome.tabs.create({
'active': true,
'url': 'http://www.example.com/',
}, tab => {
console.log('created a tab:', tab);
done();
});
});
});
这当然是一个简化的测试用例。当我运行npm test
时,我得到(略有缩写):
> extension-api-tests@0.0.1 test .../ext-test
> karma start
25 07 2017 11:57:10.395:INFO [karma]: Karma v1.7.0 server started at http://0.0.0.0:9876/
25 07 2017 11:57:10.397:INFO [launcher]: Launching browser Firefox with unlimited concurrency
25 07 2017 11:57:10.404:INFO [launcher]: Starting browser Firefox
25 07 2017 11:57:14.687:INFO [Firefox 54.0.0 (Ubuntu 0.0.0)]: Connected on socket iIjNRRQfzWj68_GNAAAA with id 42440302
.
LOG: 'message test starting'
Firefox 54.0.0 (Ubuntu 0.0.0) my frustration should respond to messages! FAILED
Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
LOG: 'tab test starting'
Firefox 54.0.0 (Ubuntu 0.0.0) my frustration should open a tab! FAILED
Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
Firefox 54.0.0 (Ubuntu 0.0.0): Executed 3 of 3 (2 FAILED) (3.998 secs / 4.001 secs)
npm ERR! Test failed. See above for more details.
我尝试使用扩展API的测试都失败了。它不说(例如)chrome.runtime
未定义(但如果我从karma.conf.js中移除'sinon-chrome'
它会这样做),所以我相信我有sinon设置。但API从不做任何事情,从不工作。我要测试的代码是 all 关于通过这些API传递数据(特别是作为消息,跨越chrome / content边界)。
答案 0 :(得分:2)
除了原始问题中的所有设置外,请意识到Sinon仅提供API表面的存根/模拟:不是伪造的API实现。
要使测试“起作用”,还必须声明模拟的行为;参见例如https://sinonjs.org/releases/latest/mocks/和https://sinonjs.org/releases/latest/stubs/。最初问题中的测试是“不可能的”,因为您主要是在测试伪造的实现,而该实现也需要在测试中编写。
一旦设置了sinon-chrome,您就可以编写更像
的测试chrome.tabs.executeScript.callsArg(2);
// ... call code under test ...
assert(chrome.tabs.executeScript.calledOnce);
(这不是我真正想要编写的测试。)
答案 1 :(得分:0)
根据https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/sendMessage,sendMessage返回一个Promise。根据您的日志,
中的成功处理程序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毫秒内返回,这应该可以。