ReactNative 多端程式碼覆蓋率調研及實踐

zailushang發表於2020-05-20
特別感謝 @chenhengjie123 @Lihuazhang @zsx10110 三位整個過程中的幫助。

1、背景

一些新專案使用React Native編寫,為了多維度把控產品質量,特增加程式碼覆蓋率統計緯度;
參考資料:

2、方案介紹

  • 插樁方案:nyc 是新版 istanbul,解決了大量istanbul存在的問題;
  • 本地統計:nyc 和 istanbul 都用於【本地執行,本地統計覆蓋率】的場景。
  • 多端統計:istanbul-middleware 是 istanbul 的一個 用於【多端執行,在服務端統計覆蓋率總和】的場景 所以,我們採用nyc進行插樁,利用istanbul-middleware進行多端統計;

3、示例及程式碼說明

3.1 js覆蓋率報告示例

首先可以從圖中看到,nyc提供的js程式碼覆蓋率報告是從Branches(分支)、Functions(函式)、Lines(行)三個維度統計的。

3.2 程式碼示例

RN程式碼覆蓋率 示例程式碼見:https://github.com/OnTheWay111/RNCodeCoverageExample
建議:先下載程式碼,然後看下文介紹,來熟悉整個程式碼結構。
如果要看原理:請看橫捷之前的文章,寫得非常好,https://testerhome.com/topics/8919

3.3 程式碼配置過程

(1)程式碼結構介紹

  • index.js: 專案入口檔案
  • package.json:專案依賴管理檔案

(2)JS插樁步驟

cd coverage_middleware  # 進入coverage_middleware專案目錄
mv ../RNdemo/js RNdemo # RN專案RNdemojs原始碼移動到coverage_middleware目錄下
npm install # 安裝專案依賴包
  • RN的js檔案插入定時回傳覆蓋率資料的方法(每隔4秒自動回傳,fetch方法是react native 提供的網路請求方法):

// post window.__coverage__ to server every 2 seconds
setInterval(function() {
fetch('http://10.60.139.6:9999/coverage/client', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(window.__coverage__)
})
.then(function() {
var date = new Date();
console.log(date + "傳送覆蓋率成功!");
console.log(window.__coverage__);
})
.catch(function(error) {
console.log('傳送覆蓋率失敗: ' + error.message);
});
}, 4000);
  • 執行插樁 shell nyc instrument RNdemo ../RNdemo/js # 將原始碼插樁後,放到../RNdemo/js

至此,插樁完成。

(3)啟動服務端專案

npm index

啟動成功如圖所示:

(4)安裝RNdemo到手機

左圖為手機,有圖為reactNative控制檯,圖中可以看到列印的覆蓋率回傳log,以及每次回傳的覆蓋率物件;

4、注意

因發現istanbul-middleware專案已經幾年沒有更新程式碼,且沒有合併pull request,所以在自己的git把之前的pull request均合併了一下,所以建議package.json中配置更新後的istanbul-middleware。

5、踩坑記錄

(1)【done】react-native啟動時紅屏報錯:Unable to load script.Make sure you're either running a metro server or that ....
解決方法:https://www.cnblogs.com/shizk/p/11189978.html

(2)【done】nyc插樁無效

  • 問題原因:nyc 需要14.1.1版本,結果在package.json配置npm install後,直接執行命令nyc,用的是全域性nyc,並不是專案依賴包node_modules中的nyc。
  • 建議:在package.json中配置nyc的script,配置後,nyc使用的就是node_module下的nyc,而非全域性nyc。配置如下圖:

(3)插樁後丟檔案
nyc instrument 後發現有丟檔案的現象,所以為了安全起見,還是加上完成copy的引數吧;

nyc instrument --complete-copy [input] [output]

(4)含有裝飾器的js無法插樁
目前還未找到解決方法

(5)【待確認】istanbul-middleware覆蓋率資料不準確
網友發現的問題,目前還沒復現,回頭等複雜專案驗證後再出結論。

相關文章