日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

你們單測覆蓋率是如何統計的?原理是什么?

來源: 責編: 時間:2024-04-02 17:23:05 209觀看
導讀高手回答我們在進行單元測試時,經常需要關注一個覆蓋率的指標,許多發布流程甚至要求達到特定的百分比。那么,單元測試覆蓋率是如何統計的呢?其底層實現原理又是怎樣的呢?單元測試覆蓋率的統計原理實際上是通過字節碼插樁實

高手回答

我們在進行單元測試時,經常需要關注一個覆蓋率的指標,許多發布流程甚至要求達到特定的百分比。NRH28資訊網——每日最新資訊28at.com

那么,單元測試覆蓋率是如何統計的呢?其底層實現原理又是怎樣的呢?NRH28資訊網——每日最新資訊28at.com

單元測試覆蓋率的統計原理實際上是通過字節碼插樁實現的。也就是說,在編譯期間會向代碼中注入一些特殊的監控代碼,以記錄測試執行過程中代碼的執行情況,從而推斷代碼的覆蓋情況。這些監控代碼能在運行時記錄代碼的執行情況,也能在編譯時生成代碼覆蓋率報告。NRH28資訊網——每日最新資訊28at.com

常見的單元測試覆蓋率統計工具包括JaCoCo、Emma、Cobertura等,這些工具能夠在編譯或運行時對代碼進行插樁,并記錄代碼的執行情況,最終生成覆蓋率報告。NRH28資訊網——每日最新資訊28at.com

具體見下表:NRH28資訊網——每日最新資訊28at.com

工具
NRH28資訊網——每日最新資訊28at.com

Jacoco
NRH28資訊網——每日最新資訊28at.com

Emma
NRH28資訊網——每日最新資訊28at.com

Cobertura
NRH28資訊網——每日最新資訊28at.com

原理
NRH28資訊網——每日最新資訊28at.com

使用 ASM 修改字節碼
NRH28資訊網——每日最新資訊28at.com

修改 jar 文件,class 文件字節碼文件
NRH28資訊網——每日最新資訊28at.com

基于 jcoverage,基于 asm 框架對 class 文件插樁
NRH28資訊網——每日最新資訊28at.com

覆蓋粒度
NRH28資訊網——每日最新資訊28at.com

行,類,方法,指令,分支
NRH28資訊網——每日最新資訊28at.com

行,類,方法,基本塊,指令,無分支覆蓋
NRH28資訊網——每日最新資訊28at.com

項目,包,類,方法的語句覆蓋/分支覆蓋
NRH28資訊網——每日最新資訊28at.com

插樁
NRH28資訊網——每日最新資訊28at.com

on the fly、offline
NRH28資訊網——每日最新資訊28at.com

on the fly、offline
NRH28資訊網——每日最新資訊28at.com

offline,把統計代碼插入編譯好的class文件中
NRH28資訊網——每日最新資訊28at.com

生成結果
NRH28資訊網——每日最新資訊28at.com

在 Tomcat 的 catalina.sh 配置 javaangent 參數,指出需要收集覆蓋率的文件,shutdown 時才收集,只能使用 kill 命令關閉 Tomcat,不要使用 kill -9
NRH28資訊網——每日最新資訊28at.com

html、xml、txt,二進制格式報表
NRH28資訊網——每日最新資訊28at.com

html,xml
NRH28資訊網——每日最新資訊28at.com

缺點
NRH28資訊網——每日最新資訊28at.com

需要源代碼
NRH28資訊網——每日最新資訊28at.com

1、需要 debug 版本,并打來 build.xml 中的 debug 編譯項;2、需要源代碼,且必須與插樁的代碼完全一致
NRH28資訊網——每日最新資訊28at.com

