# 一.安装

  1. 安装node
  2. 生成package.json文件 npm init
  3. 安装Jest框架
yarn add --dev jest
1

# 二.基本使用

  1. 创建sum.js 文件
function sum(a, b) {
  return a + b;
}
module.exports = sum;
1
2
3
4
  1. 创建名为 sum.test.js 的文件
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
1
2
3
4
5
  1. 将如下代码添加到 package.json 中:
{
  "scripts": {
    "test": "jest"
  }
}
1
2
3
4
5
  1. 执行命令yarn test 或者npm run test,执行结果如下:

# 三.生成测试覆盖率

  1. Jest初始化配置
npx jest --init
1

之后会有一些选项,你根据自己的需要进行选择就可以了:

  • Choose the test environment that will be used for testing ? 代码是运行在Node环境还是Web环境下?
  • Do you want Jest to add coverage reports ? 是否生成测试覆盖率文件?
  • Automatically clear mock calls and instrances between every test?是否需要在测试之后清楚模拟调用的一些东西?
  • 在这三个选项选择之后,你会发现你的工程根目录下多了一个jest.config.js的文件。打开文件你可以看到里边有很多Jest的配置项。
  1. coverageDirectroy详解 coverageDirectroy的配置是用来打开代码覆盖率的,如果我们把代码写成下面的样子,就说明打开了代码覆盖率的这个选项。
coverageDirectory : "coverage"   //打开测试覆盖率选项
1

当这个选项被打开后,我们就可以使用下面的命令,jest就会自动给我们生成一个代码测试覆盖率的说明。 3. 生成覆盖率说明

 npx jest --coverage 
1

当然这个不仅会有一个简单的终端图表,还会生成一个coverage的文件夹,这里边有很多文件。

我们可以打开coverage-lcov-reporrt-index.html文件,这时候就可以看到一个网页形式的,非常漂亮的测试覆盖率报告。

补充解析:

  • %stmts是语句覆盖率(statement coverage):是不是每个语句都执行了?
  • %Branch分支覆盖率(branch coverage):是不是每个if代码块都执行了?
  • %Funcs函数覆盖率(function coverage):是不是每个函数都调用了?
  • %Lines行覆盖率(line coverage):是不是每一行都执行了?

# 四.匹配器(真假匹配)

  1. toBe():等同于===,严格相等
test('测试严格相等',()=>{
  const a = {number:'007'}   
  expect(a).toBe({number:'007'})
}) 
1
2
3
4
  1. toEqual():只要内容相等,就可以通过测试;不严格匹配但要求值相等
test('测试严格相等',()=>{
    const a = {number:'007'}   
    expect(a).toEqual({number:'007'})
}) 
1
2
3
4
  1. toBeNull():只匹配null值,需要注意的是不匹配undefined的值
test('toBeNull测试',()=>{
    const a = null   
    expect(a).toBeNull()
}) 
1
2
3
4
  1. toBeUndifined():匹配undefined
test('toBeUndefined测试',()=>{
    const a = undefined   
    expect(a).toBeUndefined()
}) 
1
2
3
4
  1. toBeDefined():只要定义过了,都可以匹配成功
test('toBeDefined测试',()=>{
    const a = 'test'  
    expect(a).toBeDefined()//注意给一个null值也是可以通过测试的
}) 
1
2
3
4
  1. toBeTruthy():判断真
test('toBeTruthy 测试',()=>{
    const a =1
    expect(a).toBeTruthy()
}) 

1
2
3
4
5
  1. toBeTruthy():判断假
test('toBeFalsy 测试',()=>{
    const a = 0
    expect(a).toBeFalsy()
}) 

1
2
3
4
5

# 五.匹配器(数字匹配)

  1. toBeGreaterThan():大于什么数值,只要大于传入的数值,就可以通过测试
test('toBeGreaterThan匹配器',()=>{
    const count = 10
    expect(count).toBeGreaterThan(9)//10大于9,通过测试
})
1
2
3
4
  1. toBeLessThan():少于时,就可以通过测
test('toBeLessThan匹配器',()=>{
    const count = 10
    expect(count).toBeLessThan(11)
})
1
2
3
4
  1. toBeGreaterThanOrEqual():大于等于
  2. toBeGreaterThanOrEqual():小于等于

# 六.匹配器

  1. toMatch():字符串包含匹配器
test('toMatch匹配器',()=>{
    const str="a、b、c"
    expect(str).toMatch('a')
})
1
2
3
4

或用正则匹配

test('toMatch匹配器',()=>{
   test('toMatch匹配器',()=>{
    const str="a、b、c"
    expect(str).toMatch(/a/)
})
})
1
2
3
4
5
6
  1. toContain():数组的匹配器
test('toContain匹配器',()=>{
    const arr=['a','b','c']
    expect(arr).toContain('a')
})
1
2
3
4
  1. toThrow():专门对异常进行处理的匹配器,可以检测一个方法会不会抛出异常
const throwNewErrorFunc = ()=>{
    throw new Error('this is a new error')
}

