Jest


安装

初始化package.json

在shell中输入以下命令,初始化前端项目并生成package.json:

  npm init -y

安装Jest及相关依赖

在shell中输入以下命令,安装测试所需要的依赖:

通过 npm 添加依赖:

  npm install -D jest babel-jest babel-core babel-preset-env regenerator-runtime

babel-jest、 babel-core、 regenerator-runtime、babel-preset-env这几个依赖是为了让我们可以使用ES6的语法特性进行单元测试,ES6提供的 import 来导入模块的方式,Jest本身是不支持的。

添加.babelrc文件

在项目的根目录下添加.babelrc文件,并在文件复制如下内容:

  {
    "presets": ["env"]
  }

修改package.json中的test脚本

打开package.json文件,将script下的test的值修改为jest:

    "scripts": {
      "test": "jest"
    }

编写第一个Jest测试

创建src和test目录及相关文件

  • 在项目根目录下创建src目录,并在src目录下添加functions.js文件
  • 在项目根目录下创建test目录,并在test目录下创建functions.test.js文件

Jest会自动找到项目中所有使用.spec.js或.test.js文件命名的测试文件并执行,通常我们在编写测试文件时遵循的命名规范:测试文件的文件名 = 被测试模块名 + .test.js,例如被测试模块为functions.js,那么对应的测试文件命名为functions.test.js。

在src/functions.js中创建被测试的模块

export default {
  sum(a, b) {
    return a + b;
  }
}

在test/functions.test.js文件中创建测试用例

  import functions  from '../src/functions';

  test('sum(2 + 2) 等于 4', () => {
    expect(functions.sum(2, 2)).toBe(4);
  })

运行npm run test, Jest会在shell中打印出以下消息:

  PASS  test/functions.test.js
     sum(2 + 2) 等于 4 (7ms)

  Test Suites: 1 passed, 1 total
  Tests:       1 passed, 1 total
  Snapshots:   0 total
  Time:        4.8s

常用的几个Jest断言

上面测试用例中的expect(functions.sum(2, 2)).toBe(4)为一句断言,Jest为我们提供了expect函数用来包装被测试的方法并返回一个对象,该对象中包含一系列的匹配器来让我们更方便的进行断言,上面的toBe函数即为一个匹配器。我们来介绍几种常用的Jest断言,其中会涉及多个匹配器。

.not

  //functions.test.js
  import functions  from '../src/functions'

  test('sum(2, 2) 不等于 5', () => {
    expect(functions.sum(2, 2)).not.toBe(5);
  })

.not修饰符允许你测试结果不等于某个值的情况,这和英语的语法几乎完全一样,很好理解。

.toEqual()

  // functions.js
  export default {
    getAuthor() {
      return {
        name: 'LITANGHUI',
        age: 24,
      }
    }
  }
  // functions.test.js
  import functions  from '../src/functions';

  test('getAuthor()返回的对象深度相等', () => {
    expect(functions.getAuthor()).toEqual(functions.getAuthor());
  })

  test('getAuthor()返回的对象内存地址不同', () => {
    expect(functions.getAuthor()).not.toBe(functions.getAuthor());
  })

.toEqual匹配器会递归的检查对象所有属性和属性值是否相等,所以如果要进行应用类型的比较时,请使用.toEqual匹配器而不是.toBe。

.toHaveLength

  // functions.js
  export default {
    getIntArray(num) {
      if (!Number.isInteger(num)) {
        throw Error('"getIntArray"只接受整数类型的参数');
      }

      let result = [];
      for (let i = 0, len = num; i < len; i++) {
        result.push(i);
      }
      
      return result;
    }
  }
  // functions.test.js
  import functions  from '../src/functions';

  test('getIntArray(3)返回的数组长度应该为3', () => {
    expect(functions.getIntArray(3)).toHaveLength(3);
  })

.toHaveLength可以很方便的用来测试字符串和数组类型的长度是否满足预期。

.toThrow

  // functions.test.js
  import functions  from '../src/functions';

  test('getIntArray(3.3)应该抛出错误', () => {
    function getIntArrayWrapFn() {
      functions.getIntArray(3.3);
    }
    expect(getIntArrayWrapFn).toThrow('"getIntArray"只接受整数类型的参数');
  })

.toThorw可能够让我们测试被测试方法是否按照预期抛出异常,但是在使用时需要注意的是:我们必须使用一个函数将将被测试的函数做一个包装,正如上面getIntArrayWrapFn所做的那样,否则会因为函数抛出导致该断言失败。

.toMatch

  // functions.test.js
  import functions  from '../src/functions';

  test('getAuthor().name应该包含"li"这个姓氏', () => {
    expect(functions.getAuthor().name).toMatch(/li/i);
  })

.toMatch传入一个正则表达式,它允许我们用来进行字符串类型的正则匹配。

测试异步函数

  • 安装axios 这里我们使用最常用的http请求库axios来进行请求处理
    npm install axios
    
  • 使用async和await精简异步代码

运行测试

  • 运行测试 npm test
  • 使用 –watch 参数可以启动一个监控界面,当文件发生变化时,会便会运行相关的测试。 npm test – –watch
  • 使用 –coverage 参数,测试结束时还会得到一份测试覆盖度报告,如下图。 npm test – –coverage