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 中,這部分測試基本沒有作。

附錄

相關文章
相關標籤/搜索