问题:
最近,在查看我们现有的测试代码库时,我注意到在没有“匹配”部分的情况下使用expect()
时出现了一种危险的错字/错误:
expect(page.filters.fromDateLabel.getText(), "After");
我很确定toEqual()
本来应该用在这里:
expect(page.filters.fromDateLabel.getText()).toEqual("After");
这个问题是jasmine
在这种情况下不会失败的期望(很明显,因为实际上并没有预料到)。这让我们遇到了一个更严重的问题 - 在测试案例中没有实际测试过 - 它没有任何期望。我们对所测试的内容产生了错误的认识。
问题:
我希望尽快发现这些错误。您认为我应该如何处理这个问题?
思想:
jasmine
是否有类似内置的内容),那么会以某种方式使测试用例失败。expect()
,如果“期望”部分没有调用任何内容,则发出警告/引发错误eslint
规则答案 0 :(得分:7)
答案中提供的自定义ESLint规则现在是eslint-plugin-jasmine
1.6.0的一部分:
旧答案:
这是custom ESLint rule我最终得到的结果:
module.exports = function (context) {
return {
// checking "expect()" arguments
CallExpression: function (node) {
if (node.callee.name === 'expect') {
if (node.arguments.length > 1) {
context.report(node, 'More than one argument passed to expect()')
} else if (node.arguments.length === 0) {
context.report(node, 'No arguments passed to expect()')
}
}
},
// nothing called on "expect()"
'CallExpression:exit': function (node) {
if (node.callee.name === 'expect' && node.parent.type === 'ExpressionStatement') {
context.report(node, 'Nothing called on expect()')
}
}
}
}
检查3件事:
expect()
expect()
expect()
以下是目前捕获的无效expect()
使用示例:
expect(page.filters.fromDateLabel.getText(), "After");
expect("After");
expect();
对于选项#1,实际上有一个非常相关且有用的ESLint
规则已经实施并由[eslint-plugin-jasmine
]开源:
答案 1 :(得分:1)
我倾向于认为静态分析路线是最好的,但是如果你正在寻找一种快速而肮脏的方式,那么这里有一些代码可以抓住所有对expect
的调用所返回的期望,并创建一个代理跟踪是否曾使用任何期望的属性:
var unusedExpectations = new Set();
var originalExpect = window.expect; // Should be empty after every spec
var expect = function() {
var rawExpectation = originalExpect.apply(this, arguments);
unusedExpectations.add(rawExpectation); // Assume unused until used
// Traverse expectation and its prototypes, copying all properties to
// our proxy object. (Note that this becomes much simpler if you have
// ES6 Proxy in your environment.)
var proxy = {}
for(var proto = rawExpectation; proto; proto = proto.__proto__) {
Object.getOwnPropertyNames(proto).forEach(function(prop) {
if(Object.getOwnPropertyDescriptor(proxy, prop))
return;
Object.defineProperty(
proxy, prop, {
get: function() {
// Aha! Somebody used this expectation for _something_.
unusedExpectations.delete(rawExpectation);
return rawExpectation[prop];
}
}
);
});
}
return proxy;
}
将它放在一个隐藏Jasmine的expect
的地方,然后:
beforeEach(function() {
unusedExpectations.clear();
});
afterEach(function() {
expect(unusedExpectations.size).toEqual(0);
});
注意事项:
expect(foo).toBeFalsy;
(丢失的parens)。expect(foo).toString()
。仍然有效!
可以添加代码来检查堆栈跟踪并提取有问题的expect()
的位置,但我想标记哪个规范有未使用的expect()
就足够了。