1. 程式人生 > 其它 >只懂黑盒測試也能學會的程式碼覆蓋率及精準化測試

只懂黑盒測試也能學會的程式碼覆蓋率及精準化測試

測試覆蓋率是對測試完成程度的度量。它通常依據某種覆蓋準則來對測試用例執行情況進行衡量,以判斷測試執行得是否充分。
——出自《計算機科學技術名詞 》第三版

今天文章中我們給大家介紹覆蓋率統計及覆蓋率分析。在10月13日20:00,資深測試開發架構師思寒將光臨直播間手把手教大家如何搞定精準化測試!

溫馨提示:你以為程式碼覆蓋率與精準化測試知識與黑盒測試無緣?不,你只是沒遇到思寒講的這節課。

常見覆蓋率統計工具

  • emma

  • cobertura

  • jacoco

emma 與 cobertura 是為單元測試而設計的覆蓋率統計,jacoco 與 emma 同屬於一家公司,但是是為了更廣泛的覆蓋率統計而設計的工具。

Jacoco

jacoco 的文件中有個 mission 章節,裡面對 jacoco
的定位描述的很好。原文的大意是說其他的工具沒有得到積極有效的維護,而且其他的工具都是為了單一任務而設計,他們不是為了 “整合”
而生。從這一點上我們就可以看出 jacoco 的設計理念。

得益於 jacoco 的設計理念,以及良好的 api
設計,它可以輕鬆的與已有的工具整合,甚至進行平臺化。它也可以同時用於單元測試與整合測試,所以是一款非常優秀的覆蓋率統計工具,很多公司的精準化測試,就是重度依賴了
jacoco。

覆蓋率分析原理

要了解程式碼覆蓋率的統計原理,我們就需要去深入瞭解 jvm 的機制。這方面的知識是 java
領域的高階進階知識,限於篇幅,我們只講解下大概的原理,完整內容請參考 VM 虛擬機器系列的書籍,以及 newrelic 早年釋出的若干程式碼插樁的資料。

簡單說下原理,java 原始碼會被 javac 編譯為 class 檔案,class 檔案儲存了 class 的基本資訊與 jvm 的指令集。java
的底層 runtime,也就是 jvm 在解析 class 的時候,會把檔案格式的 class 讀取到記憶體並執行。android
也是借鑑了這一整套的設計理念,android 上的 runtime 其實是 dalvik 與 art。

當我們要統計程式碼覆蓋率的時候,就需要在程式碼的執行路徑上加入探針分析。通常是在讀取類的時候,在關鍵的指令塊的出口與入口增加標記。當指令塊被執行後,就會命中探針並完成記錄。

要修改最底層的 jvm 位元組碼往往是比較麻煩的,需要精通 jvm 的各種指令以及 java class
結構。這方面的處理目前已有有非常成熟的開源專案可以做大了,如下就是一些知名的位元組碼修改工具。

  • ASM

  • JavaAssist

  • ByteBuddy、BTrace、JVM-Sandbox

其中 ASM 是所有位元組碼操作的底層基礎,是最底層的位元組碼修改工具。其他工具是它之上的一些高階封裝。藉助於這些工具與 JVM
自身的一些除錯特性,我們就可以對 jvm 程式碼或者程序進行便捷的操縱了。

插樁方式

插樁方式有很多種,常見的方式如下

  • 原始碼插樁:offline 插樁,支援 android

  • 位元組碼插樁:offline 插樁,支援 android

  • javaagent 模式:脫離程式碼在執行時插樁,on the fly 模式

jacoco 支援位元組碼插樁與 javaagent
這兩種插樁方式。也就是就算沒有原始碼也可以統計到覆蓋率資料,但是最後分析的時候,還是要結合原始碼才能獲得更多的覆蓋率細節資料。畢竟覆蓋率的統計,並不是只是簡單的覆蓋率資料本身的指標高低。

jacoco的工作方式

jacoco 支援四種工作模式

  • file:程序結束的時候在本地生成檔案

  • tcpserver:開啟埠等待客戶端獲取覆蓋率

  • tcpclient:主動把覆蓋率資料傳送出去

  • none:不生成覆蓋率

很多人都會使用 file 模式,但是 tcp server
模式才是最易用的。因為不需要申請伺服器的檔案訪問許可權就可控制覆蓋率資料。你可以根據自己公司的部署情況選擇合適的工作模式。

on the fly 插樁模式

on the fly 插樁模式是使用最多的。首先需要在你的被測 java 程式啟動的時候,加入 jvm 的一些 javaagent 引數。


-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]destfileoutput:file、tcpserver、tcpclient、noneaddressport

你可以自己設定適合的工作模式。

離線插樁模式,適合 android 的覆蓋率統計,需要藉助於 maven、gradle 等構建工具的 instrument 指令。

on the fly 插樁模式

