Java代码质量检查工具及使用案例

2023-06-05 0 857

序言

在那时的应用软件设计中,虽然应用软件的维数愈来愈高,销售业务也全面覆盖很广,各销售业务组件销售业务错综。这种就须要他们须要工程项目组合作开发,在他们工程项目组中合作开发者的实战经验、标识符艺术风格式样都不完全一致,和缺少国际标准化的国际标准,进而引致我们的整座工程项目的的标识符无法写作,不易于中后期保护。这两天在科学研究标识符产品质量管理工作,依照在网路上收集的数据资料及跟后辈学的一点儿实战经验重新整理呵呵,有须要的全校师生能查阅,也易于之后他们简述。

主要就对上面的四块展开预测

代码文件格式规范

标识符多次重复

标识符全面覆盖面积

倚赖项预测

维数监视

Java演示控制技术

标识符评审委员和解构

接下去的采用Eclipse 应用程序来阐明那些预测应用领域:

代码文件格式规范化:codeStyle和CheckStyle

标识符多次重复:PMD 的 CPD

标识符全面覆盖面积:Coverlipse或是Emma

倚赖项预测:JDepend

维数监视:Metrics

Java演示控制技术:EasyMock、PowerMock

标识符评审委员和解构:Jupiter

代码文件格式规范化

codestyle如是说

国际标准化的标识符规范化能提高标识符的可读性、可保护性。

一般规则和文件格式规范化:如标识符缩进、程序块规范化、每行最大标识符长度;

命名规范化:如包名、类名、接口名、枚举、属性名、方法名、参数名等命名规则;

文档规范化:如类文件头注释、变量注释、方法注释等;

编程规范化:如异常、并发、多线程等;

其它规范化:如日志文件格式等。

Java代码质量检查工具及使用案例
图1

能导入标识符文件格式,实现国际标准化。

checkstyle如是说

安装checkstyle 的Eclipse应用程序

1.下载地址:

http://pan.baidu.com/s/1o6LOSwM

2.解压

net.sf.eclipsecs-updatesite_5.6.1.201306282206-bin.zip文件,到系统路径下。如:D:\geyouchao\eclipse-plugins\cs(注:一定不用起名为checkstyle,不知道为什么此名就是安装不成功),此文件夹下有两个文件夹features、plugins。

3.他们采用link的方式安装。在Eclipse的dropins文件夹下新建checkstyle.link文件,内容为:

path=D:\\geyouchao\\eclipse-plugins\\cs

4.关闭Eclipse,重启。然后在Eclipse的window》Preferences下就能看到checkstyle菜单,安装成功,如下图

Java代码质量检查工具及使用案例
图2

采用checkstyle

自定义CheckStyle规则,上面是我定义的CheckStyle模板,然后导入

Java代码质量检查工具及使用案例
图3

把新导入的,设置为默认

Java代码质量检查工具及使用案例
图4

能修改其中的值,点击“Configure…”按钮。

Java代码质量检查工具及使用案例
图5

上面是我自定义的CheckStyle.xml文件,供参考。

