程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Rational >> IBM Rational Application Developer代碼覆蓋工具入門簡介

IBM Rational Application Developer代碼覆蓋工具入門簡介

編輯:Rational

為您的 Java 程序生成代碼覆蓋統計數據

簡介:代碼覆蓋率工具是軟件測試過程中使用到的一個重要的工具,因為它提供了一個關於程序被測 試用例覆蓋程度的觀點。本文向您展示了怎樣使用 IBM® Rational® Application Developer 中提供的代碼覆蓋工具,來為 Java™ 程序生成測試的覆蓋率結果,並提供了關於怎樣分析結果以 改進測試的信息。

什麼是 Rational Code Coverage 特性?

代碼覆蓋率是軟件測試的一個 重要方面,對於一個構件的總體系統測試來說可能是一個基本的參數。覆蓋工具背後的動機向您(作為開 發員或者測試員)提供了關於代碼的一系列觀點,這些代碼在一系列的測試之中會得到檢查。該信息會非 常的有用,因為您可以使用它來設計新的測試用例以獲得足夠的覆蓋范圍。

IBM® Rational® Code Coverage 特性是一個與 IBM® Rational® Application Developer 相集成 的工具。您可以使用它來生成並分析關於 Java 程序的覆蓋率統計數據。工具會為測試下的程序生成聲明 覆蓋率統計數據(這就是說,執行程序中行的數量與百分比)。

Rational Code Coverage 特性現 在只能獲得 Rational Application Developer 7.5 版本及其後續版本。本文假設您使用的是 Rational Application Developer 7.5.4 版本。對代碼覆蓋率而配置 IBM® WebSphere® Application Server 的部分假設您使用的是 7.0 版本,但是提供的指南的一些調整仍然適用於上述版本。

指 南

為了適當地分析 Rational Code Coverage 特性中的覆蓋率統計數據,理解場景背後所用到的 技術是非常重要的。

Eclipse Test 與 Performance Tools Project(TPTP)中提供的 Rational Code Coverage 特性所使用的工具引擎。Probekit 用於控制一個類的比特代碼,並引入覆蓋率數據收集 引擎的通用訪問。圖 1 提供了關於這個過程的一個高層次的概述:

圖 1. Rational Code Coverage 執行環境的概述

基本快與可執行的單 元

Probekit 是一種在 Eclipse 平台上的框架,並可以操作所謂 可執行單元 的比特代碼。可執 行單元的定義與 基本塊 的傳統定義有輕微的不同,但是當您在分析結果時,您就需要去關注這點差異了 。

根據定義,一個所謂的基本塊就是一系列的指南,這些指南不能再進行分支或者分散。這裡的 關鍵思想在於,當第一個指南運行的時候,該塊中隨後所有指南都一定會得到執行而且不會得到中斷。接 下來的是一個基本塊,它可以認為是一個單個組或者一系列的指南。通常來說,基本塊的結尾是 branch , call, throw 或者 return 聲明。

一個可執行的單元由每一個基本快開始,而與每行源代碼相 對應的指南與前面版本中的指南有所不同。可執行的單元與基本塊的不同點,在於決定一個可執行單元末 尾的因素。例如, divide 指南並沒有認為是一個可執行單元的結尾,盡管有例外情況的存在。

Probekit 是 Rational Code Coverage 特性所使用的,以將通用代碼引入到每一個可執行的單元 之中。結果來說,您可以定制 Rational Code Coverage 特性以向組成性(換句話說,就是塊覆蓋率)可 執行單元層次報告統計數據。為了知道這些工具是怎樣更改類了,您可以參考接下來的代碼清單 1 與代 碼清單 2。代碼清單 1 提供了未處理類的分解輸出(從 javap 工具來),同時代碼清單 2 為處理過的 類提供了分解輸出。注意代碼清單 2 中 italics 的行就是作為處理步驟一部分導入的代碼部分。

清單 1. 未處理的類文件

