日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

测试框架 Jest 实例教程

發布時間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 测试框架 Jest 实例教程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Jest 是由 Facebook 開源出來的一個測試框架,它集成了斷言庫、mock、快照測試、覆蓋率報告等功能。它非常適合用來測試 React 代碼,但不僅僅如此,所有的 js 代碼都可以使用 Jest 進行測試。

本文全面的介紹如何使用 Jest,讓后來者輕松上手。文中會選取重點部分直接貼出代碼,比較簡單的部分則不會,主要是寫到后面的時候發現貼的代碼有點多,沒什么意思,所有的代碼已上傳到 Github,可以自行查閱。

安裝

使用 yarn 安裝 Jest:

$ yarn add --dev jest 復制代碼

或使用 npm:

$ npm i -D jest 復制代碼

其中 --dev 和 -D 參數指明作為 devDependencies,這樣該依賴只會在開發環境下安裝,在生成環境下則不會。

在 package.json 文件中添加下面的內容:

"scripts": {"test": "jest" } 復制代碼

這樣我們就可以通過 yarn test 或 npm test 執行測試代碼。

同樣地,你也可以選擇全局安裝 Jest:

$ yarn global add jest $ # or npm i -g jest 復制代碼

這樣你就可以直接在命令行使用 jest 命令。如果你是本地安裝,但是也想在命令行使用 jest,可以通過 node_modules/.bin/webpack 訪問它的 bin 版本,如果你的 npm 版本在 5.2.0 以上,你也可以通過 npx jest 訪問。

使用 Babel

如果你在代碼中使用了新的語法特性,而當前 Node 版本不支持,則需要使用 Babel 進行轉義。

$ npm i -D babel-jest babel-core babel-preset-env 復制代碼

注意:如果你使用 babel 7,安裝 babel-jest 的同時還需要安裝其他依賴: npm i -D babel-jest 'babel-core@^7.0.0-0' @babel/core

Jest 默認使用 babel-jest(需要安裝) 進行代碼轉義,如果你需要添加額外的預處理器,則需要在 Jest 配置文件中顯示的定義 babel-jest 作為 JavaScript 處理器(因為一旦添加了 transform 配置,babel-jest 就不會自動載入了):

"transform": {"^.+\\.jsx?$": "babel-jest" }, 復制代碼

我們還需在根目錄下創建 .babelrc 文件:

{"presets": ["env"] } 復制代碼

我這里只使用了 babel-preset-env 預設,如果需要其他的轉換,見 babel。

基本用法

我們從一個基本的 Math 模塊開始。首先創建一個 math.js 文件:

// basic/math.jsconst sum = (a, b) => a + b const mul = (a, b) => a * b const sub = (a, b) => a - b const div = (a, b) => a / bexport { sum, mul, sub, div } 復制代碼

要測試這個 Math 模塊是否正確,我們需要編寫測試代碼。通常,測試文件與所要測試的源碼文件同名,但是后綴名為 .test.js 或者 .spec.js。我們這里則創建一個 math.test.js 文件:

// basic/math.test.jsimport { sum, mul, sub, div } from './math'test('Adding 1 + 1 equals 2', () => {expect(sum(1, 1)).toBe(2) })test('Multiplying 1 * 1 equals 1', () => {expect(mul(1, 1)).toBe(1) })test('Subtracting 1 - 1 equals 0', () => {expect(sub(1, 1)).toBe(0) })test('Dividing 1 / 1 equals 1', () => {expect(div(1, 1)).toBe(1) }) 復制代碼

執行 npm test Jest 將會執行所有匹配的測試文件,并最終返回測試結果:

在編輯器中運行

很多編輯器都能支持 Jest,如:Webstorm、VS Code、Atom 等。這里簡單地介紹下如何在 Webstorm 和 VS Code 中運行。

Webstorm

Webstorm 可能出現找不到變量等問題,在 Preferences | Languages & Frameworks | JavaScript | Libraries 中點擊 Download, 然后選擇 Jest 并下載即可。

