Jest

Jest是 Facebook 的一套開源的 JavaScript 測(cè)試框架, 它自動(dòng)集成了斷言、JSDom、覆蓋率報(bào)告等開發(fā)者所需要的所有測(cè)試工具,是一款幾乎零配置的測(cè)試框架。并且它對(duì)同樣是 Facebook 的開源前端框架 React 的測(cè)試十分友好。

1. 全局安裝

yarn global add jestnpm install jest --global
這樣就可以通過(guò)命令行直接運(yùn)行Jest
yarn與npm對(duì)比

2. 結(jié)合babel使用jest

安裝所需的依賴:
yarn add --dev babel-jest @babel/core @babel/preset-env

還需安裝@babel/plugin-transform-runtime@babel/runtime,不然測(cè)試會(huì)報(bào)錯(cuò)

  • .babelrc文件配置
    可以在工程的根目錄下創(chuàng)建一個(gè)babel.config.js文件用于配置與你當(dāng)前Node版本兼容的Babel
{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "node": "current"
      }
    }]
  ],
  "plugins": ["@babel/plugin-transform-runtime"]
}
  • package.json配置
  "jest": {
    // moduleNameMapper:  一種正則表達(dá)式到模塊名的映射,匹配到的文件的內(nèi)容可以是空的
    // 可以通過(guò)該參數(shù),來(lái)mock一些圖片,css等靜態(tài)資源文件
    // 因?yàn)槲覀冊(cè)跍y(cè)試的時(shí)候?qū)嶋H上是不太需要這些文件的,但是有需要引入它作為環(huán)境上的依賴。
    "moduleNameMapper": {
      "^vue$": "vue/dist/vue.common.js"
    },
    // moduleFileExtensions: 讓jest知道你需要測(cè)試覆蓋的文件的擴(kuò)展名都是什么。
    "moduleFileExtensions": [
      "js",
      "vue"
    ],
    //  transform: 簡(jiǎn)單來(lái)說(shuō)就是轉(zhuǎn)換器,正則匹配到的文件可以通過(guò)對(duì)應(yīng)模塊的轉(zhuǎn)換器來(lái)解決一些未來(lái)版本語(yǔ)法時(shí)可以使用它。通過(guò)正則來(lái)匹配文件,為匹配到的文件使用對(duì)應(yīng)的模塊
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
    }
  }

注意: jest24不支持babel6

  • 如要使用jest24,可以將babel升級(jí)到版本7
  • 如果babel不能升級(jí)到7,那么就使用jest23
  • babel不能升級(jí)到7,要使用jest24,那么就將babel-test版本鎖在23

3. 匹配器

常用匹配器:

  • 普通匹配器: toBe, toEqual
  • Truthiness: toBeNull,toBeUndefined,toBeDefined,toBeTruthy,toBeFalsy
  • 數(shù)字: toBeGreaterThan,toBeGreaterThanOrEqual,toBeLessThan,toBeLessThanOrEqual,toBeCloseTo
  • 字符串:toMatch
  • 數(shù)組:toContain

4. 測(cè)試用例

Jest會(huì)自動(dòng)找到項(xiàng)目中所有使用.test.js文件命名的測(cè)試文件并執(zhí)行,通常我們?cè)诰帉憸y(cè)試文件時(shí)遵循的命名規(guī)范:測(cè)試文件的文件名 = 被測(cè)試模塊名 + .test.js,例如被測(cè)試模塊為functions.js,那么對(duì)應(yīng)的測(cè)試文件命名為functions.test.js。

快照測(cè)試

只要想確保UI不會(huì)意外更改,快照測(cè)試是非常有用的工具。(其實(shí)就是運(yùn)行測(cè)試的時(shí)候,把結(jié)果存一份,之后闊以用來(lái)對(duì)比,對(duì)比不上就測(cè)試不通過(guò))

// Snapshot Testing
it('will fail every time', () => {
  const user = {
    createdAt: new Date(),
    id: Math.floor(Math.random() * 20),
    name: 'LeBron James',
  }

  // expect () 返回一個(gè)"期望"的對(duì)象
  expect(user).toMatchSnapshot()
})

The first time this test is run, Jest creates a snapshot file that looks like this:

exports[`will fail every time 1`] = `
Object {
  "createdAt": 2019-12-13T02:11:50.571Z,
  "id": 1,
  "name": "LeBron James",
}
`;

Jest使用pretty-format對(duì)快照文件進(jìn)行了處理,當(dāng)代碼在審查期間,會(huì)讓代碼快照變成讓人類可閱讀的文件。
jest --updateSnapshot更新快照

測(cè)試異步

單元測(cè)試的核心之一就是測(cè)試方法的行為是否符合預(yù)期,在測(cè)試時(shí)要避免一切的依賴,將所有的依賴都mock掉

  1. 回調(diào):一種最常見的異步編程模式
    錯(cuò)誤示例:
  // 不要這么做!
  //  一旦 fetchData 執(zhí)行完畢,測(cè)試隨即完畢,而不會(huì)等待 callback 回調(diào)的執(zhí)行。
test('the data is peanut butter', () => {
  function callback(data) {
    expect(data).toBe('peanut butter')
  }

  fetchData(callback)
})

正確示例:

// 使用一個(gè)名為 done 的參數(shù),Jest 會(huì)一直等待 done 回調(diào)的執(zhí)行,一旦 done 回調(diào)執(zhí)行完畢,測(cè)試即完成。
// 如果 done 一直沒(méi)有被回調(diào),那么測(cè)試失敗。
test('the data is peanut butter', done => {
  function callback(data) {
    expect(data).toBe('peanut butter');
    done()
  }

  fetchData(callback)
})
  1. Promise
    只需要在測(cè)試中返回一個(gè) promise,Jest 會(huì)自動(dòng)等待 promise 被解析處理,如果 promise 被拒絕,那么測(cè)試失敗。
test('the data is peanut butter', () => {
   // expect.assertions 來(lái)驗(yàn)證一定數(shù)量的斷言被調(diào)用。 否則一個(gè)fulfilled態(tài)的 Promise 不會(huì)讓測(cè)試失敗
  expect.assertions(1)
  return fetchData().then(data => {
    expect(data).toBe('peanut butter');
  })
})

test('the fetch fails with an error', () => {
  expect.assertions(1);
  return fetchData().catch(e => {
    expect(e).toMatch('error')
  })
})

5. 在webpack項(xiàng)目中用

  • (1)如果你的項(xiàng)目使用了babel轉(zhuǎn)換,具體的配置,參見上述第二個(gè)菜單
    (2)如果你的項(xiàng)目沒(méi)有使用babel轉(zhuǎn)換,可以配置Jest的transform參數(shù)來(lái)進(jìn)行轉(zhuǎn)換
  • 接下來(lái),讓我們配置Jest,使其優(yōu)雅地處理資源文件,如樣式表和圖像。 通常,這些文件在測(cè)試中無(wú)足輕重,因?yàn)槲覀兛梢园踩豰ock他們。 然而, 如果你使用CSS模塊,那么最好是給你的類名查找模擬一個(gè)代理。
// package.json
{
  "jest": {
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
    }
  }
}

6. 在react項(xiàng)目中使用

  • (1) 使用create react app:
    它已經(jīng)包含了 可用的 Jest! 您只需要添加 react-test-renderer 來(lái)渲染快照。
    yarn add --dev react-test-renderer
    (2) 不使用create react app:
    yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer

  • 配置

// babel.config.js
module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react'],
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容