51Testing软件测试论坛

标题: 前端测试之Jest单元测试 [打印本页]

作者: lsekfe    时间: 2020-8-27 10:14
标题: 前端测试之Jest单元测试
一、Jest 简介
  1.优势:速度快、API简单、配置简单
  2.前置:Jest 不支持 ES Module 语法,需要安装 babel
  1.  npm install -D @babel/core @babel/preset-env
复制代码
 .babelrc
  1. {
  2.     "presets": [
  3.       [
  4.         "@babel/preset-env", {
  5.           "targets": {
  6.             "node": "current"
  7.           }
  8.         }
  9.       ]
  10.     ]
  11.   }
复制代码
 Jest 在运行前会检查是否安装 babel,如果安装了会去取 .babelrc 文件,结合 babel 将代码进行转化,运行转化后的代码。
  3. Jest 默认配置
  1. npx jest --init
复制代码
 4.Jest 模式
  ·jest --watchAll:当发现测试文件变动,将所有测试文件重新跑一遍
  ·jest --watch:需要和 git 结合使用,会比较现有文件和 commit 的文件的差异,只测试差异文件
  二、Jest 匹配器
  常见匹配器
  ·toBe
  ·toEqual:判断对象内容是否相等
  ·toMatchObject:expect(obj).toMatchObject(o),期望 o 中包含 obj
  ·toBeNull
  ·toBeUndefined
  ·toBeDefinded
  ·toBeTruthy
  ·toBeFalsy
  ·not:用于否定,比如 .not.toBeTruthy()
  Number 相关
  ·toBeGreaterThan(大于) / toBeGreaterThanOrEqual(大于等于)
  ·toBeCloseTo:用于比较浮点数,近似相等时断言成立
  ·toBeLessThan / toBeLessThanOrEqual
  String 相关
  ·toMatch:参数可以传字符串或正则
  Array Set 相关
  ·toContain
  异常匹配器
  ·toThrow:
  1. const throwError = () => {
  2.     throw new Error('error')
  3.   }
  4.   it('can throw error', () => {
  5.     expect(throwError).toThrow('error') // 判断throw函数可以抛出异常,异常信息为 "error"。也可以写正则
  6.   })
复制代码
这里有个小技巧:当我们想忽略掉单个文件中的其他测试用例,只针对一个测试用例做调试的时候,可以加上 .only
  1. it.only('test', () => {
  2.     // ...
  3.   })
复制代码
但这并不会忽略其他测试文件的测试用例
  三、测试异步代码
  这里有三个异步方法,对这三个方法进行代码测试,"www.dell-lee.com/react/api/d…" 会返回 {success: true},
  "www.dell-lee.com/react/api/4…" 则不存在。
  1.  import axios from 'axios'
  2.   export function getData1() {
  3.     return axios.get('http://www.dell-lee.com/react/api/demo.json')
  4.   }
  5.   export function getData2(fn) {
  6.     axios.get('http://www.dell-lee.com/react/api/demo.json').then(res => {
  7.       fn(res)
  8.     })
  9.   }
  10.   export function get404() {
  11.     return axios.get('http://www.dell-lee.com/react/api/404.json')
  12.   }
复制代码
对于异步代码测试,时机很重要,必须保证我们的测试用例在异步代码走完之后才结束。有以下几种办法:
  1.done,控制测试用例结束的时机
  2.如果函数执行的返回值是 Promise,将这个 Promise return 出去
  3.async + await
  1.  import {getData1, getData2, get404} from './fetchData/fetchData'
  2.   it('getData1 方法1', (done) => {
  3.     getData1().then(res => {
  4.       expect(res.data).toEqual({
  5.         success: true
  6.       })
  7.       done()  // 如果不加 done,还没执行到 .then 方法,测试用例已经结束了
  8.     })
  9.   })
  10.   it('getData1 方法2', () => {
  11.     return getData1().then(res => {
  12.       expect(res.data).toEqual({
  13.         success: true
  14.       })
  15.     })
  16.   })
  17.   it('getData2 方法2', (done) => {
  18.     getData2((res) => {
  19.       expect(res.data).toEqual({
  20.         success: true
  21.       })
  22.       done()
  23.     })
  24.   })
  25.   it('getData1 方法3', async () => {
  26.     const res = await getData1()
  27.     expect(res.data).toEqual({
  28.       success: true
  29.     })
  30.   })
  31.   /*********** 重点关注 ***********/
  32.   it('get404', (done) => {
  33.     expect.assertions(1)
  34.     get404().catch(r => {
  35.       expect(r.toString()).toMatch('404')
  36.       done()
  37.     })
  38.   })
复制代码
重点讲一下上面的最后一个测试用例,假设我们现在有一个返回的是 404 的接口,我们需要对这个接口测试,期望他返回 404。
  我们用 catch 捕获,在 catch 中判断。
  但是,假如这个接口返回的不是 404,而是正常返回 200,这个 catch 则不会执行,expect 也不会执行,测试依然是通过的。这不符合我们的预期!所以,我们需要加上 expect.assertions(1) 进行断言:下面一定会执行一个 expect
  当然,也可以用 async await 方法进行 404 接口的测试
  1.  it('get404 方法3', async () => {
  2.     await expect(get404()).rejects.toThrow()
  3.   })
复制代码













欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2