Compiled from "Part.java"
public class  com.ibm.storeapp.models.Part extends java.lang.Object{ 
public  com.ibm.storeapp.models.Part(int);
 Code:
  0:  aload_0
  1:   invokespecial  #15; //Method java/lang/Object."<init>":()V
  4:   iload_1
  5:  bipush 10
  7:  if_icmple    18 
  10:  aload_0
  11: iload_1
  12: invokespecial  #18; //Method  setDiscountedPrice:(I)V
  15: goto  23
  18: aload_0
  19:  iload_1
  20: putfield    #21; //Field price:I
  23: return

  public int getPrice();
 Code:
  0:  aload_0
  1:  getfield     #21; //Field price:I
  4:  ireturn

}

清單 2. 每一個可執行單元處理的類文件

Compiled from "Part.java"
public class  com.ibm.storeapp.models.Part extends java.lang.Object{ 
public  com.ibm.storeapp.models.Part(int);
 Code:
 0: ldc #49; //String  com/ibm/storeapp/models/Part 2: iconst_0 3: iconst_0 4:
  invokestatic #48;  //Method llc_probe$Probe_0._executableUnit:(Ljava/lang/String;II)V
 7:   aload_0
 8:  invokespecial  #15; //Method java/lang/Object."<init>":()V
 11: ldc #49; //String com/ibm/storeapp/models/Part 13: iconst_0 14: iconst_1  15:
  invokestatic #48; //Method llc_probe$Probe_0._executableUnit: (Ljava/lang/String;II)V
 18: iload_1
 19: bipush 10
 21: if_icmple     46 
 24: ldc #49; //String com/ibm/storeapp/models/Part 26: iconst_0 27:  iconst_2 28:
  invokestatic #48; //Method llc_probe$Probe_0._executableUnit: (Ljava/lang/String;II)V
 31: aload_0
 32: iload_1
 33: invokespecial   #18; //Method setDiscountedPrice:(I)V
 36: ldc #49; //String  com/ibm/storeapp/models/Part 38: iconst_0 39: iconst_3 40:
  invokestatic #48;  //Method llc_probe$Probe_0._executableUnit:(Ljava/lang/String;II)V
 43: goto  58  
 46: ldc #49; //String com/ibm/storeapp/models/Part 48: iconst_0 49:  iconst_4 50:
  invokestatic #48; //Method llc_probe$Probe_0._executableUnit: (Ljava/lang/String;II)V
 53: aload_0
 54: iload_1
 55: putfield     #21; //Field price:I
 58: ldc #49; //String com/ibm/storeapp/models/Part 60:  iconst_0 61: iconst_5 62:
  invokestatic #48; //Method  llc_probe$Probe_0._executableUnit:(Ljava/lang/String;II)V
 65: return

