一、Jest 介绍
Jest 是 Facebook 出品的一个测试框架,相对其他测试框架,其一大特点就是就是内置了常用的测试工具,比如自带断言、测试覆盖率工具,实现了开箱即用。
而作为一个面向前端的测试框架, Jest 可以利用其特有的快照测试功能,通过比对 UI 代码生成的快照文件,实现对 Vue 等常见框架的自动测试。
测试框架可分为两种:TDD(测试驱动开发)和BDD(行为驱动开发);
-
TDD:
BDD(Behavior Driven Development),即行为驱动开发 -
简单的来说就是先编写业务逻辑代码,然后以使得所有业务逻辑按照预期结果执行为目的,编写测试代码。
-
是一种以用户行为来驱动开发过程的开发模式。
-
BDD:集成测试
(Integration Testing) -
指对软件中的所有模块按照设计要求进行组装为完整系统后,进行检查和验证。
-
是一种以用户行为来驱动开发过程的开发模式。
二、基础用法
假设我们有一个方法 add,我们想测试它的准确性,不同参数传入是否都能得到正确的期待值呢?
function add(a, b) {
return a + b;
}
Jest提供了一个方法,expect 他会返回一个Jest对象,可以调用对象下的方法判断结果。
expect 也称作为 断言
// 期待 add(1,2) 的结果为 3
// toBe 是使用 Object.is 实现的一个匹配器,用来判断结果
expect(add(1,2)).toBe(3);
当我们的测试的方法多了后,就无法很快分辨出是哪段代码产生的错误
使用 test 方法对测试添加描述
test('测试 add 方法', () => {
expect(add(1, 2)).toBe(3); // √
expect(add(1, 4)).toBe(2); // ×
});
补充:
Object.is、== 、=== 的区别:
Object.is、== 和 === 三者使用的算法不同,所以产生的结果不相同。
- Object.is
SameValue算法 - ==
The Abstract Equality Comparison Algorithm算法 - ===
The Strict Equality Comparison Algorithm算法
参考文档:
算法差别:www.cnblogs.com/mengfangui/…
产生结果:www.cnblogs.com/wenqiangit/…
三、简单实现
在简单的了解了 test 和 expect 之后,我们可以思考下,这两个 API 他是如何实现的呢?
假设,我们现在有两个方法需要进行测试,分别是 add 和 minus
function add(a, b) {
return a + b;
}
function minus(a, b) {
return a - b;
}
实现
想法1:对不同入参都产生正确的期待值。
对想法1 最简单的代码实现,应该就是手动对比,传入参数后执行方法,接收结果,与期待值进行对比
var result = add(3, 7) // 接收结果
var expected = 10 // 期待值
if (result !== expected) {
throw Error(`3 + 7 应该等于 ${expected},但是结果却是 ${result}`)
}
var result = minus(3, 3)
var expected = 0
if (result !== expected) {
throw Error(`3 - 3 应该等于 ${expected},但是结果却是 ${result}`)
}
上面的代码已经实现了想法1 ,那我们要如何将它们封装到 test 和expect 中呢?
实现升级
想法2:将想法1 中的实现方式通过 Class 或者 柯里化 的方式实现
这里我们选择使用 柯里化的方式实现。
function expect(result) {
return {
toBe: function (actual) {
if (result !== actual) {
throw new Error(`预期值与实际值不相等。预期值 -> ${actual}, 实际值 -> ${result}`)
}
}
}
}
function test(desc, fn) {
try {
fn();
console.log(`${desc} 通过测试`);
} catch (e) {
console.log(`${desc} 没有通过测试, ${e}`);
}
}
test('测试加法: 3 + 7', () => {
expect(add(3, 7)).toBe(10)
})
test('测试减法: 3 - 3', () => {
expect(minus(3, 3)).toBe(0)
})