Jest使用
Jest 是由 Facebook 开发的一个 js 测试框架,jest 主要侧重于被用于做单元测试和集成测试
安装
js
npm i jest -D
运行
**package.json
**里面配置命令
js
// scripts添加测试脚本
{
"test": "jest" /* 运行后便会使用 jest 执行所有的 .test.js 为后缀的测试文件 */
}
// 如果只想测试对应的文件并一直执行,可以使用如下命令
{
"test": "npx jest 测试文件名称 --watch"
}
运行相应的文件代码,√ 测试加法 (5 ms)是测试通过,代表写的程序没问题, × 测试加法 (8 ms)是没通过
需要的结果-Expected: 3
实际的结果-Received: 4
使用
在项目中的任意位置(通常单独建个名为 test 的文件夹)新建以 .test.js
为后缀的测试文件,如 expect.test.js
(若项目中有 test.js 存在,请改为其他名称,JEST 会将 test.js 也视为测试文件)
安装了 jest 之后,会提供一些全局的方法或者对象,例如 ++test、expect、jest++,这些方法或者对象不需要导入,直接在测试文件中使用即可
it 方法实际上是 test 方法的一个别名
**expect
**是断言方法
分组
describe
可以针对不同的测试用例来进行分组,分组语法:++describe++(这个分组的描述,回调函数),该方法也是一个全局方法,不需要导入直接使用
js
const { sum, sub, mul, div } = require('./tools')
describe("这是一组测试,测试加减法", () => {
// 回调函数中就放一个一个的测试用例
/**
* 一个 test 方法意味着书写了一个测试用例
* param1 :针对这个测试用例的一个描述
* param2 :执行该用例所对应的回调函数
*/
test("测试加法", () => {
expect(sum(1, 2)).toBe(3);
});
test("测试减法", () => {
expect(sub(10, 5)).toBe(5);
});
});
describe("这是一组测试,测试乘除法", () => {
/**
* it 方法实际上是 test 方法的一个别名
*/
it("测试乘法", () => {
expect(mul(2, 3)).toBe(6);
});
it("测试除法", () => {
expect(div(10, 2)).toBe(5);
});
});
修饰符
not
用于对断言进行取反操作,可以与各种断言函数结合使用,以表示一个断言的否定形式。
js
// not表示不相等
it('1+2不等于4', () => {
// 1+2判断不等于4
expect(1+2).not.toBe(4) // true
})
resolves
rejects
匹配器
toBe
执行的是 ES6 的Object.is,与严格相等运算符(===)基本一致,不会进行强制类型转换,不同之处为 +0不等于-0,NaN等于自身,对引用类型的数据(如对象、数组等),比较其地址是否相同。
js
const { sum, sub, mul, div } = require("./tools")
test("断言2+2=4", () => {
expect(2 + 2).toBe(4);
});
// 可以以相同的方式测试其他的工具函数:
it("测试加法", ()=>{
expect(sum(1, 2)).toBe(3);
expect(sub(10, 5)).toBe(5);
expect(mul(2, 3)).toBe(6);
expect(div(10, 2)).toBe(5);
})
// toBe比较不了深度对象
test('深度比较对象', () => {
const stu = {name : "张三", score : {html : 100, css : 90}};
expect(stu).not.toBe({name : "张三", score : {html : 100, css : 90}}) // 测试通过
})
toEqual
会递归比较对象的所有属性, 比较数组/对象的每一项,但会忽略 undefined
js
test('深度比较对象', () => {
// expect({ a: 1, b: 2 }).toEqual({ a: 1, b: 2 }) // 结果是true
const stu = {name : "张三", score : {html : 100, css : 90}};
expect(stu).toEqual({name : "张三", score : {html : 100, css : 90}}) // 测试通过
expect(stu).toEqual({name : "张三", score : {html : 100, css : 100}}) // 测试报错
})
it('有undefined', () => {
const stu = {name : "张三", job: undefined, score : {html : 100, css : 90}};
expect(stu).toEqual({name : "张三", score : {html : 100, css : 90}}) // 测试通过
})
**++toBe与toEqual++**的区别是:
toBe 用于比较两个值是否严格相等(使用===
操作符)适用于以下场景:
- 原始类型:如数字、字符串、布尔值。
- 引用类型:检查两个引用是否指向同一个内存地址。
toEqual用于深度比较两个对象或数组,检查它们的值是否相等,而不是检查它们是否指向同一个内存地址。它适用于以下场景:
- 对象:比较对象的属性值是否相等。
- 数组:比较数组的元素是否相等
toStrictEqual
严格相等:与 toEqual 类似,但不会忽略 undefined
js
it('有undefined', () => {
const stu = {name : "张三", job: undefined, score : {html : 100, css : 90}};
expect(stu).toStrictEqual({name : "张三", score : {html : 100, css : 90}}) // 测试报错
})
布尔值
toBeFalsy: 断言为 false
toBeTruthy:断言为 true
toBeNull: 断言为 null
toBeDefined:测试一个值是否被定义,即检查该值是否不是undefined
toBeUndefined:断言为 undefined
js
test("布尔值相关匹配器",()=>{
const n = null;
expect(n).toBeFalsy();
// 取反:是false
expect(n).not.toBeTruthy();
const a = 0;
// 0是false
expect(a).toBeFalsy();
// toBeTruthy断言是true,not是取反就是false
expect(a).not.toBeTruthy();
})
test("无参匹配器",()=>{
const n = null;
// toBeNull断言是null
expect(n).toBeNull();
// toBeDefined断言不是undefined
expect(n).toBeDefined();
// toBeUndefined断言不是undefined
expect(n).not.toBeUndefined();
const a = 0;
// toBeNull断言不是null
expect(a).not.toBeNull();
// toBeDefined断言不是undefined
expect(a).toBeDefined();
// toBeUndefined断言不是undefined
expect(a).not.toBeUndefined();
})
数值
数值就是两个数值之间大小的比较,有大于、大于等于、小于、小于等于之类的
toBeGreaterThan:大于
toBeGreaterThanOrEqual:大于等于
toBeLessThan:小于
toBeLessThanOrEqual: 小于等于
toBeCloseTo:是否接近某个数
js
// 数值匹配器
test("数值相关匹配器",()=>{
const a = 1;
const b = 2;
// toBeGreaterThan断言大于
expect(a).toBeGreaterThan(b); // 输出错误
// toBeGreaterThanOrEqual断言大于等于
expect(a).toBeGreaterThanOrEqual(b); // 输出错误
// toBeLessThan断言小于
expect(a).toBeLessThan(b); // 输出正确
// toBeLessThanOrEqual断言小于等于
expect(a).toBeLessThanOrEqual(b);
// 这里需要注意一下浮点数
const value2 = 0.1 + 0.2;
// toBeCloseTo断言是否接近
expect(value2).toBeCloseTo(0.3);
// toBeCloseTo 还接受第二个参数,第二个参数用于指定位数,默认是两位
expect(0.302).toBeCloseTo(0.301);
expect(0.302).not.toBeCloseTo(0.301, 5);
})
toMatch
可以检查字符串是否和某一个正则表达式能够匹配上
js
test("字符串相关匹配器",()=>{
expect("this is a test").toMatch(/test/); // 输出正确
expect("this is a test").not.toMatch(/abc/); // 输出正确,not 取反
})
toContain
数组中查找指定项,toContain进行的是全等比较,也就是严格比较
js
const shoppingList = [
"diapers",
"kleenex",
"trash bags",
"paper towels",
"milk",
];
test("数组相关匹配器", () => {
expect(shoppingList).toContain("milk");
// toContain 进行的是全等比较,也就是严格比较
expect([1, 2, 3]).not.toContain("1");
expect([{ name: "张三" }, { name: "李四" }]).not.toContain({ name: "张三" });
// // toContain 还可以用来检测一个字符串是否是另一个字符串的子串
expect("this is a test").toContain("test");
// // 也可以用到集合(set)里面
expect(new Set(shoppingList)).toContain("milk");
});
toThrow
用于判断函数是否抛出异常,并可以指定抛出异常的具体内容。
js
function compileCode(){
throw new Error("aaa you are using the wrong JDK bbb");
}
test("异常相关的匹配器",()=>{
expect(()=>compileCode()).toThrow();
// toThrow 里面可以传递不同的参数
expect(()=>compileCode()).toThrow(Error);
expect(()=>compileCode()).toThrow("you are using the wrong JDK");
expect(()=>compileCode()).toThrow(/JDK/);
})
arrayContaining
匹配一个测试返回的数组,它包含所有预期的元素。就是说,这个预期数组是测试返回数组的一个子集。
js
const arr = ["张三"];
test("上面的数组不包含某一项", () => {
expect(["李四", "王武", "赵六"]).toEqual(expect.not.arrayContaining(arr));
});
objectContaining
匹配一个测试返回的对象,它包含所有预期的元素。就是说,这个预期数组是测试返回对象的一个子集。
js
const obj = {name : "张三"};
test("对象不包含上面的键值对",()=>{
expect({age : 18}).toEqual(expect.not.objectContaining(obj));
expect({name: "李四",age : 18}).toEqual(expect.not.objectContaining(obj));
})