  public int getPrice();
 Code:
 0: ldc #49; //String  com/ibm/storeapp/models/Part 2: iconst_2 3: iconst_0 4:
  invokestatic #48;  //Method llc_probe$Probe_0._executableUnit:(Ljava/lang/String;II)V
 7:   aload_0
 8:  getfield    #21; //Field price:I
 11: ireturn
  static {}; Code: 0: ldc #49; //String com/ibm/storeapp/models/Part 2: ldc #55;
  //String Part.java 4: ldc #57; //String <init>(I)V+setDiscountedPrice(I) V
  +getPrice()I 6: ldc #59; //String #10+11032,301,3 8: invokestatic #54;
  //Method llc_probe$Probe_0._staticInitializer:
   (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V 11: return

}

在 Rational Application Developer 中生成覆蓋率統計數據

Rational Code Coverage 特性的一個主要的優勢在於,您可以通過切換到項目 Properties 的 Code Coverage 窗 格,來將其在 Rational Application Developer 中的 Java 項目上激活,如圖 2 所示。

圖 2. 項目 Properties 中的代碼覆蓋窗格

選擇圖 2 中的 Enable code coverage 復選框以激活項目的代碼覆蓋率,並評價覆蓋下項目的類。您還可以使用該窗格 來定制可接受的覆蓋率層次。接下來描述了組合的支持層次:

類型覆蓋率:一個類中覆蓋的類型 百分比

方法覆蓋率:一個類中覆蓋的方法百分比

行覆蓋率:類文件中覆蓋的行百分比

塊覆蓋率:一個類文件中覆蓋的塊的百分比。注意一個塊會參考一個可執行的單元(如 以前描述 的那樣 )

您還可以指定通用的篩選規則,而且它們可以用於控制在項目中評價哪些內容。默認條 件下,項目中的所有類都會得到評價,但是您可以創建通用的篩選規則來排除目標包或者指定類型,如果 您需要限制結果的話。

Package Explorer

在您激活一個項目中的代碼覆蓋率以後,覆蓋率 統計數據就會在下一次程序啟動的時候生成。注意不是所有類型啟動配置都會自動生成統計數據。表 1 顯示了 Rational Application Developer 內支持的啟動類型。

表 1. 支持的啟動配置

啟動類型 Java Applet OSGi 框架 JUnit JUnit 插件測試 Java 程序 Eclipse 程序 標准 Widget Toolkit (SWT)程序

在 下載 部分中提供了一個范例程序,本文至始至終都會使用該范例。該程 序是一個不同交通工具(汽車、貨車、摩托車等等)的簡單再現。圖 3 中是一個概括了該程序結構的 UML 圖。

圖 3. 范例程序的 UML 圖

在項目中有兩種定義好 的 JUnit 測試:TestCar.java 與 TestCarImproved.java。正如其名字所暗含的一樣,這些測試的目標 是 Car.java 類。而在 Rational Application Developer 的 Java 視角中,您可以右擊 TestCar.java 並選擇 Run As > JUnit test 來啟動 TestCar.java 測試。JUnit 測試的結果會正常顯示在 JUnit 視圖中。覆蓋率數據的結果會集成到 Rational Application Developer UI 中,而且您可以切換回 Package Explorer 來分析它們。圖 4 顯示了 TestCar.java 測試的一個范例結果。

圖 4. Package Explorer 中顯示的 TestCar.java 的覆蓋率數據

默認條件下,UI 只 與行覆蓋率信息一起注釋;但是,您可以在工作台偏好中更改它們,並且可以選擇為包、類型以及塊而包 含覆蓋率。每一個 Java 項目的百分比是最後一次執行代碼覆蓋率的中斷。您可以在 Package Explorer 中深入研究各種 Java 工件(例如,類、類型與方法)以得到較低組合層次上的覆蓋率統計數據。

結果得到的結果的顏色情況取決於成功率:默認條件下,紅色意味著沒有達到可接受的覆蓋率層 次,而綠色則意味著得到了適當的覆蓋率范圍。一般來說,測試的目的在於達到類可接受覆蓋率層次的結 果。

基於如圖 4 所示的結果,第一個測試是不充分的:Car 類(以及抽象父類 AbstractFourWheelVehicle 和 Vehicle)並不能達到適當的覆蓋率層次。幸運的是,您有第二次嘗試的 機會:TestCarImproved.java。您可以再一次將測試作為一次正常的 JUnit 執行,而結果將會在 Package Explorer 中進行自動更新(圖 5)。

圖 5. Package Explorer 中顯示的 TestCarImproved.java 的代碼覆蓋率數據

Java 編輯器

行覆蓋率結果也是顯示的,並在 Java 編輯器中有所標記,而您可以使用它來得到一個更加明確的指示, 也就是每一類中涉及到了哪一行。在生成覆蓋率數據之後,您就可以使用 Java 編輯器來在項目中打開任 意的類了,編輯器中左邊的標尺欄顯示了關於覆蓋率的信息。圖 6 顯示了 Vehicle.java 的結果:

圖 6. Java 編輯器中顯示的覆蓋率結果

顏色編輯與在 Package Explorer 中所顯示的是一樣的。也就是,默認條件下,綠色的行是覆蓋的而紅色的則不是覆蓋 的。在 Java 編輯器中查看結果有一個微弱的優勢,那就是它還指示了部分覆蓋的行。當在源代碼中有不 止一個的可執行單元時就會產生部分覆蓋的行,但是它們中只有一個可以被執行。例如,查看圖 6 中 setTargetSpeed(int speed) 方法中第一行的代碼 :第一個可執行的單元是 if 聲明,而第二個可執行 的單元則是 return 聲明。默認條件下,一個部分的行會被標上黃色。

生成報告

您可以 將代碼覆蓋率結果數據匯編到報告之中並在 Rational Application Developer 中查看它們,或者將它們 保存到文件系統中以便未來的分析。您可以生成兩種不同類型的報告:Workbench 報告(基於 Eclipse) 與 HTML 報告。為了生成一份報告,您可以選擇 Run > Code Coverage > Generate Report。圖 7 顯示了報告生成對話框。

圖 7. 報告生成對話框

您可以在 Rational Application Developer 中使用對話框中的 Quick View 選項來創建並查看一個報告,或者使用 Save Report 選項將其保存到文件系統中去。

工作台報告

工作台報告(也叫做基於 Eclipse 的 報告)為項目提供了所有覆蓋率統計數據的穩固視圖,並包含了執行時項目中所有類的覆蓋率數據。圖 8 顯示了一個基於 Eclipse 流傳的報告。

圖 8. 一個基於 Eclipse 報告的覆蓋率結果

工作台報告與 Rational Application Developer 相集成具有額外的優勢,因為您可以使用它 們作為一個快速的工具,以提供了關於部分代碼的視角,這些代碼需要改進的測試覆蓋率數據。如圖 8 所示,工作台報告中的統計數據包含了所有層次組成的覆蓋率信息:從一個包到一種方法。右擊任意的 Java 工件會顯示出一個帶有兩種操作的彈出菜單: 在 Package Explorer 中顯示 與 在 Java 編輯器中 將其打開。對於識別和研究帶有低覆蓋率的代碼區域來說,它們是非常有用的工具,因為通過將它們在適 當的浏覽器或者編輯器中打開,從而強調了代碼的選擇區域。

HTML 報告

HTML 報告顯示了 基於 Eclipse 報告所提供的相同類型的信息,但是呈現的格式卻是 HTML 的。這些報告能夠發揮一定程 度的作用,因為它們為在獨立於 Rational Application Developer 之外去分析覆蓋率數據提供了一種有 效的方法,您可以與團隊的其他成員一起分享,或者將其發布到一個網站上以方便查看。

在工作 台的外部生成統計數據

Rational Code Coverage 工具的一個主要特性是其在 Rational Application Developer 外部生成統計數據的能力。它提供了額外的靈活性,並使得您可以定制環境以利 用系統中的 Rational Code Coverage 特性。例如,一個自然的合並過程就是創建一個構建環境並使用 JUnit 測試來生成統計數據。

通過執行以下的三個步驟:評價,執行以及生成報告,您可以將 Rational Code Coverage 特性集成到您的環境之中。

第 1 步. 評價

您可以使用兩種不同 的方法來評價您的程序。第一個就是使用 <RAD_HOME>/plugins/com.ibm.rational.llc.engine_<date>/scripts 目錄中提供的 instrument.bat/sh 腳本。本文並沒有關注這個腳本,但是您可以參考 Rational Application Developer 文獻以得到更多的信息,如果需要的話。第二個方法是使用 Rational Code Coverage 特性提 供的評價 Ant 任務。代碼清單 3 顯示了評價任務配置的范例用法,以得到本文中的范例程序。

清單 3. 本文范例程序的評價 Ant 任務的范例用法

<target  name="instrument">
 <taskdef name="instrument"
   classname="com.ibm.rational.llc.engine.instrumentation.anttask.InstrumentationTask"
   classpath="{path to com.ibm.rational.llc.engine plugin}"/>
 <instrument  saveBackups="true"
  baseLineFile="project.baseline"
   buildPath="VehicleProject"
  outputDir="VehicleProjectInstr"/>
</target>

對預期參數的快速預覽,已經列在後續的表 2 中。

表 2. 指 南任務的輸入參數

參數 描述 buildPath 對文件系統上項目的路徑 outputDir (可選的)評價項目的輸出目錄。如果沒有指定, buildPath 中的類將會進行評價。 baseLineFile (可選的)基線項目索引文件的輸出 位置。查看接下來的段落以得到關於該文件更多的信息。 saveBackups (可 選的)如果在評價之前先備份原始的類文件,那麼您可以設置為 true。

 

評價 的兩種方法都會輸出一個基線文件。所謂的基線文件是一個特定於 Rational Code Coverage 特性的概念 。基線文件包含了項目中所有類的一個索引,並維護了關於每一個類的額外元數據。該文件在報告階段( 接下來的第 3 步)使用以決定程序中的哪一個類 不被 覆蓋。該步是需要的,因為 Rational Code Coverage 數據收集引擎只是在 Java™ Virtual Machine(JVM)載入類時才會標記一個類,所以沒 有執行的類的列表在沒有元數據存在的條件下就不能進行決定了。如果基線文件沒有在報告時出現,那麼 沒有載入的類將不會出現在報告中。

第 2 步. 執行

為了執行評價好的類,您必須在啟動 時對 Java 環境做適當的配置。執行過程中所需的兩個特定的參數解釋如下:

- Dcoverage.out.file=<absolute path to output file>:該 JUM 論斷指定的文件就是覆蓋率統計 數據的輸出位置

向 classpath 添加 <Rational Application Developer HOME>/plugins/com.ibm.rational.llc.engine_<date>/RLC.jar:因為代碼已經進行了評價並 得到了 Rational Code Coverage 數據搜索引擎的回饋,RLC.jar 文件需要在運行時位於 classpath 處 。

JUnit Ant 任務提供了這些參數。代碼清單 4 提供了范例用法。

清單 4. 怎樣指定 Ant 啟動中 Rational Code Coverage 特性論斷的范例

<target name="run">
 <junit showoutput="true" fork="yes">
 <jvmarg value="- Dcoverage.out.file={absolute path to the output file}"/>
 <classpath>
  <pathelement location="{absolute path to the
  <Rational Application  Developer HOME>/plugins/com.ibm.rational.llc.engine_<date>
    /RLC.jar  file}"/>
  <pathelement location="{path to the project classes}"/>
  <pathelement path="{absolute path to the junit.jar}" />
  </classpath>
 <test name="com.ibm.vehicles.tests.TestCar" outfile="TestCar"  />
 </junit>
