Jenkins构建Android项目持续集成之findbugs的使用

Findbugs简介

关于findbugs的介绍,可以自行百度下,这里贴下百度百科的介绍。findbugs是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。这组缺陷模式是可配置的,通过配置,可以过滤掉一些我们不想或不需要检测的问题。

findbugs在gradle中的配置

理论的部分就不多阐述了,我们直接来看看项目中怎么使用findbugs吧。
首先,在build.gradle引入findbugs插件

<code class="hljs bash">apply plugin: 'findbugs'</code>

然后,添加一个task

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code class = "hljs livecodeserver" >task findbugs(type: FindBugs,dependsOn: "connectedAndroidTest" ) { //
     ignoreFailures = true
     effort = "default"
     reportLevel = "medium"
     //这里填写项目classes目录
     classes = files( "${project.rootDir}/andbase-core/build/intermediates/classes" )
     source = fileTree( 'src/main/java' )
     classpath = files()
     reports {
         //只能开启一个
         xml.enabled = false
         html.enabled = true
     }
}</code>

注意:凡是task有依赖connectedAndroidTest的,都需要连接着模拟器或者真机,否则会报错

以下是我build.gradle的内容:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<code class = "hljs livecodeserver" >apply plugin: 'com.android.library'
//代码覆盖率插件
apply plugin: 'jacoco'
//findbugs
apply plugin: 'findbugs'
android {
     compileSdkVersion 22
     buildToolsVersion '22.0.1'
     defaultConfig {
         minSdkVersion 8
         targetSdkVersion 22
         versionCode 1
         versionName "1.0"
     }
     buildTypes {
         release {
             minifyEnabled true
             proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.pro'
         }
         debug{
             testCoverageEnabled true
         }
     }
     lintOptions {
         abortOnError false
     }
     packagingOptions {
         exclude 'META-INF/NOTICE'
         exclude 'META-INF/LICENSE'
     }
     jacoco{
         version "0.7.4.201502262128"
     }
}
 
task findbugs(type: FindBugs,dependsOn: "connectedAndroidTest" ) { //
     ignoreFailures = true
     effort = "default"
     reportLevel = "medium"
     //这里填写项目classes目录
     classes = files( "${project.rootDir}/andbase-core/build/intermediates/classes" )
     source = fileTree( 'src/main/java' )
     classpath = files()
     reports {
         //只能开启一个
         xml.enabled = false
         html.enabled = true
     }
}
 
task jacocoTestReport(type:JacocoReport){ //,dependsOn:"connectedAndroidTest"
     group = "Reporting"
     description = "Generate Jacoco coverage reports after running tests."
     reports{
         xml.enabled = false
         html.enabled = true
         csv.enabled = false
     }
     classDirectories = fileTree(
             dir : "$buildDir/intermediates/classes/debug" ,
             excludes : [
                     '**/*Test.class' ,
                     '**/R.class' ,
                     '**/R$*.class' ,
                     '**/BuildConfig.*' ,
                     '**/Manifest*.*'
             ]
     )
     def coverageSourceDirs = [ 'src/main/java' ]
     additionalSourceDirs = files(coverageSourceDirs)
     sourceDirectories = files(coverageSourceDirs)
     additionalClassDirs = files(coverageSourceDirs)
     executionData = files( "$buildDir/outputs/code-coverage/connected/coverage.ec" )
}
 
dependencies {
     compile fileTree(dir: 'libs' , include: [ '*.jar' ])
     compile 'com.android.support:appcompat-v7:22.2.1'
}</code>

然后在Terminal输入命令

?
1
<code class = "hljs " >gradlew findbugs</code>

执行成功之后,会在项目根目录下build\reports\findbugs生成findbugs.html文件,打开就是查虫结果

findbugs报告

这里可以看到总体的一些警告情况。

但是当你往下查看具体的某些问题时,会发现一些R$anim 之类的

详细报告

而在Android中,R文件是自动生成,我们查虫是不需要检查该文件的。这时候过滤配置就派上用场了。

findgbugs过滤器配置