jacoco-cli 是 jacoco 的一個元件,可以在不依賴 maven、gradle 構建工具的情況下完成對程式碼的分析。主要用於 tcpserver
工作模式下。

用法如下

java -jar jacococli.jar dump [--address <address>] --destfile <path> [--help] \[--port <port>] [--quiet] [--reset] [--retry <count>]

專案演練

這是學院裡的一個動手演練的小場景,統計 jmeter 工具的啟動覆蓋率


project_root=/Users/seveniruby/temp/java_2/jacoco/apache-jmeter-5.2.1jacoco_cli_jar=org.jacoco.cli-0.8.6-20200329.124045-45-nodeps.jar  
java -javaagent:org.jacoco.agent-0.8.6-20200329.124039-45-runtime.jar \  -jar $project_root/bin/ApacheJMeter.jar  
#退出jmeter  
#生成覆蓋率報告java -jar $jacoco_cli_jar report jacoco.exec \--classfiles "$project_root/bin/ApacheJMeter.jar" \--classfiles $project_root/lib/ext/ApacheJMeter_http.jar \--html jmeter_coverage/  
#生成帶有原始碼的覆蓋率報告 java -jar $jacoco_cli_jar report  jacoco.exec  \ --classfiles "$project_root/bin/ApacheJMeter.jar" \ --classfiles $project_root/lib/ext/ApacheJMeter_http.jar \ --html jmeter_coverage/ --sourcefiles ~/projects/jmeter/src/  
#生成xml報告java -jar $jacoco_cli_jar report jacoco_tcpserver2.exec  \--classfiles "$project_root/bin/ApacheJMeter.jar" \--classfiles $project_root/lib/ext/ApacheJMeter_http.jar \--xml  jmeter_coverage_tcpserver2/jacoco.xml

完整程式碼請參考學員論壇中的課程帖中的原始碼。
匯入覆蓋率

sonarqube 可以分析 jacoco 的 exec 檔案與 xml 檔案,並自動匯入覆蓋率。exec 檔案的分析後續會放棄支援,主支援 xml
檔案的分析。


 sonar-scanner   \  -Dsonar.host.url=http://sonarqube.testing-studio.com:9000   \  -Dsonar.login=$SONARQUBE_TOKEN   \  -Dsonar.projectKey=jmeter   \  -Dsonar.projectVersion=1.0  \  -Dsonar.coverage.jacoco.xmlReportPaths=$PWD/jmeter_coverage_tcpserver2/jacoco.xml \  -Dsonar.projectBaseDir=/Users/seveniruby/projects/jmeter/ \  -Dsonar.java.binaries=/Users/seveniruby/projects/jmeter/

匯入覆蓋率

可以通過如下引數限定要分析程式碼的範圍,通常是指明要覆蓋的 package 範圍

  • sonar.sources

  • sonar.inclusions

匯入覆蓋率

sonarqube 可以智慧分析新老版本之間的新增程式碼的覆蓋率,這點非常不錯,以前一些分析程式碼 diff
的工作就節省了。他的程式碼分析也比較智慧,簡單的換行並不會干擾程式碼 diff 的分析範圍。

通過覆蓋率資料

sonarqube 支援兩種通用的測試資料匯入

  • 通用覆蓋率資料:sonar.coverageReportPaths

  • 通用測試執行資料:sonar.testExecutionReportPaths

這樣方便與各種框架進行整合,也方便測試工程師二次定製。

通用測試資料模板。

通用覆蓋率資料模板

在 sonarqube 的 scanner 分析中,加入對應的配置引數即可匯入通用測試資料。

通用測試資料匯入的常見用途

  • 將各種測試工具的測試報告轉換為 sonarqube 支援的格式從而匯入平臺

  • 將各種覆蓋率工具的覆蓋率報告轉換為標準格式匯入平臺

  • 根據需求對差異 diff 覆蓋率進行定製,比如除了對新增程式碼做覆蓋,還要對使用了新增程式碼的依賴程式碼也做分析

程式碼diff方法

程式碼的 diff 分析是一個比較大的話題,diff
只是對程式碼的最簡單的一個分析策略,要想深入的理解程式碼,我們還需要更進一步的分析程式碼的呼叫鏈。我們先看最簡單的程式碼 diff 分析工具。

程式碼 diff 分析工具

  • JGit:git 分析工具

  • JavaParser:語法分析

  • ASM:讀取位元組碼

  • javap:jdk 自帶位元組碼分析工具

** _
來霍格沃茲測試開發學社,學習更多軟體測試與測試開發的進階技術,知識點涵蓋web自動化測試 app自動化測試、介面自動化測試、測試框架、效能測試、安全測試、持續整合/持續交付/DevOps,測試左移、測試右移、精準測試、測試平臺開發、測試管理等內容,課程技術涵蓋bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相關技術,全面提升測試開發工程師的技術實力
QQ交流群:484590337
公眾號 TestingStudio
點選獲取更多資訊