设计测试用例
之前完成了测试环境的搭建,现在继续完善单元测试。在编写代码之前需要先设计测试用例,测试用例要尽可能全面地覆盖各种情况,这样才能保证质量。在覆盖全面的同时,数量要尽可能少,这样能够提高测试效率。
# 设计思路
对于函数的测试,可以按照参数分组,每个参数一组,在对一个参数进行测试时,保证其他参数无影响。例如要测试以下的leftpad函数:
// 当字符串str的长度小于count时,在字符串的左侧填充指定字符
function leftpad(str, count, ch = '0') {
return `${[...Array(count)].map((v) => '0')}${str}`.slice(-count)
}
leftpad('1', 2) // '01'
2
3
4
5
6
由于leftpad函数有3个参数,因此可以分为3组。在对每个参数进行测试时,测试用例可以分为正确的测试用例和错误的测试用例,并且对于存在边界值的情况的参数,还需要对边界值设计测试用例。需要注意的是,每个分组下面可以采用等价类划分方法,对于同一个类型的输入,只需要设计一个用例即可。
分组 | 正确的测试用例 | 错误的测试用例 | 边界值测试用例 |
---|---|---|---|
str | 任意字符串 | 非字符串 | 空字符串 |
count | 1-N | 非数字 | 0:负数 |
ch | 任意字符串 | 非字符串 | 空字符串 |
接下来,用上述方法来给我们的深度拷贝库设计测试用例。
深拷贝库示例代码:
function type(data) {
return Object.prototype.toString.call(data).slice(8, -1).toLowerCase()
}
function clone(source) {
const t = type(source)
if(t !== 'object' && t !== 'array') {
return source
}
let target
if(t === 'object') {
target = {}
for(let i in source) {
if(source.hasOwnProperty(i)) {
target[i] = clone(source[i])
}
}
}else{
target = []
for(let i = 0;i < source.length; i++) {
target[i] = clone(source[i])
}
}
return target
}
export default clone
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
由于只有一个参数,因此只有一个分组,但是因为基本类型数据和引用类型数据的拷贝行为不一致,所以要分别测试。
分组 | 正确的测试用例 | 错误的测试用例 | 边界值测试用例 |
---|---|---|---|
data | 基本数据类型、对象、数组 | 无 | 空参数、undefined、null |
# 编写代码
我们将在test.js文件中编写测试代码,因为测试代码是在Node.js中运行的,所以可以直接引用dist/index.js
文件。
下面的代码会用到expect.js
中一些新的断言接口,下面先进行简单介绍。
在断言中添加not
即可对结果进行取非转换:
expect(1).to.equal(1)
expect(1).not.to.equal(2)
2
equal
相当于全等,而eql
则表示值相等,对于深拷贝后的引用类型数据,需要用eql
来验证深拷贝结果的正确性。
例如,下面代码中arr和cloneArr的值都是[1,2,3],但两个变量并不相等
var arr = [1,2,3]
var cloneArr = [...arr]
expect(arr).to.equal(cloneArr)
expect(arr).to,eql(cloneArr)
2
3
4
完整的测试代码如下。外层的describe用来区分函数,这里只有一个函数。内层的describe用来区分不同的参数,这里只有一个参数data,内部有正确的测试用例和边界值测试用例。
var expect = require('expect.js')
var clone = require('../dist/index.js')
describe('function clone', function() {
describe('param source', function() {
it('正确的测试用例',function() {
//基本数据类型
expect(clone('abc')).to.equal('abc')
//数组
var arr = [1,[2]]
var cloneArr = clone(arr)
expect(cloneArr).not.to.equal(arr)
expect(cloneArr).to.eql(arr)
//对象
var obj = {a: {b: 1}}
var cloneObj = clone(obj)
expect(cloneObj).not.to.equal(obj)
expect(cloneObj).to.eql(obj)
})
it('边界值测试用例', function(){
expect(clone()).to.equal(undefined)
expect(clone(undefined)).to.equal(undefined)
expect(clone(null)).to.equal(null)
})
})
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
额案场测试代码的编写后,在控制台中输入npm test
命令即可运行测试,验证结果如下: