📜  用 Jest 进行测试

📅  最后修改于: 2022-05-13 01:56:39.184000             🧑  作者: Mango

用 Jest 进行测试

Jest 是 Facebook 的一个 Javascript 测试框架。它最常用于单元测试。单元测试是当您向代码单元(通常是函数)提供输入并将输出与预期输出匹配时。

笑话特点:

  • 零配置:正如我们将在本文后面看到的那样,开始编写测试和部署它们需要几乎没有配置。但是,也可以将配置文件提供给测试套件。
  • 快照: Jest 也能够启用快照测试。本质上,快照与保存的快照相匹配并检查匹配功能。
  • 隔离测试: Jest 测试并行运行以提高运行时间。

设置一个笑话项目

  • 使用 npm 安装 Jest:
npm 安装笑话。 -D 关键字将 jest 安装为 dev 依赖项

npm 安装笑话。 -D 关键字将 jest 安装为 dev 依赖项

  • 项目结构:
    在项目根目录中,创建一个测试文件夹。该文件夹将存储所有测试文件。
    请注意,js 文件(将被测试)是通过它们的名称映射的。
    例如, index.js映射到index.test.js 。此 index.test.js 文件位于“tests”文件夹中。这是传统的项目结构。

开始测试:

  • 首先,让我们看一个基本的测试工作流程。
测试 - 添加两个 pos nums

测试 - 添加两个 pos nums

  • 要运行测试,请使用脚本
npm run test
  • 这将查找项目的 package.json 中提到的测试脚本。
pkg-json-test-script-ss

pkg-json-test-script-ss。查看脚本中的测试

我们将使用'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 用于将测试返回的响应“匹配”到预期的响应。这种“结果匹配”会导致“失败”“通过”

测试添加两个 pos nums

测试添加两个 pos nums

由于'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" });
});

运行上述测试将“通过”。

gfgobj 等于

gfgobj 等于

这样做的另一个变体是使用'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 匹配。

gfgobj-testobj-toequal

gfgobj-testobj-toequal

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
})

上述测试通过。

truthy-test-js-all-test-passing

truthy-test-js-all-test-passing

但是,如果上面的任何“期望”失败,Jest 会返回有意义的错误消息,如下所示。

请注意,在上述情况下,如果任何“预期”失败,则测试也完全失败。

truthy-test-js-one-expect-failing-so-test-failing

truthy-test-js-one-expect-failing-so-test-failing

匹配号码:

//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。

user1-and-user3-in-gfgUsers

user1-and-user3-in-gfgUsers

但是,以下测试将失败,因为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']));
})

数组包含失败由于 user4-absence

数组包含失败由于 user4-absence

使用正则表达式进行测试:

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'
})

tomatch-matching-ph-in-paragraphq

tomatch-matching-ph-in-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);
});