单元测试

作为一个前端程序猿,在日常工作当中可能会遇到定制化地封装想要的组件的情况,此时我们写了很多行的代码,却并没有测试给我们回归,如果只靠我们自己保证质量,难免有漏掉的情况发生,这时单元测试的重要性就体现了。

当然了,在一些大的项目当中代码逻辑的正确性和功能性也尤为重要,此时完成一些功能后,我们也需要对其进行单元测试保证质量。

当我们按照整理好的需求还有设计文档完成了概要设计、文档书写和开发,在最后回归的时候可以按照文档和功能性对组件进行一定的测试,看看我们最终是否按照文档完成所有的功能和确保 JavaScript 代码的正确性。

接下来我们仔细看看单元测试

提到单元测试很多人会想到 Jest,那它有什么特性呢?

  • Jest 是 Facebook 开源的 JavaScript 测试框架,只需很少的配置,还能够根据需求进行扩展。

  • Jest 拥有自己独立的进程,最大限度地提高性能。

  • Jest 集成了断言、JSDom、覆盖率报告等开发者所需要的所有测试工具。通过添加 --coverage 标志生成代码覆盖率报告, 无需额外设置。Jest 可以从 整个项目收集代码覆盖面信息,包括未经测试的文件。

  • Jest 拥有良好的文档,提供了易于理解、熟悉且功能丰富的 API 来编写测试用例,并快速地反馈结果。

接下来,我们来看看如何安装和使用:

安装

使用 yarn 安装

yarn add --dev jest

使用 npm 安装

npm install --save-dev jest
配置

package.json 中增加:

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

常见命令:

{
  "nocache": "jest --no-cache", //清除缓存
  "watch": "jest --watchAll", //实时监听
  "coverage": "jest --coverage",  //生成覆盖测试文档
  "verbose": "npx jest --verbose" //显示测试描述
}

jest.config.js 添加配置项

export default {
  testMatch: ['<rootDir>/lib/**/__test__/**/*.[jt]s?(x)'],
  moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'node'],
  collectCoverage: false, // 是否收集测试时的覆盖率信息(默认是false,同package配置的--coverage参数)
  preset: 'ts-jest',
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '^.+\\.tsx?$': 'babel-jest',
  },
  globals: {
    'ts-jest': {
      tsConfig: {
        jsx: 'react',
      },
    },
  },
  testEnvironment: 'jsdom',
  rootDir: ' ',
};
  • testMatch 识别哪些文件是测试文件

  • moduleFileExtensions 测试文件的类型

  • testEnvironment 测试环境,默认为jsdom,可修改为 node

  • rootDir 当前目录,一般是 package.json 所在的目录

运行

最后使用 yarn test 或者 npm run test 运行

API

测试用例:

test(name, fn, timeout)

下面是一个测试用例,判断是否相等

test("this is a test",()=>{
  expect({a:1}).toBe({a:1})
})

断言

当你想要测试一个值的时候,可以使用 expect

判断相等

toBe 是否等于

用来比较数字和字符串,不能用于浮点数

expect(value).toBe(value)
toBeCloseTo 是否等于

用于浮点数比较,numDigits 指检查小数点后几位数

expect(value).toBeCloseTo(number, numDigits?)

现在,来看看下面的一个例子:

// 结果是 Fails
expect(0.2 + 0.1).toBe(0.3); 

// 下面是正确的写法
expect(0.2 + 0.1).toBeCloseTo(0.3, 5);

在 JavaScript 中,0.2 + 0.1 等于 0.30000000000000004。

toEqual 是否等于

用来比较数字、字符串、对象和数组,会递归的检查对象的所有属性和属性值是否相等,如果进行类型比较时,可以使用 toEqual

expect(value).toEqual(value)
toBeNull 是否等于 null

只匹配 null

expect(value).toBeNull()
toBeUndefined 是否等于 undefined

只匹配 undefined

expect(value).toBeUndefined()

包含

用来判断是否有包含关系

toHaveProperty 是否有对应属性

keyPath 代表对象的属性,value 代表属性的值

expect(value).toHaveProperty(keyPath, value?)
toContain 是否包含对应的值

括号里可以是数组或是字符串,生产当中可以用来检查数组中是否包含某一项。

expect(value).toContain(item)
toMatch 是否匹配对应的值

括号里可以是正则或是字符串

expect(value).toMatch(regexp | string)
toMatchObject 是否匹配对应的值

用来匹配对象和数组

expect(value).toMatchObject(object)

逻辑

用于逻辑判断,比如:大于、小于、是否为真等。

toBeTruthy 是否为真

可用来匹配 if 语句为真

expect(value).toBeTruthy()
toBeFalsy 是否为假

可用来匹配 if 语句为假

expect(value).toBeFalsy()

在 JavaScript 中,只有 6 种是假值,分别是:false,0,'',null,undefined 和 NaN。 其它的都是真值。

toBeGreaterThan 大于

使用 toBeGreaterThan 来进行大于的比较

expect(value).toBeGreaterThan(number | bigint)
toBeGreaterThanOrEqual 大于等于

使用 toBeGreaterThanOrEqual 来进行大于等于的比较

expect(value).toBeGreaterThanOrEqual(number | bigint)
toBeLessThan 小于

使用 toBeLessThan 来进行小于的比较

expect(value).toBeLessThan(number | bigint)
toBeLessThanOrEqual 小于等于

使用 toBeLessThanOrEqual 来进行小于等于的比较

expect(value).toBeLessThanOrEqual(number | bigint)

取反

测试不等于某个值的情况,not 后面可以是其它的断言

expect(value).not.toBe(value)

下面是一些使用的例子:

const houseForSale = {
  bath: true,
  bedrooms: 4,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    area: 20,
    wallColor: 'white',
    'nice.oven': true,
  },
  'ceiling.height': 2,
};

expect(houseForSale.bath).toBe(true);
expect(houseForSale.bedrooms).toEqual(4);
expect(houseForSale.kitchen).toBeNull();
expect(houseForSale.hello).toBeUndefined()

expect(houseForSale).toHaveProperty('bath');
expect(houseForSale).toHaveProperty('bedrooms', 4);
expect(houseForSale.kitchen.amenities).toContain('oven');
expect(houseForSale.kitchen.wallColor).toMatch(/white/);

expect(houseForSale.bath).toBeTruthy();
expect(houseForSale.bath).toBeFalsy();
expect(houseForSale.kitchen.area).toBeGreaterThan(18);
expect(houseForSale.kitchen.area).toBeLessThan(30);

expect(houseForSale).not.toHaveProperty('pool');

分组

describe(name, fn)

分组可以包含多个测试用例,即多个 test():

describe("component test",()=>{
    test("this is a test",()=>{
      ......
    })
    test("this is b test",()=>{
      ......
    })
    ......
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容