Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Jenkins構建Android項目持續集成之findbugs的使用

Jenkins構建Android項目持續集成之findbugs的使用

編輯:關於Android編程

題外話

這篇本來和之前的系列要一起出的,但是因為中間公司要發布一個版本,給耽擱了,今天工作做完了,又閒了下來。所以就又來繼續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文件,打開就是查蟲結果

findbugs報告

這裡可以看到總體的一些警告情況。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPrWryse1scTjzfnPwrLpv7S+38zltcTEs9CpzsrM4sqxo6y74beiz9bSu9CpUiRhbmltINauwOC1xDwvcD4NCjxwPjxpbWcgYWx0PQ=="詳細報告" src="/uploadfile/Collfiles/20151230/2015123009195482.png" title="\" />

而在Android中,R文件是自動生成,我們查蟲是不需要檢查該文件的。這時候過濾配置就派上用場了。

findgbugs過濾器配置

在項目根目錄下新建一個findbug_filter.xml文件,內容如下

<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 配置如下:

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$’的警告都沒有了,說明過濾器生效了。
再者,我們可能有這樣的需求,可能每個人的查看報告的側重點不同,所以想,報告是否可以更個性化一些。同樣的,我們可以根據過濾器實現。

<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>

其中,

是以一大類bug相關的來設置過濾器的,category的值有哪些呢?有PERFORMANCE(性能問題)、CORRECTNESS(一般正確性問題)、MT_CORRECTNESS(多線程正確性問題)、MALICIOUS_CODE(惡意代碼),這四大類。

而BugCode是category類下的細分,而它們的name值有哪些呢,這裡可以從報告中查看得知:

BugCode

上圖是Performance Category,Code列就是BugCode name的可選值。
通過過濾器的配置,我們可以個性化的定制報告了。

Jenkins配置findbugs

增加構建後操作步驟

構建後步驟

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報告

郵箱配置findbugs

保存配置,立即構建。如果運行正常的話,可以看到如下的報告

jenkins報告

你也可以從郵箱內容打開鏈接查看報告

郵箱鏈接

總結

至此,本系列也差不多講完了。這套持續集成是我們公司正在用的,所以實用性還是蠻高的,用起來有很多好處,不管是對開發、測試都有很大的便利性,大大的提高了項目的質量和可控性。往大的說,它也為敏捷開發提供了可行性基礎。第一次寫這樣的系列,有什麼錯的或者建議,希望能看到你的提出。

看下其他文章:
1、Jenkins構建Android項目持續集成之簡介篇
2、Jenkins構建Android項目持續集成之Jenkins的安裝篇
3、Jenkins構建Android項目持續集成之系統配置篇
4、Jenkins構建Android項目持續集成之創建項目
5、Jenkins構建Android項目持續集成之單元測試及代碼覆蓋率
6、Jenkins構建Android項目持續集成之findbugs的使用

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved