自动化测试方法之一:单元测试
定义: 单元测试实质上是一段用来测试产品代码的代码,比如已知一个方法,调用这个方法,检测出结果,并将其与所预期的结果相对照
作用:
- 当实现完成时,用于确认它的正确行为
- 当实现有变化时,确认它的行为没有变化
- 当新的单元加入时,确认是否达到目的
原则:
- 独立的测试各个组件
- 独立运行,一个测试不依靠另一个测试
- 所有测试能够同时运行
- 有自我检查和自我汇报功能
怎么写一个单元测试
- 设置,测试对象的具体配置
- 应用,调用函数进行测试
- 验证,断言结果符合预期。状态验证:对输入输出关系的验证;行为验证:对某函数调用的验证。
- 拆卸,
断言: 单元测试的核心部分是断言,断言是对单元应达到状态的一种预期
测试函数: 每个测试函数就只执行一个单元,但可以调用一个或多个断言
测试用例: 一组相关的测试函数就是一个测试用例
测试套件: 更复杂的系统中,测试用例被进一步组成测试套件
// 测试用例
describe('deleteRow 删除一行并重置index', () => {
// 测试函数
it('删除指定行', () => {
const testArr = [{ uid: 0, index: 0 }, { uid: 1, index: 1 }, { uid: 2, index: 2 }];
expect(deleteRow(testArr, 1)).toEqual([{ uid: 0, index: 1 }, { uid: 2, index: 2 }]);
});
it('重置index', () => {
const testArr = [{ uid: 0, index: 111 }, { uid: 1, index: 333 }, { uid: 2, index: 222 }];
expect(deleteRow(testArr, 1)).toEqual([{ uid: 0, index: 1 }, { uid: 2, index: 2 }]);
});
it('删除不存在行', () => {
const testArr = [{ uid: 0, index: 1 }, { uid: 1, index: 2 }, { uid: 2, index: 3 }];
expect(deleteRow(testArr, 3)).toEqual(testArr);
});
});
单元测试的好处:
- 编写一次测试,多次运行
- 回归测试
- 代码重构
- 跨浏览器的测试
- 写的好的测试还可当作底层接口文档
- 最大的一个好处,作为程序设计的工具,可以帮助我们分离耦合过紧的代码
测试驱动开发
定义: 测试驱动开发是一种编程技术,将单元测试移动到前面,成为产品代码的最初切入点。在编写产品代码之前测试已经被编写成规范了。
目的:
- TDD目标不是测试
- 目标是帮助推进代码设计,写出松耦合冗余少、遵从单一职责原则的代码,提高代码健壮性,因为TDD要求我们在提供解决方案之前先想到结果。
TDD开发过程:
TDD开发过程是一个迭代的过程,每次迭代都由着4步构成:
- 编写一个测试
- 运行测试,观看新测试失败
- 使这个测试通过
- 重构消除冗余
基准测试
用来测试相对性能,当一个问题有多种解决方案时,可以用基准测试做一个选择。
function runBenchmark(name,test){
setTimeout(()=>{
let start = new Date().getTiem();
test();
let total = new Date().getTime()-start;
console.log(`${name}:${total}ms`);
},15)
}
模拟对象
解释
在测试一个方法时,方法中可能会调用其他的方法,不用关心其他方法的内部实现,只用关心是否被调用,还可以模拟返回值。
作用
- 验证外部函数是否被调用
- 设置外部依赖函数的返回值
参考资料: 《测试驱动的javascript开发》