<xml version=”1.0″encoding=”UTF-8″> <!DOCTYPE module PUBLIC “-//PuppyCrawl//DTD Check Configuration 1.2//EN””http://www.puppycrawl.com /dtds/configuration_1_2.dtd”> <module name=”Checker”> <propertyname=”severity” value=”warning”/> <property name=”charset” value=”UTF-8″/> <!– 长度方面的检查 –> <!– 文件长度不超过1500行 –> <module name=”FileLength”> <property name=”max” value=”1500″ /> </module> <module name=”TreeWalker”> <!– javadoc的检查 –> <!– 检查所有的interface和class –> <module name=”JavadocType” /> <!– 命名方面的检查 –> <!– 局部的final变量,包括catch中的参数的检查 –> <module name=”LocalFinalVariableName” /> <!– 局部的非final型的变量,包括catch中的参数的检查 –> <module name=”LocalVariableName” /> <!– 包名的检查(只允许小写字母) –> <module name=”PackageName”> <property name=”format”value=”^[a-z]+ (\.[a-z][a-z0-9]*)*$” /> </module> <!–仅仅是static型的变量(不包括static final型 )的检查 –> <module name=”StaticVariableName” /> <!– 类型(Class或Interface)名的检查 –> <module name=”TypeName” /> <!– 非static型变量的检查 –> <module name=”MemberName” /> <!– 方法名的检查 –> <module name=”MethodName” /> <!– 方法的参数名 –> <modulename=”ParameterName ” /> <!– 常量名的检查 –> <module name=”ConstantName” /> <!– 没用的import检查,比如:1.没有被用到 2.多次重复的 3.import java.lang的 4.import 与该类在同一个package的 –> <module name=”UnusedImports” /> <!– 每行不超过150个字–> <module name=”LineLength”> <property name=”max” value=”150″ /> </module> <!– 方法不超过150行 –> <module name=”MethodLength”> <property name=”tokens” value=”METHOD_DEF”/> <property name=”max”value=”150″ /> </module> <!– 方法的参数个数不超过5个。并且不对构造方法展开检查–> <module name=”ParameterNumber”> <property name=”max” value=”5″ /> <property name=”tokens” value=”METHOD_DEF”/> </module> <!– 空格检查 –> <!– 允许方法名后紧跟左边圆括号”(” –> <module name=”MethodParamPad” /> <!– 在类型转换时,不允许左圆括号右边有空格,也不允许与右圆括号左边有空格 –> <module name=”TypecastParenPad” /> <!– 关键字 –> <!– 每个关键字都有正确的出现顺序。比如 public static final XXX 是对一个常量的声明。如果采用 static public final 就是错误的 –> <module name=”ModifierOrder” /> <!– 多余的关键字 –> <module name=”RedundantModifier” /> <!– 对区域的检查 –> <!– 不能出现空白区域 –> <module name=”EmptyBlock” /> <!– 所有区域都要采用大括号 –> <module name=”NeedBraces” /> <!– 多余的括号 –> <module name=”AvoidNestedBlocks”> <property name=”allowInSwitchCase” value=”true”/> </module> <!– 代码方面的检查 –> <!– 不许出现空语句 –> <module name=”EmptyStatement” /> <!– 不允许魔法数 –> <module name=”MagicNumber”> <property name=”tokens”value=”NUM_DOUBLE, NUM_INT” /> </module> <!– 多余的throw –> <module name=”RedundantThrows” /> <!– String的比较不能用!= 和 == –> <module name=”StringLiteralEquality” /> <!– if最多嵌套3层 –> <module name=”NestedIfDepth”> <property name=”max” value=”3″ /> </module> <!– try最多被嵌套2层 –> <module name=”NestedTryDepth”> <property name=”max” value=”2″ /> </module> <!– clone方法必须调用了super.clone() –> <module name=”SuperClone” /> <!– finalize 必须调用了super.finalize() –> <module name=”SuperFinalize” /> <!– 不能catch java.lang.Exception –> <module name=”IllegalCatch”> <property name=”illegalClassNames”value=”java.lang.Exception” /> </module> <!– 确保一个类有package声明 –> <module name=”PackageDeclaration” /> <!– 一个方法中最多有3个return –> <modulename=”ReturnCount”> <property name=”max” value=”3″ /> <property name=”format” value=”^$” /> </module> <!– 依照 Sun 代码规范化, class 或 interface 中的顺序如下: 1.class 声明。首先是 public, 然后是protected , 然后是 package level (不包括access modifier )最后是private . (多个class放在一个java文件中的情况) 2.变量声明。首先是 public, 然后是protected然后是 package level (不包括access modifier )最后是private . (多个class放在一个java文件中的情况) 3.构造函数 4.方法 –> <module name=”DeclarationOrder” /> <!– 同一行不能有多个声明 –> <module name=”MultipleVariableDeclarations” /> <!– 不必要的圆括号 –> <module name=”UnnecessaryParentheses” /> <!– 检查并确保所有的常量中的L都是大写的。因为小写的字母l跟数字1太象了 –> <module name=”UpperEll” /> <!– 检查数组类型的定义是String[] args,而不是String args[] –> <module name=”ArrayTypeStyle” /> <!– 检查java标识符的缩进默认配置:基本缩进4个空格,新行的大括号:0。新行的case 4个空格 <module name=”Indentation” /> </module> </module>

上面是采用CheckStyle检查过得标识符

Java代码质量检查工具及使用案例
图6

常见错误预测

常见的CheckStyle错误有那些:

1.Type is missing a javadoc commentClass

缺少类型说明

2.“{” should be on the previous line

“{” 应该位于前一行

3.Methods is missing a javadoc comment

方法前面缺少javadoc注释

4.Expected@throwstag for “Exception”

在注释中希望有@throws的说明

5.“.” Is preceeded with whitespace “.”

前面不能有空格

6.“.” Is followed by whitespace“.”

后面不能有空格

7.“=” is not preceeded with whitespace

“=” 前面缺少空格

8.“=” is not followed with whitespace

“=” 后面缺少空格

9.“}” should be on the same line

“}” 应该与下条语句位于同一行

10.Unused@paramtag for “unused”