</target>

第 3 步. 生成報告

您可 以使用 Rational Code Coverage 特性所提供的另外一項 Ant 任務來生成報告。該項任務使用 BIRT Eclipse.org 項目所提供的報告功能,並因此需要您去下載 BIRT V2.3.2 Reporting Engine 獨立版。該 操作可以通過訪問 http://www.eclipse.org/birt/download,選擇 V2.3.2 版本並下載 Report Engine 版本來完成。注意該 Ant 任務只能產生 HTML 報告。

清單 5 提供了報告 Ant 任務的范例用法。 注意,作為輸入,它需要在第 2 步中所生成的覆蓋率數據以及在第 1 步中(可選)所生成的基線文件。

清單 5. 本文中范例程序報告生成 Ant 任務的范例

<target name="generate -report">
 <path id="lib.path">
 <pathelement location="{absolute  path to the
  <Rational Application Developer HOME>/plugins/
     com.ibm.rational.llc.common_<date>.jar plugin}"/>
 <pathelement  location="{absolute path to the
  <Rational Application Developer  HOME>/plugins/
    com.ibm.rational.llc.report_<date> plugin}"/>
 <pathelement location="{absolute path to the
  <Rational Application  Developer HOME>/plugins/
    org.eclipse.equinox.common_<date>.jar  plugin}"/>
 <fileset dir="{absolute path to the BIRT ReportEngine  directory}\lib" includes="*.jar"/>
 </path>

 <taskdef  name="code-coverage-report"
   classname="com.ibm.rational.llc.report.birt.adapters.ant.ReportGenerationTask"
   classpathref="lib.path"/>

 <code-coverage-report 
   outputDir="{absolute path to the report output directory}"
   coverageDataFile="{absolute path to the coveragedata file generated in step 1}"
  baseLineFiles="{absolute path to the baseline file generated in step  1}"/>
