用 Jest 进行测试
Jest 是 Facebook 的一个 Javascript 测试框架。它最常用于单元测试。单元测试是当您向代码单元(通常是函数)提供输入并将输出与预期输出匹配时。
笑话特点:
- 零配置:正如我们将在本文后面看到的那样,开始编写测试和部署它们需要几乎没有配置。但是,也可以将配置文件提供给测试套件。
- 快照: Jest 也能够启用快照测试。本质上,快照与保存的快照相匹配并检查匹配功能。
- 隔离测试: Jest 测试并行运行以提高运行时间。
设置一个笑话项目
- 使用 npm 安装 Jest:
- 项目结构:
在项目根目录中,创建一个测试文件夹。该文件夹将存储所有测试文件。
请注意,js 文件(将被测试)是通过它们的名称映射的。
例如, index.js映射到index.test.js 。此 index.test.js 文件位于“tests”文件夹中。这是传统的项目结构。
开始测试:
- 首先,让我们看一个基本的测试工作流程。
- 要运行测试,请使用脚本
npm run test
- 这将查找项目的 package.json 中提到的测试脚本。
我们将使用'expect'方法来测试我们的功能。也可以使用'describe'和'it'来测试这些功能。
一个基本测试:添加两个正数并检查结果。
//index.js
testForAdd: (a, b) => { return (a + b) },
//index.test.js
test('test adding two positive nums', function() {
expect(testFns.testForAdd(4, 5)).toBe(9);
});
当'npm run test'运行时, index.test.js文件被遍历。然后运行放置在“testFns”对象中的 testForAdd函数。 toBe 用于将测试返回的响应“匹配”到预期的响应。这种“结果匹配”会导致“失败”或“通过” 。
由于'toBe(8)' ,以下测试将失败。
//example of a failing test
test('test adding two positive nums - failing test', function() {
expect(testFns.testForAdd(4, 5)).toBe(8);
});
与toBe相反: not.toBe()
'toBe' 匹配器的反面是通过简单地在它前面加上'not'来创建的。
例如:
//test successful - test for opposite of a matcher.
//The following test will 'Pass' if the returned value is not equal to 8.
test('test adding two positive nums - failing test', function() {
expect(testFns.testForAdd(4, 5)).not.toBe(8);
});
将 'toBe' 与 JS 对象一起使用:
让我们考虑一个要测试 JS 对象的每个字段的情况。 Jest 为我们提供了一种使用'toEqual' 的方法。 'toEqual'是一个深度匹配器(检查每个可能的字段和子字段)。
//expect toEqual example - check every field's value
// testFns.test_toEqual(gfgObj)
test('check gfgObj toEqual', () => {
let gfgObj = { name: "GFG" };
gfgObj['type'] = "company";
expect(gfgObj).toEqual({ name: "GFG", type: "company" });
});
运行上述测试将“通过”。
这样做的另一个变体是使用'toEqual'匹配两个对象。
这样做是这样的:
test('check gfgObj toEqual', () => {
let gfgObj = {
name: "GFG",
type: "company",
members: {
employees: 100,
contributors: 500
}
};
let testObj = {
name: "GFG",
type: "company",
members: {
employees: 100,
contributors: 500
}
};
expect(gfgObj).toEqual(testObj);
});
该测试演示了 toEqual 的深度匹配功能。
上述测试通过,因为 gfgObj 中的每个密钥对都与 testObj 匹配。
toBeCloseTo – 用于浮点数和其他近似匹配
//see here that a+b != c even though simple addition is taking place.
> var a = 1.32
> undefined
> var b = 2.31
> undefined
> c = a+b;
> 3.63
> var res = false;
> if(c==(a+b)) {c=true;}
> undefined
> c
> false
在这种情况下,最好使用 Jest 库中的“toBeCloseTo”匹配器。
test('floating point number - use toBeCloseTo instead', function() {
// const num1 = 0.3;
// const num2 = 0.2;
const result = 9.31 + 9.2;
expect(result).toBeCloseTo(18.51);
})
上面的测试也通过了。
匹配真假:
https://jestjs.io/docs/en/using-matchers#truthiness
很多时候,编写测试是为了检查 'expect' 返回的真值和假值。
JS 中的虚假值。
JS 中的真实值。
//checking for truthy values - All the tests will return truthy.
test('check for truthy', function() {
const gfgObj = {
first: null,
second: undefined,
third: false
}
expect(gfgObj.first).not.toBeTruthy(); // True - Pass
expect(gfgObj.second).toBeUndefined(); // True - Pass
expect(gfgObj.third).toBeFalsy(); // True - Pass
})
上述测试通过。
但是,如果上面的任何“期望”失败,Jest 会返回有意义的错误消息,如下所示。
请注意,在上述情况下,如果任何“预期”失败,则测试也完全失败。
匹配号码:
//tests for Number matches
test('test for numbers', function() {
const result = 3 + 9;
// expect(result).toBe(12); //the plain old matcher
expect(result).not.toBeLessThan(10); // result > 10
expect(result).toBeLessThan(15); // result < 15
expect(result).not.toBeGreaterThan(15); // result 10
expect(result).toBeGreaterThanOrEqual(12); //result >= 12
// expect(result).not.toBeGreaterThanOrEqual(12); // result == 12, this Fails
// expect(result).toBeLessThanOrEqual(10); // result >= 10, this Fails
})
数组中包含的测试值:
我们还可以测试特定值是否包含在数组中。请注意,如果数组中至少有一个值不存在,则此测试将“失败”。例如,
//testing arrays
const gfgUsers = [
'user1',
'user2',
'user3'
];
test('test for a value in gfgUsers', function() {
// expect(gfgUsers).toContain('user2');
// expect(gfgUsers).not.toContain('user2');
//expect array containing
expect(gfgUsers).toEqual(expect.arrayContaining(['user1', 'user3']));
})
上述测试通过,因为 gfgUsers 中存在 user1 和 user3。
但是,以下测试将失败,因为gfgUsers中不存在“user4”。
//testing arrays
const gfgUsers = [
'user1',
'user2',
'user3'
];
test('test for a value in gfgUsers', function() {
//expect array containing
expect(gfgUsers).toEqual(expect.arrayContaining(['user1', 'user4']));
})
使用正则表达式进行测试:
test('string match tests - toMatch - used for regex-es', function() {
const str = 'GeeksforGeeks';
// expect(str).toMatch(/f/);
// expect(str).toMatch(/Z/);
//you can create more complex Regexes
const str1 = 'This is a test paragraph. I wrote it.'
expect(str1).toMatch(/[pP][hH][\.]/); //matches 'ph.' in the word 'paragraph'
})
扩展匹配器
Jest 还提供了扩展其“匹配器”功能的规定,这是使用“expect.extend()”关键字完成的。 .extend()函数作为对象传递匹配器。
语法: expect.extend({matcher1, matcher2}) ;
例如,如果我们想构建一个匹配器来检查字符串中是否存在短语:
expect.extend({
stringPresent(receivedString, phraseString) {
bool phrasePresent = true;
var re = new RegExp(phraseString);
if (re.test(receivedString)) {
phrasePresent = true;
} else {
phrasePresent = false;
}
if (phrasePresent === true) {
return {
message: () =>
`string present`,
pass: true,
};
} else {
return {
message: () =>
`string absent`,
pass: false,
};
}
},
});
处理异常
我们还可以检查代码单元抛出的错误类型。我们可以检查名称、消息、对象等抛出的错误。
语法:expect( fnName() ).toThrow( error );
错误参数/参数在这里是可选的。
假设我们想通过抛出的错误消息来测试一个函数。
function testGFGMessage() {
throw new Error('this is testGFGMessage function error');
}
test('testing testGFGMessage', function(){
expect(testGFGMessage).toThrow('this is testGFGMessage function error');
})
还有许多其他方法可以抛出错误并检查它们。详细的参考可以在这里找到。
跳过/运行测试子集
https://jestjs.io/docs/en/api#testskipname-fn
Jest 还提供了在运行测试套件时跳过特定测试的规定。
要实现它,只需使用“skip”关键字。例如,
function addFn(num1, num2){
return num1 + num2;
}
test.skip('skip test example - skipping the addition test', () => {
expect(addFn(2, 3)).toBe(5);
});
与此相反的是只实现测试的一个子集,这是通过使用“only”关键字来实现的。例如,
function addFn(num1, num2){
return num1 + num2;
}
test.only('skip test example - skipping the addition test', () => {
expect(addFn(2, 3)).toBe(5);
});