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 個主要的生命週期函數:
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 的方式:
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' }) })
jest 能夠測試 react component,可是咱們用了狀態分離的方式開發前端, 大部分功能都在 action 中,這部分測試基本沒有作。