知识大全 巧用工具 为Java程序生成代码做覆蓋统计

Posted

篇首语:古之立大事者,不惟有超世之才,亦必有坚忍不拔之志。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 巧用工具 为Java程序生成代码做覆蓋统计相关的知识,希望对你有一定的参考价值。

巧用工具 为Java程序生成代码做覆蓋统计  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  曾经为大家相信介绍过 款常用Java测试工具 代码覆蓋率工具这项软件测试过程中使用的一个重要的工具却从来没介绍过 来为Java?程序生成测试的覆蓋率结果 并提供了关于怎样分析结果以改进测试的信息 本文向您展示了怎样使用IBM一款开发工具(IBM? Rational? Application Developer)中提供的代码覆蓋工具如何来为Java?程序生成测试的覆蓋率结果

  什么是Rational Code Coverage特性?

  代码覆蓋率是软件测试的一个重要方面 对于一个构件的总体系统测试来说可能是一个基本的参数 覆蓋工具背后的动机向您(作为开发员或者测试员)提供了关于代码的一系列观点 这些代码在一系列的测试之中会得到检查 该信息会非常的有用 因为您可以使用它来设计新的测试用例以获得足够的覆蓋范围

  IBM? Rational? Code Coverage特性是一个与IBM? Rational? Application Developer相集成的工具 您可以使用它来生成并分析关于Java程序的覆蓋率统计数据 工具会为测试下的程序生成声明覆蓋率统计数据(这就是说 执行程序中行的数量与百分比)

  Rational Code Coverage特性现在只能获得Rational Application Developer 版本及其后续版本 本文假设您使用的是Rational Application Developer 版本 对代码覆蓋率而配置IBM? WebSphere?Application Server的部分假设您使用的是 版本 但是提供的指南的一些调整仍然适用于上述版本

  指南

  为了适当地分析Rational Code Coverage特性中的覆蓋率统计数据 理解场景背后所用到的技术是非常重要的

  Eclipse Test与Performance Tools Project(TPTP)中提供的Rational Code Coverage特性所使用的工具引擎 Probekit用于控制一个类的比特代码 并引入覆蓋率数据收集引擎的通用访问 图 提供了关于这个过程的一个高层次的概述

  图 Rational Code Coverage执行环境的概述

  基本快与可执行的单元

  Probekit是一种在Eclipse平台上的框架 并可以操作所谓可执行单元的比特代码 可执行单元的定义与基本块的传统定义有轻微的不同 但是当您在分析结果时 您就需要去关注这点差异了

  根据定义 一个所谓的基本块就是一系列的指南 这些指南不能再进行分支或者分散 这里的关键思想在于 当第一个指南运行的时候 该块中随后所有指南都一定会得到执行而且不会得到中断 接下来的是一个基本块 它可以认为是一个单个组或者一系列的指南 通常来说 基本块的结尾是branch call throw或者return声明

  一个可执行的单元由每一个基本快开始 而与每行源代码相对应的指南与前面版本中的指南有所不同 可执行的单元与基本块的不同点 在于决定一个可执行单元末尾的因素 例如 pide指南并没有认为是一个可执行单元的结尾 尽管有例外情况的存在

  Probekit是Rational Code Coverage特性所使用的 以将通用代码引入到每一个可执行的单元之中 结果来说 您可以定制Rational Code Coverage特性以向组成性(换句话说 就是块覆蓋率)可执行单元层次报告统计数据 为了知道这些工具是怎样更改类了 您可以参考接下来的代码清单 与代码清单 代码清单 提供了未处理类的分解输出(从javap工具来) 同时代码清单 为处理过的类提供了分解输出 注意代码清单 中italics的行就是作为处理步骤一部分导入的代码部分

  清单 未处理的类文件

   Compiled from Part java

   public class ibm storeapp models Part extends java lang Object

   public ibm storeapp models Part(int);

     Code:

      :   aload_

      :   invokespecial   # ; //Method java/lang/Object <init> :()V

      :   iload_

      :   bipush 

      :   if_icmple      

      :  aload_

      :  iload_

      :  invokespecial   # ; //Method setDiscountedPrice:(I)V

      :  goto   

      :  aload_

      :  iload_

      :  putfield        # ; //Field price:I

      :  return

  

      public int getPrice();

     Code:

      :   aload_

      :   getfield        # ; //Field price:I

      :   ireturn

  

  

  清单 每一个可执行单元处理的类文件

   Compiled from Part java

   public class ibm storeapp models Part extends java lang Object

   public ibm storeapp models Part(int);

   Code:

     : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :   aload_

   :   invokespecial   # ; //Method java/lang/Object <init> :()V

   : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :  iload_

   :  bipush 

   :  if_icmple      

   : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :  aload_

   :  iload_

   :  invokespecial   # ; //Method setDiscountedPrice:(I)V

   : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :  goto   

   : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :  aload_

   :  iload_

   :  putfield        # ; //Field price:I

   : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :  return

  

   public int getPrice();

   Code:

   : ldc # ; //String /ibm/storeapp/models/Part : iconst_ : iconst_ :

       invokestatic # ; //Method llc_probe$Probe_ _executableUnit:(Ljava/lang/String;II)V

   :   aload_

   :   getfield        # ; //Field price:I

   :  ireturn

   static ; Code: : ldc # ; //String /ibm/storeapp/models/Part : ldc # ;

       //String Part java : ldc # ; //String <init>(I)V+setDiscountedPrice(I)V

       +getPrice()I : ldc # ; //String # + : invokestatic # ;

       //Method llc_probe$Probe_ _staticInitializer:

       (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V : return

  

  

  在Rational Application Developer中生成覆蓋率统计数据

  Rational Code Coverage特性的一个主要的优势在于 您可以通过切换到项目Properties的Code Coverage窗格 来将其在Rational Application Developer中的Java项目上激活 如图 所示

  图 项目Properties中的代码覆蓋窗格

  选择图 中的Enable code coverage复选框以激活项目的代码覆蓋率 并评价覆蓋下项目的类 您还可以使用该窗格来定制可接受的覆蓋率层次 接下来描述了组合的支持层次

  ◆类型覆蓋率 一个类中覆蓋的类型百分比

  ◆方法覆蓋率 一个类中覆蓋的方法百分比

  ◆行覆蓋率 类文件中覆蓋的行百分比

  ◆块覆蓋率 一个类文件中覆蓋的块的百分比 注意一个块会参考一个可执行的单元(如以前描述的那样)

  您还可以指定通用的筛选规则 而且它们可以用于控制在项目中评价哪些内容 默认条件下 项目中的所有类都会得到评价 但是您可以创建通用的筛选规则来排除目标包或者指定类型 如果您需要限制结果的话

  Package Explorer

  在您激活一个项目中的代码覆蓋率以后 覆蓋率统计数据就会在下一次程序启动的时候生成 注意不是所有类型启动配置都会自动生成统计数据 表 显示了Rational Application Developer内支持的启动类型

  表 支持的启动配置

   启动类型 Java Applet OSGi框架 JUnit JUnit插件测试 Java程序 Eclipse程序 标准Widget Toolkit (SWT)程序

  该程序是一个不同交通工具(汽车 货车 摩托车等等)的简单再现 图 中是一个概括了该程序结构的UML图

  图 范例程序的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来分析它们 图 显示了TestCar java测试的一个范例结果

  图 Package Explorer中显示的TestCar java的覆蓋率数据

  默认条件下 UI只与行覆蓋率信息一起注释 但是 您可以在工作台偏好中更改它们 并且可以选择为包 类型以及块而包含覆蓋率 每一个Java项目的百分比是最后一次执行代码覆蓋率的中断 您可以在Package Explorer中深入研究各种Java工件(例如 类 类型与方法)以得到较低组合层次上的覆蓋率统计数据

  结果得到的结果的颜色情况取决于成功率 默认条件下 红色意味着没有达到可接受的覆蓋率层次 而绿色则意味着得到了适当的覆蓋率范围 一般来说 测试的目的在于达到类可接受覆蓋率层次的结果

  基于如图 所示的结果 第一个测试是不充分的 Car类(以及抽象父类AbstractFourWheelVehicle和Vehicle)并不能达到适当的覆蓋率层次 幸运的是 您有第二次尝试的机会 TestCarImproved java 您可以再一次将测试作为一次正常的JUnit执行 而结果将会在Package Explorer中进行自动更新(图 )

  图 Package Explorer中显示的TestCarImproved java的代码覆蓋率数据

  Java编辑器

  行覆蓋率结果也是显示的 并在Java编辑器中有所标记 而您可以使用它来得到一个更加明确的指示 也就是每一类中涉及到了哪一行 在生成覆蓋率数据之后 您就可以使用Java编辑器来在项目中打开任意的类了 编辑器中左边的标尺栏显示了关于覆蓋率的信息 图 显示了Vehicle java的结果

  图 Java编辑器中显示的覆蓋率结果

  颜色编辑与在Package Explorer中所显示的是一样的 也就是 默认条件下 绿色的行是覆蓋的而红色的则不是覆蓋的 在Java编辑器中查看结果有一个微弱的优势 那就是它还指示了部分覆蓋的行 当在源代码中有不止一个的可执行单元时就会产生部分覆蓋的行 但是它们中只有一个可以被执行 例如 查看图 中setTargetSpeed(int speed)方法中第一行的代码 第一个可执行的单元是if声明 而第二个可执行的单元则是return声明 默认条件下 一个部分的行会被标上黄色

  生成报告

  您可以将代码覆蓋率结果数据汇编到报告之中并在Rational Application Developer中查看它们 或者将它们保存到文件系统中以便未来的分析 您可以生成两种不同类型的报告 Workbench报告(基于Eclipse)与HTML报告 为了生成一份报告 您可以选择Run>Code Coverage>Generate Report 图 显示了报告生成对话框

  图 报告生成对话框

  您可以在Rational Application Developer中使用对话框中的Quick View选项来创建并查看一个报告 或者使用Save Report选项将其保存到文件系统中去

  工作台报告

  工作台报告(也叫做基于Eclipse的报告)为项目提供了所有覆蓋率统计数据的稳固视图 并包含了执行时项目中所有类的覆蓋率数据 图 显示了一个基于Eclipse流传的报告

  图 一个基于Eclipse报告的覆蓋率结果

  工作台报告与Rational Application Developer相集成具有额外的优势 因为您可以使用它们作为一个快速的工具 以提供了关于部分代码的视角 这些代码需要改进的测试覆蓋率数据 如图 所示 工作台报告中的统计数据包含了所有层次组成的覆蓋率信息 从一个包到一种方法 右击任意的Java工件会显示出一个带有两种操作的弹出菜单 在Package Explorer中显示与在Java编辑器中将其打开 对于识别和研究带有低覆蓋率的代码区域来说 它们是非常有用的工具 因为通过将它们在适当的浏览器或者编辑器中打开 从而强调了代码的选择区域

  HTML报告

  HTML报告显示了基于Eclipse报告所提供的相同类型的信息 但是呈现的格式却是HTML的 这些报告能够发挥一定程度的作用 因为它们为在独立于Rational Application Developer之外去分析覆蓋率数据提供了一种有效的方法 您可以与团队的其他成员一起分享 或者将其发布到一个网站上以方便查看

  在工作台的外部生成统计数据

  Rational Code Coverage工具的一个主要特性是其在Rational Application Developer外部生成统计数据的能力 它提供了额外的灵活性 并使得您可以定制环境以利用系统中的Rational Code Coverage特性 例如 一个自然的合并过程就是创建一个构建环境并使用JUnit测试来生成统计数据

  通过执行以下的三个步骤 评价 执行以及生成报告 您可以将Rational Code Coverage特性集成到您的环境之中

  第 步 评价

  您可以使用两种不同的方法来评价您的程序 第一个就是使用<RAD_HOME>/plugins/ ibm rational llc engine_<date>/scripts目录中提供的instrument bat/sh脚本 本文并没有关注这个脚本 但是您可以参考Rational Application Developer文献以得到更多的信息 如果需要的话 第二个方法是使用Rational Code Coverage特性提供的评价Ant任务 代码清单 显示了评价任务配置的范例用法 以得到本文中的范例程序

  清单 本文范例程序的评价Ant任务的范例用法

   <target name= instrument >

     <taskdef name= instrument

       classname= ibm rational llc engine instrumentation anttask InstrumentationTask

       classpath= path to ibm rational llc engine plugin />

     <instrument saveBackups= true

       baseLineFile= project baseline

       buildPath= VehicleProject

       outputDir= VehicleProjectInstr />

   </target>

  对预期参数的快速预览 已经列在后续的表 中

  表 指南任务的输入参数

  参数描述

  buildPath对文件系统上项目的路径

  outputDir(可选的)评价项目的输出目录 如果没有指定 buildPath中的类将会进行评价

  baseLineFile(可选的)基线项目索引文件的输出位置 查看接下来的段落以得到关于该文件更多的信息

  saveBackups(可选的)如果在评价之前先备份原始的类文件 那么您可以设置为true

  评价的两种方法都会输出一个基线文件 所谓的基线文件是一个特定于Rational Code Coverage特性的概念 基线文件包含了项目中所有类的一个索引 并维护了关于每一个类的额外元数据 该文件在报告阶段(接下来的第 步)使用以决定程序中的哪一个类不被覆蓋 该步是需要的 因为Rational Code Coverage数据收集引擎只是在Java? Virtual Machine(JVM)载入类时才会标记一个类 所以没有执行的类的列表在没有元数据存在的条件下就不能进行决定了 如果基线文件没有在报告时出现 那么没有载入的类将不会出现在报告中

  第 步 执行

  为了执行评价好的类 您必须在启动时对Java环境做适当的配置 执行过程中所需的两个特定的参数解释如下

  ◆ Dcoverage out file=<absolute path to output file> 该JUM论断指定的文件就是覆蓋率统计数据的输出位置

  ◆向classpath添加<Rational Application Developer HOME>/plugins/ ibm rational llc engine_<date>/RLC jar 因为代码已经进行了评价并得到了Rational Code Coverage数据搜索引擎的回馈 RLC jar文件需要在运行时位于classpath处

  JUnit Ant任务提供了这些参数 代码清单 提供了范例用法

  清单 怎样指定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/ 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= ibm vehicles tests TestCar outfile= TestCar />

   </junit>

   </target>

  第 步 生成报告

  您可以使用Rational Code Coverage特性所提供的另外一项Ant任务来生成报告 该项任务使用BIRT 项目所提供的报告功能 并因此需要您去下载BIRT V Reporting Engine独立版 该操作可以通过访问 选择V 版本并下载Report Engine版本来完成 注意该Ant任务只能产生HTML报告

  清单 提供了报告Ant任务的范例用法 注意 作为输入 它需要在第 步中所生成的覆蓋率数据以及在第 步中(可选)所生成的基线文件

  清单 本文中范例程序报告生成Ant任务的范例

   <target name= generate report >

   <path id= lib path >

     <pathelement location= absolute path to the

       <Rational Application Developer HOME>/plugins/

           mon_<date> jar plugin />

     <pathelement location= absolute path to the

       <Rational Application Developer HOME>/plugins/

           ibm rational llc report_<date> plugin />

     <pathelement location= absolute path to the

       <Rational Application Developer HOME>/plugins/

           mon_<date> jar plugin />

     <fileset dir= absolute path to the BIRT ReportEngine directory\\lib includes= * jar />

   </path>

  

   <taskdef name= code coverage report

      classname= ibm rational llc report birt adapters ant ReportGenerationTask

      classpat/>

  

   <code coverage report

      outputDir= absolute path to the report output directory

      coverageDataFile= absolute path to the coveragedata file generated in step

      baseLineFiles= absolute path to the baseline file generated in step />

   </target>

  在图 中显示有一个范例HTML报告 使用Ant任务生成HTML报告会提供一种方法 用户可以通过这种方法来查看独立于Rational Application Developer之外Ant环境中生成的统计数据

  图 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/ ibm rational llc engine_<date>/RLC jar

   在Generic JVM arguments中 添加 Dcoverage out file=output file JVM论断 如上面所述的那样 该论断指定了应该将输出的统计数据保存在什么地方

   保存服务器配置并重启服务器

  图 显示了在作出以上所做的变更之后Administrative Console的屏幕截图 注意在每一个服务器实例的后面必须有一个指南 这些服务器实例会执行一个代码覆蓋率程序

  图 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中结果所用所有工具的访问途径

cha138/Article/program/Java/hx/201311/25668

相关参考

知识大全 提高代码质量及字节码防止内存错误

  大多Java程序员知道他们的程序通常不会被编译为本机代码而是被编译为由java虚拟机(JVM)执行的字节码格式然而很少有java程序员曾经看过字节码因为他们的工具不鼓励他们去看大多Java调试工具

知识大全 用Java代码生成打印收据

用Java代码生成打印收据  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  首先来看看效果如下图 

知识大全 为测试 Java 应用程序生成证书链

为测试Java应用程序生成证书链  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  学习如何创建数字

知识大全 轻松有效检查Java代码的三个工具

轻松有效检查Java代码的三个工具  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java项目最

知识大全 Java程序性能优化-代码调优

Java程序性能优化-代码调优  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!   代码调

知识大全 Java 发Post请求实例程序代码

Java发Post请求实例程序代码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  //说明使用j

知识大全 Java中国象棋博弈程序探秘之生成有效着法

Java中国象棋博弈程序探秘之生成有效着法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  着法生

知识大全 使用Eclipse调试Java程序的代码介绍

使用Eclipse调试Java程序的代码介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs

知识大全 DWR调用客户端Java代码的程序实例

DWR调用客户端Java代码的程序实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  //———

知识大全 如何防止JAVA程序源代码被反编译

如何防止JAVA程序源代码被反编译  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  我们都知道JA