Jest單元測試入門

單元測試主要包含斷言、測試框架、測試用例、測試覆蓋率、mock、持續集成等幾個方面,因爲Node的特殊性,它還會加入異步代碼測試和私有方法的測試這兩個部分。html

斷言

在程序設計中,斷言是一種放在程序中的一階邏輯(如一個結果爲真或是假的邏輯判斷式),目的是爲了標示程序開發者預期的結果——當程序運行到斷言的位置時,對應的斷言應該爲真。若斷言不爲真,程序會停止運行,並出現錯誤信息。node

斷言用於檢查程序在運行時是否知足指望。ios

node自帶斷言就是assert模塊,具體使用請查看官方文檔:地址npm

const assert = require('assert');
assert.equal(Math.max(1, 100), 100);
複製代碼

經常使用的第三方斷言庫有chai,官方地址:連接json

chai

測試框架

前面提到斷言一旦檢查失敗,將會拋出異常中止整個應用,這對於作大規模斷言檢查時並不友好。更通用的作法是,記錄下拋出的異常並繼續執行,最後生成測試報告。這些任務的承擔者就是測試框架。axios

經常使用的第三方測試框架有mocha,jest,他們之間的區別在於jest內容更加全面,集成了斷言,jsdom模擬瀏覽器DOM環境。api

jest

測試用例

每一個功能至少要包含一個測試用例,今天介紹jest寫測試用例,先安裝jest和@types/jest,後面這個是類型聲明文件,能夠幫助咱們在寫代碼的時候會有語法提示。promise

npm i jest @types/jest
複製代碼

默認會測試spec和test結尾的js文件,全部寫單元測試的文件名必須是sum.spec.js或者sum.test.js這個的格式。瀏覽器

jest

而後須要在package.json裏面增長一段腳本bash

{
  "scripts": {
    "test": "jest"
  }
}
複製代碼

經過運行npm run test最後會生成測試報告

jest

在測試用例中使用it語法表示一個用例,expect表示預期結果,toBe表示三個等號的比較,若是條件成立單元測試便可經過。

匹配器

至關,不相等,包含,等等,匹配的關係

// describe表示分組,分組裏面一個個的用例
describe('測試基本方法', () => {
  it('測試sum函數', () => {
    expect(sum(1, 2)).toBe(3)
  })
  it('測試1+1=2', () => {
    expect(1 + 1).toBe(2)
  })
  it ('對象比較', () => {
    expect({name: 1}).toEqual({name: 1})
  })
})

it('測試不相等', () => {
  expect(1+1).not.toBe(3) // 1+1不等3
  expect(3).toBeLessThan(5) // 3<5
})

it('測試包含', () => {
  expect('hello').toContain('h') // 參數是字符串
  expect('hello').toMatch(/h/) // 參數能夠是正則
})
複製代碼

測試DOM

it('測試刪除DOM', () => {
  document.body.innerHTML = `<div><button></button></div>`

  let button = document.querySelector('button')
  expect(button).not.toBe(null)

  // 本身寫的移除的DOM方法
  removeNode(button);

  button = document.querySelector('button')
  expect(button).toBe(null)
})
複製代碼

測試異步

// 回調
export const getDataCallback = fn => {
  setTimeout(() => {
    fn({name: 'callback'})
  }, 1000);
}

// promise
export const getDataPromise = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({name: 'promise'})
    }, 1000);
  })
}

複製代碼
import { getDataCallback, getDataPromise } from '../util'

// 異步回調
it('測試回調函數', (done) => {
  // done參數
  getDataCallback((data) => {
    expect(data).toEqual({ name: 'callback' })
    done() // 標識調用完成
  })
})

it('測試promise', () => {
  // 返回的promise會等待完成
  return getDataPromise().then(data => {
    expect(data).toEqual({ name: 'promise' })
  })
})

it('測試promise', async () => {
  // 使用await語法
  const data = await getDataPromise()
  expect(data).toEqual({ name: 'promise' })
})

複製代碼

mock

若是咱們要測試接口,好比使用axios發送api請求

import axios from 'axios'
// 測試接口調用
export const fetchUser = () => {
  return axios.get('/list')
}
複製代碼

咱們並不會真實的發送API請求,而是模擬數據返回,這個時候能夠在__mocks__下面建axios.js文件,jest就不會再使用node_modules文件中的axios發請求了,而是使用咱們本身寫的axios模塊。

// mock axios
export default {
  get(url) {
    return new Promise((resolve, reject) => {
      // 根據請求路徑mock數據
      if (url === '/list') {
        resolve({ name: 'hello' })
      }
    })
  }
}
複製代碼
import { fetchUser } from '../api'

it('測試請求列表', async () => {
  // 把請求的邏輯mock
  const data = await fetchUser()
  expect(data).toEqual({name: 'hello'})
})
複製代碼

測試覆蓋率

想要查看測試覆蓋率,咱們須要先生成配置文件,經過命令

npx jest --init
複製代碼

而後還須要在package.json中添加一段腳本

{
  "scripts": {
    "test": "jest --coverage"
  }
}
複製代碼

經過命令運行npm run test最後會生成測試覆蓋率

jest
還會在coverage目錄的lcov-report目錄裏生成HTML文件,能夠經過瀏覽器打開查看。

測試風格

咱們將測試用例的不一樣組織方式稱爲測試風格,現今流行的單元測試風格主要有TDD(測試驅動開發)和BDD(行爲驅動開發)兩種。

關注點不一樣。

  1. TDD關注全部功能是否被正確實現,每個功能都具有對應的測試用例;通常爲先寫好測試用例,而後再開發代碼,這樣就可讓測試用例覆蓋全部代碼。
  2. BDD關注總體行爲是否符合預期,適合自頂向下的設計方式。通常是先開發代碼,再寫單元測試。這個較爲經常使用。
相關文章
相關標籤/搜索