test('toThrow匹配器',()=>{
    expect(throwNewErrorFunc).toThrow('this is a new error')
})
1
2
3
4
5
6
7
  1. not:相反或者说取反
const throwNewErrorFunc = ()=>{
    throw new Error('this is a new error')
}

test('toThrow匹配器',()=>{
    expect(throwNewErrorFunc).not.toThrow()//测试用例就不能通过测试了,我们需要删除或注释掉抛出的异常,才可以通过测试
})
1
2
3
4
5
6
7

# 七.让Jest支持import和ES6语法

目前我们的Jest是不支持import...from....这种形式,如果使用就会报错,因为Jest默认支持的是CommonJS规范,也就是Node.js中的语法,他只支持require这种引用

  1. 使用Babel转换器

安装一下Babel.

npm install @babel/core@7.4.5 @babel/preset-env@7.4.5 -D
1

或者直接使用yarn来进行安装

yarn add  @babel/core@7.4.5 @babel/preset-env@7.4.5  --dev
1

耐心等待babel安装完成,然后打开package.json文件,可以看到文件里有这样两行代码。

 "devDependencies": {
    "@babel/core": "^7.4.5",
    "@babel/preset-env": "^7.4.5",
    "jest": "^24.8.0"
  },

1
2
3
4
5
6

看到这样的代码,说明Babel已经安装成功。然后我们还需要对Babel进行配置。 2. Babel基本配置 在项目根目录下新建一个.babelrc的文件

{
    "presets":[
        [
                "@babel/preset-env",{
                "targets":{
                    "node":"current"
                }
            }
        ]
    ]
}
1
2
3
4
5
6
7
8
9
10
11

当写完这段代码后,就可以进行转换了。再次使用yarn test进行测试,这时候就可以正确通过测试了。也就是说我们用的babel起到作用了。

那为什么会这样那?其实在Jest里有一个babel-jest组件,我们在使用yarn test的时候,它先去检测开发环境中是否安装了babel,也就是查看有没有babel-core,如果有bable-core就会去查看.babelrc配置文件,根据配置文件进行转换,转换完成,再进行测试。

# 八.异步代码测试方法

  1. 回调函数式 fetchData.js
import axios from 'axios'

export const fetchData = (fn)=>{
    axios.get(您的url)
    .then((response)=>{
        fn(response.data)
    })
}
1
2
3
4
5
6
7
8

fetchData.test.js

import { fetchData } from './fetchData.js'
test('fetchData 测试',(done)=>{
   fetchData((data)=>{
       expect(data).toEqual({
           success: true
       })
       done()//加入一个done方法,保证我们的回调已经完成了,这时候我们表示测试完成。
   })
  })
1
2
3
4
5
6
7
8
9
  1. 直接返回promise fetchData.js
export const fetchTwoData = ()=>{
    return axios.get(您的url)
}
1
2
3

fetchData.test.js

import { fetchTwoData } from './fetchData.js'
test('FetchTwoData 测试', ()=>{
       return  fetchTwoData().then((response)=>{
            expect(response.data).toEqual({
                success: true
            })
        })//注意的是要使用return才能测试成功
  })
1
2
3
4
5
6
7
8
  1. 不存在的接口测试方法 fetchData.js
export const fetchThreeData = ()=>{
    return axios.get(您的url)
}
1
2
3

fetchData.test.js

test('FetchThreeData 测试', ()=>{
      expect.assertions(1)  // 断言,必须执行一次expect
      return fetchThreeData().catch((e)=>{
        expect(e.toString().indexOf('404')> -1).toBe(true)

      })
  })
1
2
3
4
5
6
7
  1. async...await fetchData.js
export const fetchFourData = ()=>{
    return axios.get(您的url)
}
1
2
3

fetchData.test.js

test('FetchFourData 测试', async()=>{
        const response  = await fetchFourData()
        expect(response.data).toEqual({
            success : true
        })
})
1
2
3
4
5
6

# 九.Jest中的四个钩子函数

  1. beforeAll()钩子函数的意思是在所有测试用例之前进行执行。
  2. afterAll()钩子函数是在完成所有测试用例之后才执行的函数。
  3. beforeEach()钩子函数,是在每个测试用例前都会执行一次的钩子函数
  4. afterEach()钩子函数,是在每次测试用例完成测试之后执行一次的钩子函数

# 十.Jest中对测试用例进行分组

Jest为我们提供了一个分组的语法describe(),这个方法接受两个参数

describe('a类相关测试',()=>{
  test(描述,()=>{
   测试内容
})
test(描述,()=>{
   测试内容
})
})
describe('b类相关测试',()=>{
  test(描述,()=>{
    测试内容
  })
  test(描述,()=>{
    测试内容
  })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 十一.钩子函数的作用域

  • 钩子函数在父级分组可作用域子集,类似继承
  • 钩子函数同级分组作用域互不干扰,各起作用
  • 先执行外部的钩子函数,再执行内部的钩子函数

# 【参考】

  • Jest官网:https://jestjs.io/docs/en/expect
  • https://jspang.com/detailed?id=65