没有参数“unused”,不需注释

11.Variable “CA” missing javadoc

变量“CA”缺少javadoc注释

12.Line longer than 80characters

行长度超过80

13.Line contains a tab character

行含有”tab” 字符

14.Redundant “Public” modifier

冗余的“public”modifier

15.Final modifier out of order with the JSL

suggestionFinal modifier的顺序错误

16.Avoid using the “.*” form of import

Import文件格式避免采用“.*”

17.Redundant import from the same package

从同一个包中Import内容

18.Unused import-java.util.list

Import进来的java.util.list没有被采用

19.Duplicate import to line 13

多次重复Import同一个内容

20.Import from illegal package

从非法包中 Import内容

21.“while” construct must use “{}”

“while” 语句缺少“{}”

22.Variable “sTest1” must be private and haveaccessor method

变量“sTest1”应该是private的,并且有调用它的方法

23.Variable “ABC” must match pattern“^[a-z][a-zA-Z0-9]*$”

变量“ABC”不符合命名规则“^[a-z][a-zA-Z0-9]*$”

24.“(” is followed by whitespace

“(” 后面不能有空格

25.“)” is proceeded by whitespace

“)” 前面不能有空格

标识符多次重复

PMD如是说

安装PMD 的Eclipse应用程序

1.下载地址:

http://jingyan.baidu.com/article/1919 2ad835de6ee53e57073c.html

2.解压

net.sourceforge.pmd.eclipse-3.2.6.v200903300643.zip文件,到系统路径下。如:D:\geyouchao\eclipse-plugins\pmd,此文件夹下有两个文件夹features、plugins。

3.他们采用link的方式安装。在Eclipse的dropins文件夹下新建pmd.link文件,内容为:

path=D:\\geyouchao\\eclipse-plugins\\pmd

4.关闭Eclipse,重启。然后在Eclipse的window》Preferences下就能看到PMD菜单,安装成功,如下图

Java代码质量检查工具及使用案例
图7

采用PMD

Java代码质量检查工具及使用案例
图8

上面是PCD生成的多次重复标识符,能对其中的标识符展开预测,修改

Java代码质量检查工具及使用案例
图9

标识符全面覆盖面积

Coverlipse如是说

安装coverlipse 的Eclipse应用程序

1.下载地址:

https://sourceforge.net/projects/coverlipse /files/Coverlipse/

下载下图中5个文件

Java代码质量检查工具及使用案例
图10

1.解压coverlipse-0.9.6.zip文件,到系统路径下。如:D:\geyouchao\eclipse-plugins\ coverlipse-0.9.6,此文件夹下有两个文件夹features、plugins。

2.他们采用link的方式安装。在Eclipse的dropins文件夹下新建coverlipse.link文件,内容为:

path=D:\\geyouchao\\eclipse-plugins\\coverlipse

3.关闭Eclipse,重启。右键java标识符,点击dubug,安装成功,如下图

Java代码质量检查工具及使用案例
图11

倚赖项分析

jdepend如是说

安装jdepend 的Eclipse应用程序

1.下载地址:

http://andrei.gmxhome.de/ jdepend4eclipse/links.html

Java代码质量检查工具及使用案例
图12

2.拷贝

de.loskutov.eclipse.jdepend_1.2.4.201406241900.jar文件,到Eclipse的dropins目录下。如:D:\geyouchao\eclipse4.2-xu\dropins。

3.关闭Eclipse,重启。通过右键单击源文件夹并选择Run JDepend Analysis。一定要选择一个含源标识符的源文件夹;否则看不到此菜单项。

Java代码质量检查工具及使用案例
图13

采用jdepend

Java代码质量检查工具及使用案例
图14

上面对jdepend的预测的结果简单如是说

Java代码质量检查工具及使用案例
图15

1.Selected objects():选择预测的包

2.Package:包全路径

http://3.CC(concr.cl.):当前行对应包的具体类的数量。

4.AC(abstr.cl.):当前行对应包的抽象类和接口的数量。

http://5.Ca(aff.):倚赖于被预测package的其他package的数量,用于衡量pacakge的职责。即有多少包调用了它。(AfferentCouplings)

6.Ce(eff.):被预测package的类所倚赖的其他package的数量,用于衡量package的独立性。即它调用了多少其他包。(EfferentCouplings)

7.A:被预测package中的抽象类和接口与所在package所有类数量的比例,取值范围为0-1。(Abstractness)

8.I:I=Ce/(Ce+Ca),用于衡量package的不稳定性,取值范围为0-1。I=0表示最稳定,I=1表示最不稳定。即如果这个类不调用任何其他包,则它是最稳定的。(Instability)

