Jest测试框架笔记

1,617 阅读5分钟
  • 主流的测试框架有 Jasmine、 MOCHA、 Jest等。
  • 相比来说Jest比其他的测试框架比较新,Jest的优点有基础好、速度快、API简单、隔离性好、多项目运行(如React写前台,node写后台俩者可以并行)、覆盖率
## 安装命令
npm install jest@24.8.0 -D
## 因为测试框架在开发环境中使用,所有加上 -D 这样只会在开发环境中使用这个包,不会打包到生产环境中。

## 将package.json文件的scripts标签的值修改为jest即可运行测试
{
  "name": "jest_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "jest": "^24.8.0"
  }
}

单元测试和集成测试

  • 单元测试是指对软件中最小的可测试单元进行检测和校验,前端所说的单元测试就是对一个模块进行测试。也就是说前端测试的时候,测试的一定是一个模块。
  • 集成测试则是组装测试。在单元测试的基础上,将所有模块按照涉及要求组装成子系统进行集成测试。(也就是说把所有模块组合起来测试)

Jest的初始化配置

npx jest --init

  • 输入完命令后会出现选项,主要是资讯运行环境和是否生成测试覆盖率文件,在根目录下多了一个jest.config.js的文件,里面都是Jest的配置项。

coverageDirectory

在jest.config.js文件中的这个配置项是用来生成代码覆盖率文件的

  • 在控制台中输入 npx jest --coverage 命令会生成一个coverage文件夹里面就是测试的报告

jest的匹配器

  • jest中可以测试类似于数据的类型是否一致
toBe           严格匹配 似于    ===
toEqual        不严格匹配 类似于 == 
toBeNull       可以匹配 Null
toBeUndefined  可以匹配undefined
toBeDefined    只要是定义了都可以匹配成功
toBeTruthy     匹配为真
toBeFalsy      匹配为假
toBeGreaterThanOrEqual  大于等于
toBeCloseTo    可以校验浮点数
toMatch		   匹配字符串
toContain	   匹配数组
toThrow		   校验有异常,有异常则通过
not.toThrow	   检测没有异常

jest 自动测试

  • 只需要在package.json文件的scripts标签的值加上 --watchAll 运行 npm run test命令之后,只要修改测试文件即可自动测试

jest支持ES6

  • jest 是不支持es6的,使用安装命令 cnpm install @babel/core@7.4.5 @babel/preset-env@7.4.5 --dev
  • 在根目录中新建一个 .babelrc 文件里面配置上
{
    "presets": [
        [
            "@babel/preset-env",{
                "targets":{
                    "node":"current"
                }
            }
        ]
    ]
}

异步代码测试方法

  • 回调函数方式
    • 使用axios库来做网络请求,安装命令 cnpm install axios@0.19.0 --save
import { fetchData } from './fetchData'

test('网络请求', (done) => {
    fetchData(data=>{
        expect(data).toEqual({
            "msg":"hello!!"
        })
        done()
    })
})
## 网络请求必须加入done方法, 来保证我们的回调已经完成了
	如果没有done方法即使请求错误  也会显示正确

jest的断言

  • 在测试404直接使用catch就可以很简单的获取请求错误
test("测试404", ()=>{
	return fetchThreeData().catch((e)=>{
    	expect(e.toString().indexOf('404') > -1).toBe(true)
    })
})
  • 这样的确可以获取抛出的错误,并测试通过。但是如果网页没抛出错误,jest检测也不会报错。
  • 因为请求没有抛出错误,我却调用了catch方法。由于没有异常不走这个方法。jest会默认通过这个测试。

像这种情况就需要用到jest的断言。使用了它就必须执行一次 expect

test("测试404", ()=>{
	expect.assertions(1) // Jest断言
	return fetchThreeData().catch((e)=>{
    	expect(e.toString().indexOf('404') > -1).toBe(true)
    })
})
// 现在测试用例就不会通过测试了。因为我们测试是测试请求报错。这样子的代码在突发情况下的健壮性更好