Webstorm 可以識別測試代碼,在編輯器中點擊“相應的運行按鈕”即可運行,或使用快捷鍵 ctrl+shift+R(mac 中)。具體的操作可以參考我之前寫的 Node.js 中 使用 Mocha 進行單元測試的博客。

VS Code

要想在 VS Code 中運行,我們需要安裝 Jest 插件。

插件安裝完成后,如果你安裝了 Jest,它會自動的運行測試代碼。你可以可以手動的運行通過 Jest: Start Runner 命令,它會執行測試代碼并在文件發生修改后重新運行。

匹配器

匹配器用來實現斷言功能。在前面的例子中,我們只使用了 toBe() 匹配器:

test('Adding 1 + 1 equals 2', () => {expect(sum(1, 1)).toBe(2) }) 復制代碼

在此代碼中,expect(sum(1, 1)) 返回一個“期望”對象,.toBe(2) 是匹配器。匹配器將 expect() 的結果(實際值)與自己的參數(期望值)進行比較。當 Jest 運行時,它會跟蹤所有失敗的匹配器,并打印出錯誤信息。

常用的匹配器如下:

  • toBe 使用 Object.is 判斷是否嚴格相等。
  • toEqual 遞歸檢查對象或數組的每個字段。
  • toBeNull 只匹配 null。
  • toBeUndefined 只匹配 undefined。
  • toBeDefined 只匹配非 undefined。
  • toBeTruthy 只匹配真。
  • toBeFalsy 只匹配假。
  • toBeGreaterThan 實際值大于期望。
  • toBeGreaterThanOrEqual 實際值大于或等于期望值
  • toBeLessThan 實際值小于期望值。
  • toBeLessThanOrEqual 實際值小于或等于期望值。
  • toBeCloseTo 比較浮點數的值,避免誤差。
  • toMatch 正則匹配。
  • toContain 判斷數組中是否包含指定項。
  • .toHaveProperty(keyPath, value) 判斷對象中是否包含指定屬性。
  • toThrow 判斷是否拋出指定的異常。
  • toBeInstanceOf 判斷對象是否是某個類的實例,底層使用 instanceof。

所有的匹配器都可以使用 .not 取反:

test('Adding 1 + 1 does not equal 3', () => {expect(1 + 1).not.toBe(3) }) 復制代碼

對于 Promise 對象,我們可以使用 .resolves 和 .rejects:

// .resolves test('resolves to lemon', () => {// make sure to add a return statementreturn expect(Promise.resolve('lemon')).resolves.toBe('lemon') })// .rejects test('rejects to octopus', () => {// make sure to add a return statementreturn expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus',) }) 復制代碼

異步測試

JavaScript 代碼中常常會包含異步代碼,當測試異步代碼時,Jest 需要知道什么時候異步代碼執行完成,在異步代碼執行完之前,它會去執行其他的測試代碼。Jest 提供了多種方式測試異步代碼。

回調函數

當執行到測試代碼的尾部時,Jest 即認為測試完成。因此,如果存在異步代碼,Jest 不會等待回調函數執行。要解決這個問題,在測試函數中我們接受一個參數叫做 done,Jest 將會一直等待,直到我們調用 done()。如果一直不調用 done(),則此測試不通過。

// async/fetch.js export const fetchApple = (callback) => {setTimeout(() => callback('apple'), 300) }// async/fetch.test.js import { fetchApple } from './fetch'test('the data is apple', (done) => {expect.assertions(1)const callback = data => {expect(data).toBe('apple')done()}fetchApple(callback) }) 復制代碼

expect.assertions(1) 驗證當前測試中有 1 處斷言會被執行,在測試異步代碼時,能確保回調中的斷言被執行。

Promise

如果異步代碼返回 Promise 對象,那我們在測試代碼直接返回該 Promise 即可,Jest 會等待其 resolved,如果 rejected 則測試不通過。

test('the data is banana', () => {expect.assertions(1)return fetchBanana().then(data => expect(data).toBe('banana')) }) 復制代碼

如果期望 promise 是 rejected 狀態,可以使用 .catch():

