Ash*_*our 24 unit-testing parameterized-unit-test jasmine parameterized-tests
好吧作为C#NUnit的家伙,这可能很奇怪.
但茉莉花是否允许参数化单元测试?
我不确定它是否违反"声明"和"它"以使非程序员可读.
我见过一些第三方插件,但它们有点陈旧,不确定它是否已添加到茉莉花中.如果我想使用插件
只是为了帮助将来发现这一点的人,我在茉莉花论坛上被告知在Jasmine本身内没有对参数化测试的一流支持.
Mar*_*ein 29
基于piotrek的答案和Javascript中的参数化测试文章,您还可以使用以下使用ES6语法的方法:
[
['abc', 3],
['ab', 2],
['', 0],
].forEach(([string, expectedLength]) => {
it(`should return length ${expectedLength} for string "${string}"`, () => {
expect(string.length).toBe(expectedLength);
});
});
Run Code Online (Sandbox Code Playgroud)
我已经使用Jest测试框架对其进行了测试,但它也适用于Jasmine.
Fra*_*rzi 21
另一种解决方案是使用Array of Objects而不是Array of Arrays.如果你使用像TypeScript这样的打字系统,它会更合适.
想象一下,您有以下参数化测试:
it('action(value) should reset the forms pool only if value is true', () => {
[
[true, 1],
[false, 0],
].forEach(([value, calledTimes]) => {
spyResetFormsPool.calls.reset();
component.action(value); // type error #1
expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes); // type error #2
});
});
Run Code Online (Sandbox Code Playgroud)
使用TypeScript,它将无法编译,从而产生两个错误:
错误#1:
错误TS2345:类型'数字|的参数 boolean'不能赋值给'boolean'类型的参数.
错误#2:
错误TS2345:类型'数字|的参数 boolean'不能赋值给'number'类型的参数.类型'true'不能分配给'number'类型.
那是因为TypeScript看到一个' number |数组 布尔 '.
我们可以通过使用一些显式转换来快速解决此警告:
it('action(value) should reset the forms pool only if value is true', () => {
[
[true, 1],
[false, 0],
].forEach(([value, calledTimes]) => {
spyResetFormsPool.calls.reset();
component.action(value as boolean); // necessary cast
expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes as number); // necessary cast
});
});
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案并不是很好.
更好的方法是使用对象数组,因此默认情况下正确处理类型,不需要显式转换:
it('action(value) should reset the forms pool only if value is true', () => {
[
{ value: true, calledTimes: 1 },
{ value: false, calledTimes: 0 },
].forEach(({ value, calledTimes }) => {
spyResetFormsPool.calls.reset();
component.action(value);
expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes);
});
});
Run Code Online (Sandbox Code Playgroud)
你想用for而不是forEach(我个人认为它更具可读性)吗?这也是可能的:
it('action(value) should reset the forms pool only if value is true', () => {
for (const {value, calledTimes} of [
{value: true, calledTimes: 1},
{value: false, calledTimes: 0},
]) {
spyResetFormsPool.calls.reset();
component.action(value);
expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes);
}
});
Run Code Online (Sandbox Code Playgroud)
您可以使用以下约定来提高可读性:
const testCases = [
{actualValue: true, expectedValue: true},
{actualValue: false, expectedValue: false}
]
testCases.forEach(({actualValue, expectedValue}) => {
it(`should be the same given: ${actualValue} and expected :${expectedValue} values`, () => {
expect(actualValue).toBe(expectedValue)
})
})
Run Code Online (Sandbox Code Playgroud)
您将看到以下要运行的测试用例:
Test Results
+ should be the same given: true and expected: true values
+ should be the same given: false and expected: false values
Run Code Online (Sandbox Code Playgroud)
我已经很长时间没有使用 jasmine 了,但是添加参数化测试非常容易:
['abc', 3,
'ab', 4,
'', 0].
it('should contain string length', function(string, expected){
expect(string.length).toBe(expected);
});
Run Code Online (Sandbox Code Playgroud)
只需几行基础设施代码:
Array.prototype.it = function(description, testCaseFunction) {
_(this)
.chunk(testCaseFunction.length)
.each(function(innerArray){
it(description + ' ' + JSON.stringify(innerArray), function(){
testCaseFunction.apply(this, innerArray);
});
})
.value();
};
Run Code Online (Sandbox Code Playgroud)
根据您所需的语法和更改默认 js 对象的意愿,您有很多选择:http://blog.piotrturski.net/2015/04/jasmine-parameterized-tests.html