异步代码

  • 使用 async ... await 的形式
    • async函数返回一个Promise对象,当函数执行的时候,一旦遇到await就会先返回。等到触发的异步操作完成,才会接着执行函数体内后面的语句。
    • await关键字后面需要一个promise对象,如诺不是,则需要调用resolve转换它

test('测试', async()=>{
	await expect(fetchFourData()).resolves.toMatchObject({
    	// 使用resolves把当前的对象转为promise对象
        // toMatchObject 匹配对象中的所有属性
    	data:{
        	success:true
        }
    })
})

Jest的钩子函数

  • 如果有vue或者react开发的经历,钩子函数不用太多的介绍。没有这些开发经历一般也不会用到自动化测试吧。 哈哈哈

  • Jest的钩子主要分4个

    • beforeAll() 所有测试用例之前调用

    • afterAll() 所有测试用例之后调用

    • beforeEach() 每一个测试用例触发前调用(有几个就触发几次)

    • afterEach() 每一个测试用例测试完成调用(有几个就触发几次)

Jest分组

  • jest 提供了一个分组的方法describe() 这个方法有俩个参数
    • 字符串 ———— “命名”
    • 回调函数 ———— 放置测试方法
describe('菊经纬组',()=>{
   test(' 按脚 ', () => {
       baojian.gongzhu(1)
       baojian.AnJiao()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '鞠倩伟来按脚' )
   })
   test(' 宫廷 ', () => {
       baojian.gongzhu(1)
       baojian.gtzl()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '鞠倩伟来宫廷主撩' )
   })
})

钩子函数作用域

  • 钩子函数在父级分组可作用域子集,类似继承
  • 钩子函数同级分组作用域互不干扰,各起作用
  • 先执行外部的钩子函数,再执行内部的钩子函数
/**
* 测试用例分组
*/
describe('菊经纬组',()=>{
   beforeAll(()=>{
       console.log('菊经纬组___最早执行');
   })
   test(' 按脚 ', () => {
       baojian.gongzhu(1)
       baojian.AnJiao()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '鞠倩伟来按脚' )
   })
   test(' 宫廷 ', () => {
       baojian.gongzhu(1)
       baojian.gtzl()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '鞠倩伟来宫廷主撩' )
   })
})

/**
* 测试用例分组
*/

describe('三橘彩花组',()=>{
   afterEach(()=>{
       console.log('三橘彩花组测试方法完成后,都会执行');
   })
   test(' 按摩 ', () => {
       baojian.gongzhu(2)
       baojian.AnMo()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '三橘彩花来按摸' )
   })
   test(' 台式 ', () => {
       baojian.gongzhu(2)
       baojian.taishi()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '三橘彩花来台式保健' )
   })
})
/*
 console.log fetchData/newBaoJian.test.js:31
     菊经纬组___最早执行
   console.log fetchData/newBaoJian.test.js:36
     鞠倩伟来按脚
   console.log fetchData/newBaoJian.test.js:42
     鞠倩伟来宫廷主撩
   console.log fetchData/newBaoJian.test.js:58
     三橘彩花来按摸
   console.log fetchData/newBaoJian.test.js:53
     三橘彩花组测试方法完成后,都会执行
   console.log fetchData/newBaoJian.test.js:64
     三橘彩花来台式保健
   console.log fetchData/newBaoJian.test.js:53
     三橘彩花组测试方法完成后,都会执行
*/

Jest知识新添 ———— only

  • 使用这个方法会只执行当前这条测试用例
describe('菊经纬组',()=>{
   beforeAll(()=>{  
       console.log('菊经纬组___最早执行');
   }) // 执行
   
   test.only(' 按脚 ', () => { 
       baojian.gongzhu(1)
       baojian.AnJiao()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '鞠倩伟来按脚' )
   }) // 执行
   
   test(' 宫廷 ', () => { 
       baojian.gongzhu(1)
       baojian.gtzl()
       console.log( baojian.fuwu );
       expect( baojian.fuwu ).toEqual( '鞠倩伟来宫廷主撩' )
   }) // 不执行
})