test('the fetch fails with an error', () => {expect.assertions(1)return fetchError().catch(e => expect(e).toMatch('error')) }) 復制代碼

除此之外,還可以使用上文中提到的 .resolves 和 .rejects。

Async/Await

如果異步代碼返回 promise,我們還可以使用 async/await:

test('async: the data is banana', async () => {expect.assertions(1)const data = await fetchBanana()expect(data).toBe('banana') })test('async: the fetch fails with an error', async () => {expect.assertions(1)try {await fetchError()} catch (e) {expect(e).toMatch('error')} }) 復制代碼

也可以將 aysnc/awiat 與 .resolves 或 .rejects 結合:

test('combine async with `.resolves`', async () => {expect.assertions(1)await expect(fetchBanana()).resolves.toBe('banana') }) 復制代碼

鉤子函數

Jest 為我們提供了四個測試用例的鉤子:beforeAll()、afterAll()、beforeEach()、afterEach()。

beforeAll() 和 afterAll() 會在所有測試用例之前和所有測試用例之后執行一次。 beforeEach() 和 afterEach() 會在每個測試用例之前和之后執行。

分組

我們可以使用 describe 將測試用例分組,在 describe 塊中的鉤子函數只作用于塊內的測試用例:

beforeAll(() => console.log('1 - beforeAll')) // 1 afterAll(() => console.log('1 - afterAll')) // 12 beforeEach(() => console.log('1 - beforeEach')) // 2,6 afterEach(() => console.log('1 - afterEach')) // 4,10 test('', () => console.log('1 - test')) // 3 describe('Scoped / Nested block', () => {beforeAll(() => console.log('2 - beforeAll')) // 5afterAll(() => console.log('2 - afterAll')) // 11beforeEach(() => console.log('2 - beforeEach')) // 7afterEach(() => console.log('2 - afterEach')) // 9test('', () => console.log('2 - test')) // 8 }) 復制代碼

需要注意的是,頂級的 beforeEach 會在 describe 塊內的 beforeEach 之前執行。

Jest 會先執行 describe 塊內的操作,等 describe 塊內的操作執行完畢后,按照出現在 describe 中的先后順序執行測試用例,因此初始化和銷毀操作應該放在鉤子函數中運行,而不是 describe 塊內:

describe('outer', () => {console.log('describe outer-a') // 1describe('describe inner 1', () => {console.log('describe inner 1') // 2test('test 1', () => {console.log('test for describe inner 1') // 6expect(true).toEqual(true)})})console.log('describe outer-b') // 3test('test 1', () => {console.log('test for describe outer') // 7expect(true).toEqual(true)})describe('describe inner 2', () => {console.log('describe inner 2') // 4test('test for describe inner 2', () => {console.log('test for describe inner 2') // 8expect(false).toEqual(false)})})console.log('describe outer-c') // 5 }) 復制代碼

Mocks

在測試中,mock 可以讓你更方便的去測試依賴于數據庫、網絡請求、文件等外部系統的函數。 Jest 內置了 mock 機制,提供了多種 mock 方式已應對各種需求。

Mock 函數

函數的 mock 非常簡單,調用 jest.fn() 即可獲得一個 mock 函數。 Mock 函數有一個特殊的 .mock 屬性,保存著函數的調用信息。.mock 屬性還會追蹤每次調用時的 this。

// mocks/forEach.js export default (items, callback) => {for (let index = 0; index < items.length; index++) {callback(items[index])} }import forEach from './forEach'it('test forEach function', () => {const mockCallback = jest.fn(x => 42 + x)forEach([0, 1], mockCallback)// The mock function is called twiceexpect(mockCallback.mock.calls.length).toBe(2)// The first argument of the first call to the function was 0expect(mockCallback.mock.calls[0][0]).toBe(0)// The first argument of the second call to the function was 1expect(mockCallback.mock.calls[1][0]).toBe(1)// The return value of the first call to the function was 42expect(mockCallback.mock.results[0].value).toBe(42) }) 復制代碼

除了 .mock 之外,Jest 還未我們提供了一些匹配器用來斷言函數的執行,它們本身只是檢查 .mock 屬性的語法糖:

// The mock function was called at least once expect(mockFunc).toBeCalled(); 復制代碼

使用 mockReturnValue 和 mockReturnValueOnce 可以 mock 函數的返回值。 當我們需要為 mock 函數增加一些邏輯時,可以使用 jest.fn()、mockImplementation 或者 mockImplementationOnce mock 函數的實現。 還可以使用 mockName 還給 mock 函數命名,如果沒有命名,輸出的日志默認就會打印 jest.fn()。

Mock 定時器

Jest 可以 Mock 定時器以使我們在測試代碼中控制“時間”。調用 jest.useFakeTimers() 函數可以偽造定時器函數,定時器中的回調函數不會被執行,使用 setTimeout.mock 等可以斷言定時器執行情況。當在測試中有多個定時器時,執行 jest.useFakeTimers() 可以重置內部的計數器。

執行 jest.runAllTimers(); 可以“快進”直到所有的定時器被執行;執行 jest.runOnlyPendingTimers() 可以使當前正在等待的定時器被執行,用來處理定時器中設置定時器的場景,如果使用 runAllTimers 會導致死循環;執行 jest.advanceTimersByTime(msToRun:number),可以“快進”執行的毫秒數。

Mock 模塊

模塊的 mock 主要有兩種方式:

  • 使用 jest.mock(moduleName, factory, options) 自動 mock 模塊,jest 會自動幫我們 mock 指定模塊中的函數。其中,factory 和 options 參數是可選的。factory 是一個模塊工廠函數,可以代替 Jest 的自動 mock 功能;options 用來創建一個不存在的需要模塊。
  • 如果希望自己 mock 模塊內部函數,可以在模塊平級的目錄下創建 __mocks__ 目錄,然后創建相應模塊的 mock 文件。對于用戶模塊和 Node 核心模塊(如:fs、path),我們仍需要在測試文件中顯示的調用 jest.mock(),而其他的 Node 模塊則不需要。

此外,在 mock 模塊時,jest.mock() 會被自動提升到模塊導入前調用。

對于類的 mock 基本和模塊 mock 相同,支持自動 mock、手動 mock 以及調用帶模塊工廠參數的 jest.mock(),還可以調用 jest.mockImplementation() mock 構造函數。

快照測試

快照測試是 Jest 提供的一個相當棒的 UI 測試功能,它會記錄 React 結構樹快照或其他可序列化的值,并與當前測試的值進行比較,如果不匹配則給出錯誤提示。快照應該被當做代碼來對待,它需要被提交到版本庫并進行 Review。

如果組件渲染結果發生變化,測試將會失敗。當組件正常調整時,我們可以調用 jest -u 更新快照。在監控模式下,我們可以通過交互式的命令更新快照。

下面通過一個簡單的 text 組件來測試一下:

// Text.jsimport React from 'react'export default ({className, children}) => {return (<span className={className}>{children}</span>) } 復制代碼

除了 react 我們還需要安裝依賴:npm i -D babel-preset-react react-test-renderer,其中 babel-preset-react 預設用來解析 jsx 語法,需要添加到 babel 配置中。

測試代碼如下:

// Text.test.jsimport React from 'react' import renderer from 'react-test-renderer'import Text from './Text'it('render correctly', () => {const tree = renderer.create(<Text className="success">Snapshot testing</Text>).toJSON()expect(tree).toMatchSnapshot() }) 復制代碼

執行測試代碼后,會生成如下快照:

// Jest Snapshot v1, https://goo.gl/fbAQLPexports[`render correctly 1`] = ` <spanclassName="success" >Snapshot testing </span> `; 復制代碼

如果后續修改導致組件渲染結果發生變化,快照將會不匹配,測試則不通過。

Jest 命令行

jest 命令行工具有有用的選項。運行 jest -h 可以查看所有可用的選項。所有的 Jest 的 配置項都可以通過命令行來指定。

基本用法:jest [--config=<pathToConfigFile>] [TestPathPattern] 生成配置信息:jest --init 運行符合指定用模板或文件名的測試︰jest path/to/my-test.js 啟動監視模式︰jest --watch 生成覆蓋率報告:jest --coverage

Jest 配置

Jest 的一個理念是提供一套完整集成的“零配置”測試體驗,開發人員可以直接上手編寫測試用例。它為我們集成了測試常用的工具,多數情況下使用默認配置或少量的調整即可。

Jest 的配置可以定義在 package.json 或 jest.config.js 文件中或通過命令行參數 --config <path/to/js|json>。配置并不是必須的,具體內容見文檔,按需取用即可。

PS:Jest 中 testURL 的默認值是 about:blank,在 jsdom 環境下運行會報錯,設置了 testURL 為一個有效的 URL 后能夠避免這個問題,如:http://localhost。

總結

以上是生活随笔為你收集整理的测试框架 Jest 实例教程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久精品tv | 熊猫电影yy8y全部免费观看 | 免费成人毛片 | 精品人成| 午夜日韩av| 国产新婚疯狂做爰视频 | 欧美一级二级三级视频 | 精品国产乱码久久久久久牛牛 | 免费av视屏| 日本一区二区视频在线观看 | 国语对白做受xxxxx在线中国 | 久久精国产 | 精品国模一区二区三区欧美 | 91在线亚洲| av在线播放国产 | 天天舔天天干天天操 | 国产精品三级在线观看无码 | 欧美成人片在线观看 | av涩涩| 女人色极品影院 | 国际av在线| 久久亚洲AV无码专区成人国产 | 亚洲精品一区二区三区四区 | 丰满少妇被猛烈进入高清播放 | 久久66热这里只有精品 | av天天网| 性生活视频在线播放 | 精品人妻一区二 | 我和我的太阳泰剧在线观看泰剧 | 99热手机在线观看 | 中文字幕在线日本 | 亚洲免费色视频 | 亚洲性视频 | 国产资源久久 | 亚洲蜜桃av| av之家在线 | aaaa毛片| 97人人爽人人 | 国产毛片久久久久久久 | 性生交大片免费看狂欲 | 欧美成人精品一区 | 男女污污视频在线观看 | 国产精品视频免费 | 亚洲一区区 | 亚洲色成人网站www永久四虎 | 欧美大尺度做爰啪啪床戏明星 | 黑花全肉高h湿play短篇 | 韩国av免费在线观看 | 天天草夜夜草 | 动漫美女放屁 | 欧美日韩18 | 成人一区二区三区在线 | 亚洲大逼 | 琪琪午夜伦理影院7777 | 国产aⅴ片 | 性色视频 | 在线观看你懂的视频 | 在线99视频 | 一区二区在线观看免费 | 免费观看毛片 | 日韩欧美h | 日韩日b视频 | www.日批| 丁香激情婷婷 | 性色av一区二区 | 黄瓜视频在线观看 | 日韩欧美中文字幕一区二区三区 | 日韩精品偷拍 | 第一色网站 | 欧美整片在线 | 久福利| 大乳女喂男人吃奶 | 精品成人免费一区二区在线播放 | 人妻体内射精一区二区三区 | 无码成人一区二区 | 欧美激情视频网址 | www.色中色| www.四虎在线 | 国产又黄又猛又粗 | 欧美一区二区久久 | 国产情趣视频 | 日本黄色片网址 | 99热99re6国产在线播放 | 91人人爱 | 国产极品美女高潮无套在线观看 | 日本三级免费网站 | 狠狠操狠狠爱 | 亚洲日本片 | 久久婷婷五月综合色国产香蕉 | 国产亚洲制服欧洲高清一区 | 兄弟兄弟全集免费观看 | 日本福利在线观看 | 国产亚洲制服欧洲高清一区 | 亚洲av高清一区二区三区 | 欧美剧场 | 精品国产污污免费网站入口 | 78m78成人免费网站 | 国产美女精品人人做人人爽 | 91精品在线免费 |