1、不能捕獲測試用例中未考慮的異常;2、關閉服務器才能輸出覆蓋率信息(已有修改源代碼的解決方案,定時輸出結果;輸出結果之前設置了 hook,會與某些服務器的 hook 沖突,web 測試中需要將 cobertura.ser 文件來回 copy
NRH28資訊網——每日最新資訊28at.com

性能
NRH28資訊網——每日最新資訊28at.com


NRH28資訊網——每日最新資訊28at.com

小巧
NRH28資訊網——每日最新資訊28at.com

插入的字節碼信息更多
NRH28資訊網——每日最新資訊28at.com

執行方式
NRH28資訊網——每日最新資訊28at.com

maven,ant,命令行
NRH28資訊網——每日最新資訊28at.com

命令行
NRH28資訊網——每日最新資訊28at.com

maven,ant
NRH28資訊網——每日最新資訊28at.com

Jenkins 集成
NRH28資訊網——每日最新資訊28at.com

生成 html 報告,直接與 hudson 集成,展示報告,無趨勢圖
NRH28資訊網——每日最新資訊28at.com

無法與 hudson 集成
NRH28資訊網——每日最新資訊28at.com

有集成的插件,美觀的報告,有趨勢圖
NRH28資訊網——每日最新資訊28at.com

報告實時性
NRH28資訊網——每日最新資訊28at.com

默認關閉,可以動態從 jvm dump 出數據
NRH28資訊網——每日最新資訊28at.com

可以不關閉服務器
NRH28資訊網——每日最新資訊28at.com

默認是在關閉服務器時才寫結果
NRH28資訊網——每日最新資訊28at.com

維護狀態
NRH28資訊網——每日最新資訊28at.com

持續更新中
NRH28資訊網——每日最新資訊28at.com

停止維護
NRH28資訊網——每日最新資訊28at.com

停止維護,不支持java1.8的lamda表達式
NRH28資訊網——每日最新資訊28at.com

什么是字節碼插樁

Java字節碼插樁技術是指在編譯期或運行期,通過修改Java字節碼的方式,在代碼中插入額外的代碼。這種技術可以在不改變Java源代碼的情況下,對Java應用程序的運行時行為進行監控、調試、分析和優化等操作。舉例來說,它可以用于實現性能監控、代碼覆蓋率檢測、代碼安全掃描等功能。NRH28資訊網——每日最新資訊28at.com

字節碼插樁技術通常包括以下幾個步驟:NRH28資訊網——每日最新資訊28at.com

  1. 生成目標類的字節碼,這一步可以通過Java編譯器(如javac)或其他工具(如AspectJ)來完成。
  2. 解析字節碼,識別需要進行插樁的代碼區域(如方法、循環、異常處理等)。
  3. 插入額外的字節碼,通常通過編寫Java代碼來實現這一步,然后利用字節碼生成庫(如ASM、Javassist等)生成相應的字節碼。
  4. 將修改后的字節碼重新寫回到磁盤或內存中,以供后續使用。

假設我們希望對一個Java方法進行性能監控,我們可以在方法的入口和出口處分別插入計時器,以統計方法的執行時間。以下代碼展示了如何實現這一功能:NRH28資訊網——每日最新資訊28at.com

public class Monitor {    public static void start() {        long startTime = System.nanoTime();        // 將起始時間記錄到ThreadLocal中,以便在方法返回時進行計算        ThreadLocalHolder.set("startTime", startTime);    }    public static void end() {        long endTime = System.nanoTime();        // 獲取起始時間        long startTime = (long) ThreadLocalHolder.get("startTime");        // 計算方法執行時間        long elapsedTime = endTime - startTime;        System.out.println("Method execution time: " + elapsedTime + "ns");    }}public class Example {    public void method() {        Monitor.start();        // 執行方法邏輯        Monitor.end();    }}

然而,若需監控多個方法的性能,分別在每個方法中插入Monitor.start()和Monitor.end()將導致代碼重復、可讀性下降,并存在遺漏的風險。在這種情況下,可以借助字節碼插樁技術,在編譯期或運行期間自動向每個方法的入口和出口處插入Monitor.start()和Monitor.end(),以確保代碼的統一性和可維護性。NRH28資訊網——每日最新資訊28at.com

具體實現可借助字節碼生成庫ASM或Javassist來實現,此處以ASM為例。以下代碼展示了如何使用ASM對Example類進行字節碼插樁:NRH28資訊網——每日最新資訊28at.com

import org.objectweb.asm.ClassReader;import org.objectweb.asm.ClassVisitor;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;import java.io.IOException;public class MonitorTransformer implements Opcodes {    public static byte[] transform(byte[] classBytes) throws IOException {        ClassReader reader = new ClassReader(classBytes);        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);        ClassVisitor visitor = new ClassVisitor(Opcodes.ASM5, writer) {            @Override            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {                MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);                // 只為指定方法添加字節碼插樁                if ("method".equals(name) && "()V".equals(desc)) {                    mv = new MethodVisitor(Opcodes.ASM5, mv) {                        @Override                        public void visitCode() {                            super.visitCode();                            // 在方法執行之前插入字節碼                            mv.visitMethodInsn(INVOKESTATIC, "Monitor", "start", "()V", false);                        }                        @Override                        public void visitInsn(int opcode) {                            // 在方法返回之前插入字節碼                            if (opcode == RETURN) {                                mv.visitMethodInsn(INVOKESTATIC, "Monitor", "end", "()V", false);                            }                            super.visitInsn(opcode);                        }                    };                }                return mv;            }        };        reader.accept(visitor, ClassReader.EXPAND_FRAMES);        return writer.toByteArray();    }}


NRH28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-80882-0.html你們單測覆蓋率是如何統計的?原理是什么?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 深度解析Git核心機理,你學會了嗎?

下一篇: 代碼是如何被被編譯的?

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 奈曼旗| 留坝县| 红安县| 腾冲县| 策勒县| 泰州市| 河南省| 舒城县| 西青区| 乡城县| 江山市| 山西省| 建平县| 哈巴河县| 洪江市| 昌黎县| 宜昌市| 西乌珠穆沁旗| 昌江| 左权县| 温宿县| 屏边| 建昌县| 衡东县| 松滋市| 白朗县| 甘德县| 扎鲁特旗| 东乌珠穆沁旗| 永和县| 咸丰县| 溧阳市| 克东县| 麦盖提县| 罗平县| 巩义市| 若尔盖县| 托克托县| 怀集县| 息烽县| 酉阳|