jest 自动化测试

概述

jest 是 facebook 开源的,用来进行单元测试的框架,能够测试 javascipt 和 react。 单元测试各类好处已经被说烂了,这里就很少扯了。重点要说的是,使用 jest, 能够下降写单元测试的难度。javascript

单元测试作得好,可以极大提升软件的质量,加快软件迭代更新的速度, 可是,单元测试也不是银弹,单元测试作得好,并非测试框架好就行,其实单元测试作的好很差,很大程度上取决于代码写的是否易于测试。 单元测试不单单是测试代码,经过编写单元测试 case,也能够反过来重构已有的代码,使之更加容易测试。html

jest 的零配置思路是我最喜欢的特性。前端

安装方式

# yarn
yarn add --dev jest

# OR npm
npm install --save-dev jest

测试方式

随着 node.js 的发展,javascipt 语言的发展,前端能够胜任愈来愈多的工做,后端不少时候反而沦为数据库的 http API 因此前端不单单是测试看得见的页面,还有不少看不见的逻辑须要测试。java

jest 提供了很是方便的 API,能够对下面的场景方便的测试node

通常函数

对于通常的函数,参考附录中的 jest Expect API 能够很容易的写测试 case 待测试文件:joinPath.jsreact

const separator = '/'
const replace = new RegExp(separator + '{1,}', 'g')
export default (...parts) => parts.join(separator).replace(replace, separator)

测试文件的命名:joinPath.test.js 采用这种命名,jest 会自动找到这个文件来运行git

import joinPath from 'utils/joinPath'

test('join path 01', () => {
  const path1 = '/a/b/c'
  const path2 = '/d/e/f'

  expect(joinPath(path1, path2)).toBe('/a/b/c/d/e/f')
})

test('join path 02', () => {
  const path1 = '/a/b/c/'
  const path2 = '/d/e/f'

  expect(joinPath(path1, path2)).toBe('/a/b/c/d/e/f')
})

test('join path 03', () => {
  const path1 = '/a/b/c/'
  const path2 = 'd/e/f'

  expect(joinPath(path1, path2)).toBe('/a/b/c/d/e/f')
})

异步函数

上面的是普通函数,对于异步函数,好比 ajax 请求,测试写法一样容易 待测试文件:utils/client.jsgithub

export const get = (url, headers = {}) => {
  return fetch(url, {
    method: 'GET',
    headers: {
      ...getHeaders(),
      ...headers
    }
  }).then(parseResponse)
}

测试文件:client.test.jsajax

import { get } from 'utils/client'

test('fetch by get method', async () => {
  expect.assertions(1)
  // 测试使用了一个免费的在线 JSON API
  const url = 'https://jsonip.com/'

  const data = await get(url)
  const { about } = data
  expect(about).toBe('/about')
})

测试的生命周期

jest 测试提供了一些测试的生命周期 API,能够辅助咱们在每一个 case 的开始和结束作一些处理。 这样,在进行一些和数据相关的测试时,能够在测试前准备一些数据,在测试后,清理测试数据。数据库

4 个主要的生命周期函数:

  • afterAll(fn, timeout): 当前文件中的全部测试执行完成后执行 fn, 若是 fn 是 promise,jest 会等待 timeout 毫秒,默认 5000
  • afterEach(fn, timeout): 每一个 test 执行完后执行 fn,timeout 含义同上
  • beforeAll(fn, timeout): 同 afterAll,不一样之处在于在全部测试开始前执行
  • beforeEach(fn, timeout): 同 afterEach,不一样之处在于在每一个测试开始前执行
BeforeAll(() => {
  console.log('before all tests to excute !')
})

BeforeEach(() => {
  console.log('before each test !')
})

AfterAll(() => {
  console.log('after all tests to excute !')
})

AfterEach(() => {
  console.log('after each test !')
})

Test('test lifecycle 01', () => {
  expect(1 + 2).toBe(3)
})

Test('test lifecycle 03', () => {
  expect(2 + 2).toBe(4)
})

mock

我本身以为能不 mock,仍是尽可能不要 mock,不少时候以为代码很差测试而使用 mock,还不如看看如何重构代码,使之不用 mock 也能测试。 对于某些函数中包含的一些用时过长,或者调用第三方库的地方,而这些地方并非函数的主要功能, 那么,能够用 mock 来模拟,从而提升测试执行的速度。

对于上面异步函数的例子,咱们改形成 mock 的方式:

const funcUseGet = async url => {
  return await get(url)
}

test('mock fetch get method', async () => {
  const client = require('utils/client')
  client.get = jest.fn(url => ({ mock: 'test' }))

  const url = 'http://mock.test'
  const data = await funcUseGet(url)

  expect(data).toEqual({ mock: 'test' })
})

react 测试

jest 能够测试 react component,可是咱们用了状态分离的方式开发前端, 大部分功能都在 action 中,这部分测试基本没有作。

附录

相关文章
相关标签/搜索