在项目根目录下新建一个findbug_filter.xml文件,内容如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<code class = " hljs xml" ><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D% 221.0 % 22 %20encoding%3D%22UTF- 8 % 22 %3F%2D%2D%3E-->
<findbugsfilter>
     <match>
         <!--{cke_protected}{C}%3C!%2D%2D%20ignore%20all%20issues%20in%20resource%20generation% 20 %2D%2D%3E-->
         < class name= "~.*\.R\$.*" >
     </ class ></match>
 
     <match>
         < class name= "~.*\.Manifest\$.*" >
     </ class ></match>
 
     <match>
         < class name= "~.*\.*Test" >
         <!--{cke_protected}{C}%3C!%2D%2D%20test%20classes%20are%20suffixed%20by% 20 'Test' % 20 %2D%2D%3E-->
         <not>
             <bug code= "IJU" > <!--{cke_protected}{C}%3C!%2D%2D% 20 'IJU' %20is%20the%20code%20for%20bugs%20related%20to%20JUnit%20test%20code% 20 %2D%2D%3E-->
         </bug></not>
     </ class ></match>
</findbugsfilter></code>

上面match到的是要过滤掉,而不是要捕捉的,所以我们过滤掉了R文件、manifest文件和测试用例类。
相应的,我们需要修改gradle配置,让过滤器生效,在task findbugs 配置如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<code class = "hljs livecodeserver" >task findbugs(type: FindBugs,dependsOn: "connectedAndroidTest" ) { //
     ignoreFailures = true
     effort = "default"
     reportLevel = "medium"
     //过滤器
     excludeFilter = new File( "${project.rootDir}/findbug_filter.xml" )
     //这里填写项目classes目录
     classes = files( "${project.rootDir}/andbase-core/build/intermediates/classes" )
     source = fileTree( 'src/main/java' )
     classpath = files()
     reports {
         //只能开启一个
         xml.enabled = false
         html.enabled = true
     }
}</code>

然后在Teminal再执行gradlew findbugs,重新查看报告,之前的那些关于‘R$’的警告都没有了,说明过滤器生效了。
再者,我们可能有这样的需求,可能每个人的查看报告的侧重点不同,所以想,报告是否可以更个性化一些。同样的,我们可以根据过滤器实现。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<code class = " hljs xml" ><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D% 221.0 % 22 %20encoding%3D%22UTF- 8 % 22 %3F%2D%2D%3E-->
<findbugsfilter>
     <match>
         <!--{cke_protected}{C}%3C!%2D%2D%20ignore%20all%20issues%20in%20resource%20generation% 20 %2D%2D%3E-->
         < class name= "~.*\.R\$.*" >
     </ class ></match>
 
     <match>
         < class name= "~.*\.Manifest\$.*" >
     </ class ></match>
 
     <match>
         < class name= "~.*\.*Test" >
         <!--{cke_protected}{C}%3C!%2D%2D%20test%20classes%20are%20suffixed%20by% 20 'Test' % 20 %2D%2D%3E-->
         <not>
             <bug code= "IJU" > <!--{cke_protected}{C}%3C!%2D%2D% 20 'IJU' %20is%20the%20code%20for%20bugs%20related%20to%20JUnit%20test%20code% 20 %2D%2D%3E-->
         </bug></not>
     </ class ></match>
     <!--{cke_protected}{C}%3C!%2D%2D%E8%BF% 87 %E6%BB%A4%E6%8E% 89 %E4%B8% 80 %E4%BA%9Bbug%2D%2D%3E-->
     <match>
         <!--{cke_protected}{C}%3C!%2D%2D1%E3% 80 % 81 %E6% 80 %A7%E8% 83 %BD%E9% 97 %AE%E9%A2% 98 %2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D%3CBug%20category%3D%22PERFORMANCE% 22 % 20 %2F%3E%2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D2%E3% 80 % 81 %E4%B8% 80 %E8% 88 %AC%E6%AD%A3%E7%A1%AE%E6% 80 %A7%E9% 97 %AE%E9%A2% 98 %2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D%3CBug%20category%3D%22CORRECTNESS% 22 % 20 %2F%3E%2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D3%E3% 80 % 81 %E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%AD%A3%E7%A1%AE%E6% 80 %A7%E9% 97 %AE%E9%A2% 98 %2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D%3CBug%20category%3D%22MT_CORRECTNESS% 22 % 20 %2F%3E%2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D4%E3% 80 % 81 %E6% 81 %B6%E6% 84 %8F%E4%BB%A3%E7%A0% 81 %EF%BC%8C%E6%9C% 89 %E5%8F%AF%E8% 83 %BD%E6% 88 % 90 %E4%B8%BA%E6% 94 %BB%E5% 87 %BB%E7% 82 %B9%2D%2D%3E-->
         <!--{cke_protected}{C}%3C!%2D%2D%3CBug%20category%3D%22MALICIOUS_CODE% 22 % 20 %2F%3E%2D%2D%3E-->
 
         <or>
             <!--{cke_protected}{C}%3C!%2D%2DField%20names%20should%20start%20with%20a%20lower%20case%20letter%2D%2D%3E-->
             <bugcode name= "Nm" >
             <!--{cke_protected}{C}%3C!%2D%2DMethod%20ignores%20exceptional%20return%20value%20or%20Return%20value%20of%20method%20without%20side%20effect%20is%20ignored%2D%2D%3E-->
             <bugcode name= "RV" >
             <!--{cke_protected}{C}%3C!%2D%2D%E5%9B%BD%E9% 99 % 85 %E5%8C% 96 %2D%2D%3E-->
             <bugcode name= "Dm" >
         </bugcode></bugcode></bugcode></or>
     </match>