</target>

在圖 9 中顯示有一個范例 HTML 報告。使用 Ant 任務 生成 HTML 報告會提供一種方法,用戶可以通過這種方法來查看獨立於 Rational Application Developer 之外 Ant 環境中生成的統計數據。

圖 9. HTML 報告中的覆蓋率結果

嘗試一下!

本文的 下載 部分為 Ant 環境提供了范例腳本以及構建文件,該環境可以 用於指導、執行並生成關於范例程序的報告。如果您對測試該環境感興趣,那麼您可以參考一下 Standalone.zip 文件中的 README 文件。

在 WebSphere Application Server 上生成統計數據

使用 WebSphere Application Server 來生成代碼覆蓋率統計數據在這裡是支持的,但是不幸的 是,這個版本中並不支持來自 Rational Application Developer 內部的自動化配置。但是,版本中提供 的 Rational Code Coverage 特性足夠靈活以集成到服務器環境中去,包括 WebSphere Application Server。為了對代碼覆蓋率而配置您的 WebSphere Application Server ,您需要按照以下步驟進行操作 :

啟動服務器

登錄到 Administrative Console

在左邊的窗格中,展開 Servers

展開 Server Types

點擊 WebSphere 程序服務器

選擇適當的程序服務器

展開右 部窗格選項區域內 Server Infrastructure 部分中 Java and Process Management 項

