React Native單元測試

      網友投稿 952 2025-04-01

      概述

      所謂單元測試就是對每個單元進行的測試一般針對的是函數、類或單個組件不涉及系統和集成單元測試是軟件測試的基礎測試一個完備的軟件系統都會涉及到單元測試。

      目前Javascript的測試工具很多但是針對React的測試主要使用的是Facebook推出的Jest框架Jest是基于Jasmine的JavaScript測試框架具有上手容易、快速、可靠的特點是React.js默認的單元測試框架。相比其他的測試框架Jest具有如下的一些特點

      適應性Jest是模塊化、可擴展和可配置的

      沙箱和快速Jest虛擬化了JavaScript的環境能模擬瀏覽器并且并行執行

      快照測試Jest能夠對React 樹進行快照或別的序列化數值快速編寫測試提供快速更新的用戶體驗

      支持異步代碼測試支持promises和async/await

      自動生成靜態分析結果不僅顯示測試用例執行結果也顯示語句、分支、函數等覆蓋率。

      環境搭建

      安裝Jest

      首先在項目目錄下使用下面的命令安裝Jest。

      如果你使用的是react-native init命令行方式來創建的RN項目且RN版本在0.38以上則無需手動安裝系統在生成項目的時候會自動添加依賴。

      配置Babel

      現在很多的項目都使用es6及以上版本編寫為了兼容老版本我們可以使用Babel來將es5的語法轉換為es6。使用Babel前我們需要使用如下的命令來安裝Babel。

      說明如果使用的是Babel 的version 7則需要安裝babel-jest, babel-core@^7.0.0-bridge.0 和 @babel/core安全命令如下:

      然后在項目的根目錄里添加 .babelrc 文件在文件中配置如下react-native腳本內容。

      如果是自動生成的 .babelrc 文件的配置腳本如下

      此時需要將上面的presets配置修改為 "presets": ["react-native"]。

      完整配置

      為了方便查看 下面是package.json文件的完整配置

      說明如果報AccessibilityInfo錯誤請注意react-naitve的版本號因為react-naitve的版本和其他庫存在一些兼容問題請使用0.55.4及以下穩定版本。

      Enzyme

      Enzyme 是 Airbnb 公司開源的測試工具庫是react-addons-test-utils的封裝的產品它模擬了 jQuery 的 API非常直觀并且易于使用和學習提供了一些與眾不同的接口和幾個方法來減少測試的樣板代碼方便你判斷、操縱和遍歷 React Components 的輸出并且減少了測試代碼和實現代碼之間的耦合。相比react-addons-test-utilsenzyme的API 就一目了然下表是兩個框架常用的函數的對比。

      Enzyme提供了三種渲染方法

      shallow

      shallow 方法就是對官方的 Shallow Rendering 的封裝淺渲染在將一個組件作為一個單元進行測試的時候非常有用可以確保你的測試不會去間接斷言子組件的行為。shallow 方法只會渲染出組件的第一層 DOM 結構其嵌套的子組件不會被渲染出來從而使得渲染的效率更高單元測試的速度也會更快。例如

      mount

      mount 方法則會將 React 組件渲染為真實的 DOM 節點特別是在依賴真實的 DOM 結構必須存在的情況下比如說按鈕的點擊事件。 完全的 DOM 渲染需要在全局范圍內提供完整的 DOM API 這也就意味著它必須在至少“看起來像”瀏覽器環境的環境中運行如果不想在瀏覽器中運行測試推薦使用 mount 的方法是依賴于一個名為 jsdom 的庫它本質上是一個完全在 JavaScript 中實現的 headless 瀏覽器。 mount渲染方式的示例如下

      render

      render 方法則會將 React 組件渲染成靜態的 HTML 字符串返回的是一個 Cheerio 實例對象采用的是一個第三方的 HTML 解析庫 Cheerio。這個 CheerioWrapper 可以用于分析最終結果的 HTML 代碼結構它的 API 跟 shallow 和 mount 方法的 API 都保持基本一致。

      Jest單元測試

      簡單示例

      首先我們在項目的根目錄新建一個名為__test__的文件夾然后編寫一個組件例如

      然后我們在__test__文件夾下編寫一個名為jest.test.js的文件代碼如下

      使用命令 “yarn jest” 系統就會開始執行單元測試如果沒有任何錯誤將會顯示PASS相關的信息。

      當然上面的例子并沒有涉及到任何的業務邏輯只是介紹了下在React Native中如何使用Jest進行單元測試。

      生成快照測試

      快照測試是第一次運行測試的時候在不同情況下的渲染結果掛載前保存的一份快照文件后面每次再運行快照測試時都會和第一次的比較除非使用“npm test -- -u”命令重新生成快照文件。

      為了測試快照測試我們先新建一個帶有邏輯的組件。例如

      上面的組件擁有三種狀態初始狀態點擊狀態以及再次被點擊的狀態所以在測試文件中我們分別生成三種狀態的快照快照測試文件的代碼如下

      然后在控制臺運行yarn jest命令就會看到在__tests___snapshots_\目錄下看到快照測試快照測試文件的代碼如下

      如果需要更新快照文件執行yarn test -- -u命令。

      DOM測試

      DOM測試主要測試組件生成的 DOM 節點是否符合預期比如響應事件之后組件的屬性與狀態是否符合預期。DOM 測試 依賴于官方的 TestUtil所以需要安裝react-addons-test-utils依賴庫安裝的時候注意版本的兼容問題。不過在實戰過程中我發現react-addons-test-utils會報很多錯誤并且官方文檔也不是很友好。

      這里推薦使用airbnb開源的Enzyme 腳手架Enzyme是由 airbnb 開發的React單測工具它擴展了React的TestUtils并通過支持類似jQuery的find語法可以很方便的對render出來的結果做各種斷言開發體檢十分友好。

      生成測試報告

      使用命令yarn test -- --coverage就可以生成測試覆蓋報告。如圖

      同時還會在根目錄生成一個名為 coverage 的文件夾是測試覆蓋報告的網頁版包含更多更詳細的信息。

      Jest基礎語法

      匹配器

      匹配器用于測試輸入輸出的值是否符合預期下面介紹一些常見的匹配器。

      普通匹配器

      最簡單的測試值的方法就是看值是否精確匹配使用的是toBe()例如

      toBe()使用的是JavaScript中的Object.is()屬于ES6中的特性所以不能檢測對象如果要檢測對象的值的話需要用到toEqual。

      Truthiness

      在實際的測試中有時候我們需要明確區分undefined、null和false等情況而Jest提供的下面的一些規則可以幫我們完成上面的需求。

      toBeNull只匹配null

      toBeUndefined只匹配undefined

      toBeDefine與toBeUndefined相反

      toBeTruthy匹配任何if語句為真

      toBeFalsy匹配任何if語句為假

      數字匹配器

      toBeGreaterThan()大于 toBeGreaterThanOrEqual()大于或者等于 toBeLessThan()小于 toBeLessThanOrEqual()小于或等于 注對比兩個浮點數是否相等使用的是toBeCloseTo()而不是toEqual()。

      例子

      字符串

      使用toMatch()函數測試字符串傳遞的參數需要是正則表達式。例如

      數組

      如果要檢測某個字符串是否包含某個字符串或字符可以使用toContain()。例如

      toThrow

      如果想在測試特定函數的時候拋出錯誤則可以在它調用的時候可以使用toThrow()。

      異步函數

      在實際開發過程中經常會遇到一些異步的JavaScript代碼。當有異步方式運行的代碼的時候Jest需要知道當前它測試的代碼是否已經完成然后它才可以轉移動另一個測試。也就是說測試的用例一定要在測試對象結束之后才能夠運行。異步測試有多種手段

      回調

      回調函數和異步沒有必然的聯系回調只是異步的一種調用方式而已。現在假設一個fetchData(call)函數獲取一些數據并在完成的時候調用call(data)我們想要測試返回的數據是不是包含字符串'peanut butter'那么我們可以這樣寫

      React Native單元測試

      Promise

      Promise表示“承諾將來會執行”的對象基礎內容可以參考廖雪峰的Promise。例如還是上面的fetchData我們使用Promise代替回調來實現網絡請求。則測試代碼寫法如下

      上面我們使用expect.assertions來驗證一定數量的斷言是否被調用如果想要Promise被拒絕我們可以使用.catch方法。

      Async/Await

      Async/Await是一種新的異步請求實現方式若要編寫async測試只需要在函數前面使用async關鍵字即可。例如

      Jest Object

      在寫測試的時候我們經常需要進行測試之前做一些準備工作。例如多次測試重復設置的工作可以使用beforeEach和afterEach。

      在某些情況下如果只需要在文件的開頭做一次設置則可以使用beforeAll和afterAll來處理。

      作用域

      默認情況下before和after的塊可以應用到文件中的每一個測試。此外可以通過describe塊來將將測試中的某一塊進行分組當before和after的塊在describe塊內部的時候則只適用于該describe塊內的測試。例如

      Jest測試之Mock

      mock測試就是在測試過程中對于某些不容易構造或者不容易獲取的對象用一個虛擬的對象來創建以便繼續進行測試的測試方法。Mock函數通常會提供以下三種特性

      捕獲函數調用情況

      設置函數返回值

      改變函數的內部實現

      本節我們主要介紹與 Mock 函數相關的幾個API分別是jest.fn()、jest.spyOn()、jest.mock()。

      jest.fn()

      jest.fn()是創建Mock函數最簡單的方式如果沒有定義函數內部的實現jest.fn()會返回undefined作為返回值。例如

      jest.fn()所創建的Mock函數還可以設置返回值定義內部實現或返回Promise對象。

      上面的代碼是jest.fn()提供的幾個常用的API和斷言語句下面我們在src/fetch.js文件中寫一些被測試代碼以更加接近業務的方式來理解Mock函數的實際應用。

      需要說明的是被測試代碼中依賴了axios這個常用的請求庫和JSONPlaceholder這個上篇文章中提到免費的請求接口請先在shell中執行npm install axios --save安裝依賴。

      我們在fetch.js中封裝了一個fetchPostsList方法該方法請求了JSONPlaceholder提供的接口并通過傳入的回調函數返回處理過的返回值。如果我們想測試該接口能夠被正常請求只需要捕獲到傳入的回調函數能夠被正常的調用即可。例如

      jest.mock(

      在上一個請求fetch.js文件夾中我們封裝的請求方法可能在其他模塊被調用但有時候我們并不需要進行實際的請求請求方法已經通過單側或需要該方法返回非真實數據。此時使用jest.mock(去mock整個模塊是十分有必要的。

      然后我們編寫一個測試文件用于測試getPostList請求。

      測試代碼中我們使用了jest.mock('../src/fetch.js')去mock整個fetch.js模塊如果注釋掉這行代碼執行測試腳本時會出現以下報錯信息。

      jest.spyOn()

      jest.spyOn()方法同樣可以創建一個mock函數但是該mock函數不僅能夠捕獲函數的調用情況還可以正常的執行被spy的函數。實際上jest.spyOn()是jest.fn()的語法糖它創建了一個和被spy的函數具有相同內部代碼的mock函數。例如

      上圖是之前jest.mock()的示例代碼中的正確執行結果的截圖從shell腳本中可以看到console.log('fetchPostsList be called!');這行代碼并沒有在shell中被打印這是因為通過jest.mock()后模塊內的方法是不會被jest所實際執行的。這時我們就需要使用jest.spyOn()。

      執行npm run test后可以看到shell中的打印信息說明通過jest.spyOn()fetchPostsList被正常的執行了。

      E2E自動化測試

      本文轉載自異步社區。

      HTTP React 單元測試

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表格數據怎么轉換為箱形圖?
      下一篇:怎么在WPS2013表格中對變價商品計算利潤
      相關文章
      亚洲高清日韩精品第一区| 亚洲国产综合精品中文第一区| 亚洲高清无在码在线电影不卡 | 亚洲无线码在线一区观看| 亚洲一区日韩高清中文字幕亚洲| 大胆亚洲人体视频| 亚洲Av无码乱码在线播放| 久久亚洲欧美国产精品| 风间由美在线亚洲一区| mm1313亚洲国产精品无码试看| 日韩国产精品亚洲а∨天堂免| 亚洲AV噜噜一区二区三区 | 亚洲第一综合天堂另类专| 亚洲美国产亚洲AV| 亚洲爆乳精品无码一区二区| 久久久久亚洲国产AV麻豆| 亚洲AV无码一区二区乱子仑| 免费亚洲视频在线观看| 亚洲国产免费综合| 中国亚洲女人69内射少妇| 中文字幕亚洲一区| 亚洲AV无码专区国产乱码4SE| 亚洲av日韩av无码黑人| 亚洲视频网站在线观看| 亚洲国产成人久久77| 亚洲一区精彩视频| 亚洲AV无码一区二区三区网址| 国产精品亚洲专区无码不卡| 亚洲精品岛国片在线观看| 亚洲无线码在线一区观看| 久热综合在线亚洲精品| 亚洲精品午夜视频| 亚洲一区精彩视频| 亚洲AⅤ视频一区二区三区| 亚洲中文字幕久久精品无码喷水 | 亚洲国产精品无码成人片久久| 青青草原精品国产亚洲av| 亚洲人成激情在线播放| 亚洲国产精品无码第一区二区三区| 久久精品亚洲日本波多野结衣| 亚洲精品乱码久久久久久不卡 |