題外話
這篇本來和之前的系列要一起出的,但是因爲中間公司要發佈一個版本,給耽擱了,今天工作做完了,又閒了下來。所以就又來繼續jenkins構建Android項目持續集成系列的findbugs篇。
Findbugs簡介
關於findbugs的介紹,可以自行百度下,這裏貼下百度百科的介紹。findbugs是一個靜態分析工具,它檢查類或者 JAR 文件,將字節碼與一組缺陷模式進行對比以發現可能的問題。這組缺陷模式是可配置的,通過配置,可以過濾掉一些我們不想或不需要檢測的問題。
findbugs在gradle中的配置
理論的部分就不多闡述了,我們直接來看看項目中怎麼使用findbugs吧。
首先,在build.gradle引入findbugs插件
apply plugin: 'findbugs'
然後,添加一個task
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有依賴connectedAndroidTest的,都需要連接着模擬器或者真機,否則會報錯
以下是我build.gradle的內容:
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'
}
然後在Terminal輸入命令
gradlew findbugs
執行成功之後,會在項目根目錄下build\reports\findbugs生成findbugs.html文件,打開就是查蟲結果
這裏可以看到總體的一些警告情況。
但是當你往下查看具體的某些問題時,會發現一些R$anim 之類的
而在Android中,R文件是自動生成,我們查蟲是不需要檢查該文件的。這時候過濾配置就派上用場了。
findgbugs過濾器配置
在項目根目錄下新建一個findbug_filter.xml文件,內容如下
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<!-- ignore all issues in resource generation -->
<Class name="~.*\.R\$.*"/>
</Match>
<Match>
<Class name="~.*\.Manifest\$.*"/>
</Match>
<Match>
<Class name="~.*\.*Test" />
<!-- test classes are suffixed by 'Test' -->
<Not>
<Bug code="IJU" /> <!-- 'IJU' is the code for bugs related to JUnit test code -->
</Not>
</Match>
</FindBugsFilter>
上面match到的是要過濾掉,而不是要捕捉的,所以我們過濾掉了R文件、manifest文件和測試用例類。
相應的,我們需要修改gradle配置,讓過濾器生效,在task findbugs 配置如下:
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
}
}
然後在Teminal再執行gradlew findbugs,重新查看報告,之前的那些關於‘R$’的警告都沒有了,說明過濾器生效了。
再者,我們可能有這樣的需求,可能每個人的查看報告的側重點不同,所以想,報告是否可以更個性化一些。同樣的,我們可以根據過濾器實現。
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<!-- ignore all issues in resource generation -->
<Class name="~.*\.R\$.*"/>
</Match>
<Match>
<Class name="~.*\.Manifest\$.*"/>
</Match>
<Match>
<Class name="~.*\.*Test" />
<!-- test classes are suffixed by 'Test' -->
<Not>
<Bug code="IJU" /> <!-- 'IJU' is the code for bugs related to JUnit test code -->
</Not>
</Match>
<!--過濾掉一些bug-->
<Match>
<!--1、性能問題-->
<!--<Bug category="PERFORMANCE" />-->
<!--2、一般正確性問題-->
<!--<Bug category="CORRECTNESS" />-->
<!--3、多線程正確性問題-->
<!--<Bug category="MT_CORRECTNESS" />-->
<!--4、惡意代碼,有可能成爲攻擊點-->
<!--<Bug category="MALICIOUS_CODE" />-->
<Or>
<!--Field names should start with a lower case letter-->
<BugCode name="Nm"/>
<!--Method ignores exceptional return value or Return value of method without side effect is ignored-->
<BugCode name="RV"/>
<!--國際化-->
<BugCode name="Dm"/>
</Or>
</Match>
</FindBugsFilter>
其中,
<Bug category="MT_CORRECTNESS" />
是以一大類bug相關的來設置過濾器的,category的值有哪些呢?有PERFORMANCE(性能問題)、CORRECTNESS(一般正確性問題)、MT_CORRECTNESS(多線程正確性問題)、MALICIOUS_CODE(惡意代碼),這四大類。
<BugCode name="Dm"/>
而BugCode是category類下的細分,而它們的name值有哪些呢,這裏可以從報告中查看得知:
上圖是Performance Category,Code列就是BugCode name的可選值。
通過過濾器的配置,我們可以個性化的定製報告了。
Jenkins配置findbugs
增加構建後操作步驟
看說明,該路徑配置是獲取xml文件的,但是,之前我們獲取到的是html文件,怎麼辦?所以,這裏我們要修改一下gradle配置。
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
}
}
我們將xml.enabled設置爲true,html.enabled設置爲false。
然後,構建命令也要添加findbugs
郵箱也相應添加findbugs報告
保存配置,立即構建。如果運行正常的話,可以看到如下的報告
你也可以從郵箱內容打開鏈接查看報告
總結
至此,本系列也差不多講完了。這套持續集成是我們公司正在用的,所以實用性還是蠻高的,用起來有很多好處,不管是對開發、測試都有很大的便利性,大大的提高了項目的質量和可控性。往大的說,它也爲敏捷開發提供了可行性基礎。第一次寫這樣的系列,有什麼錯的或者建議,希望能看到你的提出。
看下其他文章:
1、Jenkins構建Android項目持續集成之簡介篇
2、Jenkins構建Android項目持續集成之Jenkins的安裝篇
3、Jenkins構建Android項目持續集成之系統配置篇
4、Jenkins構建Android項目持續集成之創建項目
5、Jenkins構建Android項目持續集成之單元測試及代碼覆蓋率
6、Jenkins構建Android項目持續集成之findbugs的使用