</findbugsfilter></code>

其中,

?
1
<code class = "hljs xml" ><bug category= "MT_CORRECTNESS" ></bug></code>

是以一大类bug相关的来设置过滤器的,category的值有哪些呢?有PERFORMANCE(性能问题)、CORRECTNESS(一般正确性问题)、MT_CORRECTNESS(多线程正确性问题)、MALICIOUS_CODE(恶意代码),这四大类。

?
1
<code class = "hljs xml" ><bugcode name= "Dm" ></bugcode></code>

而BugCode是category类下的细分,而它们的name值有哪些呢,这里可以从报告中查看得知:

BugCode

上图是Performance Category,Code列就是BugCode name的可选值。
通过过滤器的配置,我们可以个性化的定制报告了。

Jenkins配置findbugs

增加构建后操作步骤

构建后步骤

findbugs配置

看说明,该路径配置是获取xml文件的,但是,之前我们获取到的是html文件,怎么办?所以,这里我们要修改一下gradle配置。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<code class = "hljs livecodeserver" >task findbugs(type: FindBugs,dependsOn: "connectedAndroidTest" ) { //
     ignoreFailures = true
     effort = "default"
     reportLevel = "medium"
     //过滤器
     excludeFilter = new File( "${project.rootDir}/findbug_filter.xml" )
     //这里填写项目classes目录
     classes = files( "${project.rootDir}/andbase-core/build/intermediates/classes" )
     source = fileTree( 'src/main/java' )
     classpath = files()
     reports {
         //只能开启一个
         xml.enabled = true
         html.enabled = false
     }
}</code>

我们将xml.enabled设置为true,html.enabled设置为false。
然后,构建命令也要添加findbugs

构建命令

邮箱也相应添加findbugs报告

邮箱配置findbugs

保存配置,立即构建。如果运行正常的话,可以看到如下的报告

jenkins报告

你也可以从邮箱内容打开链接查看报告

邮箱链接

总结

至此,本系列也差不多讲完了。这套持续集成是我们公司正在用的,所以实用性还是蛮高的,用起来有很多好处,不管是对开发、测试都有很大的便利性,大大的提高了项目的质量和可控性。往大的说,它也为敏捷开发提供了可行性基础。第一次写这样的系列,有什么错的或者建议,希望能看到你的提出。

看下其他文章:
1、Jenkins构建Android项目持续集成之简介篇
2、Jenkins构建Android项目持续集成之Jenkins的安装篇
3、Jenkins构建Android项目持续集成之系统配置篇
4、Jenkins构建Android项目持续集成之创建项目
5、Jenkins构建Android项目持续集成之单元测试及代码覆盖率
6、Jenkins构建Android项目持续集成之findbugs的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值