9.D:预测package和理想曲线A+I=1的垂直距离,用于衡量package在稳定性和抽象性之间的平衡。(Distance)

理想的package要么完全是抽象类和稳定(x=0,y=1),要么完全是具体类和不稳定(x=1,y=0)。取值范围为0-1,

D=0表示完全符合理想国际标准,

D=1表示package最大程度地偏离了理想国际标准。即你的包要么全是接口,不调用任何其他包(完全是抽象类和稳定),要么是具体类,不被任何其他包调用。

10.Cycle!:循环倚赖

11. Package with cycle:包与包直接有循环调用

12. Depends

upon-efferentdependencies:倚赖的包

13. Used by-afferentdependencies:被引用的包

Java代码质量检查工具及使用案例
图16

Instability:不稳定

Abstractness:抽象性

问题预测

Java代码质量检查工具及使用案例
图17

针对上图中Cycle!列中有感叹号图标问题,是因为以上三个包中的类有传递倚赖,故出现此警告。

解决办法:

把其中的某个或是某些类再单独抽出新包,解决此问题。

维数监视

metrics(量度)如是说

安装metrics 的Eclipse应用程序

1.下载地址:

https://sourceforge.net/projects/metrics/

Java代码质量检查工具及使用案例
图18
Java代码质量检查工具及使用案例
图19
Java代码质量检查工具及使用案例
图20
Java代码质量检查工具及使用案例
图21

2.解压updatesite_1.3.6.zip文件,

net.sourceforge.metrics.updatesite文件夹下有features和plugins分别拷贝到Eclipse的对应目录下。如:D:\geyouchao\eclipse4.2-xu\plugins等。

3.关闭Eclipse,重启。然后在Eclipse的window》Preferences下就能看到Metrics Preferences菜单,安装成功,如下图

Java代码质量检查工具及使用案例
图22

设置metrics参数

下图是metrics提供的配置项,上面对各配置项展开解释

Java代码质量检查工具及使用案例
图23
Java代码质量检查工具及使用案例

lack of cohesion of methods:

介于0-1之间,0表示最有凝聚力,1表示完全没有凝聚力。

1)如果所有方法都采用所有的实例字段,一个类是完全有凝聚力的

2)静态方法和实例方法计数,它还包括构造函数、属性的getter和setter,所有方法。

在Since Sonar 4.1中此量度已经被删除。

3) 子的数量NOC(Number ofchildren)子类在类的层次内,子类能最直接地从属于一类。随着子类数量的增大,重用也增加了。但父类抽象的表示可能减少,即一些子类可能不是父类真正的成员,同时,测试数量(用来检查每个子类在操作前后的要求)也将增加。

4) 方法中聚合的不足LCOM(Lack ofcohesion in Methods)

一个类内的每种方法访问一个或多个属性(也称实例变量)。LCOM是访问一个或多个相同属性方法的数量

如果LCOM很大,则说明方法能通过属性与其他方法耦合,这就增加了类设计的复杂性。通常,对LCOM值很大的类,能把它分为两个或多个单独的类,这种每个类能的设计更方便。

这里讲的耦合和聚合与传统应用软件中讲的是一样的。他们希望高聚合和低耦合,即保持低的LCOM.但在某些时候,LCOM很大也是合理的。

5)每个类的加权方法WMC(Weighted Methodsper Class)

6)Out-of-range:超出范围,溢出

上面是metric的安全范围设置,在此页面中能设置每项指标的安全范围。若警告启用,指标值超出他们设置的安全范围就好发出警告。

Java代码质量检查工具及使用案例
图24

采用metrics

1.右键单击您的工程项目并选择 Properties 菜单。在结果窗口中,选择 EnableMetrics plugin 复选框并单击 OK:

Java代码质量检查工具及使用案例
图25

2.从 Eclipse 中选择 Window 菜单打开 Metrics 视图,然后选择 Show View | Other…。

3.选择 Metrics | Metrics View 打开如图 13 中显示的窗口。您须要采用Java 透视图并重新构建工程项目,进而显示那些度量值。

Java代码质量检查工具及使用案例
图26

注:一定要重新构建工程项目

Java代码质量检查工具及使用案例
图27

Java 演示控制技术(mock)

Mock是什么

Mock通常是指,在测试一个对象A时,他们构造一些假的对象来演示与A之间的交互,而那些Mock对象的行为是他们事先设定且符合预期。通过那些Mock对象来测试A在正常逻辑,异常逻辑或压力情况下工作是否正常。

引入Mock最大的优势在于:Mock的行为固定,它确保当你访问该Mock的某个方法时总是能够获得一个没有任何逻辑的直接就返回的预期结果。

Mock Object的采用通常会带来以下一些好处:

隔绝其他组件出错引起本组件的测试错误。

隔绝其他组件的合作开发状态,只要定义好接口,不用管他们合作开发有没有完成。

一些速度较慢的操作,能用MockObject代替,快速返回。

对于分布式系统的测试,采用Mock Object会有另外两项很重要的收益:

通过Mock Object能将一些分布式测试转化为本地的测试

将Mock用于压力测试,能解决测试集群无法演示线上集群大规模下的压力

mock控制技术的目的和作用是演示一些在应用中不容易构造或是比较复杂的对象,进而把测试与测试边界以外的对象隔离开。

Mock应用场景

在采用Mock的过程中,发现Mock是有一些通用性的,对于一些应用场景,是非常适合采用Mock的:

真实对象具有不可确定的行为(产生不可预测的结果,如股票的行情)

真实对象很难被创建(比如具体的web容器)

真实对象的某些行为很难触发(比如网络错误)

真实情况令程序的运行速度很慢

真实对象有用户界面

测试须要询问真实对象它是如何被调用的(比如测试可能须要验证某个回调函数是否被调用了)

真实对象实际上并不存在(当须要和其他合作开发小组,或是新的硬件系统打交道的时候,这是一个普遍的问题)

当然,也有一些不得不Mock的场景:

一些比较难构造的Object:这类Object通常有很多倚赖,在单元测试中构造出这种类通常花费的成本太大。

执行操作的时间较长Object:有一些Object的操作费时,而被测对象倚赖于这一个操作的执行结果,例如大文件写操作,数据的更新等等,出于测试的需求,通常将这类操作展开Mock。

异常逻辑:一些异常的逻辑往往在正常测试中是很难触发的,通过Mock能人为的控制触发异常逻辑。

在一些压力测试的场景下,也不得不采用Mock,例如在分布式系统测试中,通常须要测试一些单点(如namenode,jobtracker)在压力场景下的工作是否正常。而通常测试集群在正常逻辑下无法提供足够的压力(主要就原因是受限于机器数量),这时候就须要应用Mock去满足。

在那些场景下,他们应该如何去做Mock的工作了,一些现有的Mock辅助工具能帮助他们展开Mock工作。

EasyMock应用

Easymock官网:

http://easymock.org/

EasyMock 是早期比较流行的MocK测试框架。它提供对接口的演示,能够通过录制、回放、检查三步来完成大体的测试过程,能验证方法的调用种类、次数、顺序,能令 Mock 对象返回指定的值或抛出指定异常。通过 EasyMock,他们能方便的构造 Mock 对象进而使单元测试顺利展开。

EasyMock 是采用 MIT license 的一个开源工程项目

采用EasyMock大致能划分为以下几个步骤:

① 采用 EasyMock 生成 Mock 对象;

② 录制 Mock 对象的预期行为和输出;

③ 将 Mock 对象切换到 播放 状态;

④ 调用 Mock 对象方法展开单元测试;

⑤ 对 Mock 对象的行为展开验证。

mockito应用

mockito官网

https://code.google.com/p/mockito/

虽然官网路上不了,能到csdn上下载

http://download.csdn.net/download /wjjiang917/5519381

是EasyMock之后流行的mock辅助工具。相对EasyMock学习成本低,而且具有非常简洁的API,测试标识符的可读性很高。

采用mockito大致能划分为以下几个步骤:

① 采用 mockito 生成 Mock 对象;

② 定义(并非录制) Mock 对象的行为和输出(expectations部分);

③ 调用 Mock 对象方法展开单元测试;

④ 对 Mock 对象的行为展开验证。

PowerMock应用

PowerMock官网

https://code.google.com/p/powermock/

这个辅助工具是在EasyMock和Mockito上扩展出来的,目的是为了解决EasyMock和Mockito不能解决的问题,比如对static, final, private方法均不能mock。其实测试架构设计良好的标识符,一般并不需要那些功能,但如果是在已有工程项目上增加单元测试,老标识符有问题且不能改时,就不得不采用那些功能了。

PowerMock 在扩展功能时完全采用和被扩展的框架相同的API, 熟悉 PowerMock 所支持的模拟框架的合作开发者会发现 PowerMock 非常容易上手。PowerMock 的目的就是在当前已经被大家所熟悉的接口上通过添加极少的方法和注释来实现额外的功能。目前PowerMock 仅扩展了 EasyMock 和 mockito,须要和EasyMock或Mockito配合一起采用。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务