點擊 Process definition

點擊 Additional Properties 部分中的 Java Virtual Machine

在 Boot Classpath 部分中,添加 RLC.jar 文件。如上面介紹的那樣,該 .jar 文件位於 Rational Code Coverage 數據收集引擎中,並位於 <Rational Application Developer HOME>/plugins/com.ibm.rational.llc.engine_<date>/RLC.jar

在 Generic JVM arguments 中,添加 -Dcoverage.out.file={output file} JVM 論斷。如上面所述的那樣,該論斷指定 了應該將輸出的統計數據保存在什麼地方。

保存服務器配置並重啟服務器。

圖 10 顯示了 在作出以上所做的變更之後 Administrative Console 的屏幕截圖。注意在每一個服務器實例的後面必須 有一個指南,這些服務器實例會執行一個代碼覆蓋率程序。

圖 10. WebSphere Application Server 對 Rational Code Coverage 特性的配置

在服務器對代碼覆蓋 率進行配置之後,您就可以手動對服務器進行代碼覆蓋率的配置了(從 Administration Console 上進行 ),或者使用 Rational Application Developer 中的集成支持功能。注意覆蓋率的結果不會自動導入到 Rational Application Developer 中以進行分析,這樣您需要執行接下來的步驟來將統計數據導回到工 作區中:

在 Rational Application Developer 中的 Java 視角中,右擊 Package Explorer 並 選擇 Import

展開 Code Coverage

選擇 Code Coverage Data File 並點擊 Next

選擇 Data is located on the file system 選項並點擊 Next

在 Coverage Data file 區域中,選擇服務器所提供的文件系統上的覆蓋率數據

在 Into folder 區域中,選擇工作區中的 一個目錄以保存導入的文件。

在 Associate with Project 區域中選擇適當的項目。您應該將統 計數據與工作區中的項目聯系起來,工作區中包含的源代碼用於在服務器上生成統計數據。

點擊 Finish

當覆蓋率數據文件位於工作區中時,您可以在 UI 中顯示統計數據並生成報告。您可以右 擊覆蓋率文件並選擇 Code Coverage > Show code coverage indicators 或者 Generate Report 來 完成該操作。該功能可以使您更加受益,因為它提供了對分析 Rational Application Developer 中結果 所用所有工具的訪問途徑。

原文: http://www.ibm.com/developerworks/cn/rational/10/introtocodecoveragetoolinrationalapplicatio ndeveloper/index.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved