鍍金池/ 教程/ Android/ 測試 - Testing
依賴(lài)關(guān)系,Android 庫和多項目設置 - Dependencies,Android Libraries and Multi-
要求 - Requirements
構建變種版本 - Build Variants
高級構建定制 - Advanced Build Customization
測試 - Testing
基本項目 - Basic Project
簡(jiǎn)介 - Introduction

測試 - Testing

構建一個(gè)測試程序已經(jīng)被集成到應用項目中,沒(méi)有必要再專(zhuān)門(mén)建立一個(gè)測試項目。

單元測試

單元測試的支持被試驗性地添加到 1.1 版本中,請看 這頁(yè)。本章節剩余部分描述了可以在真機(或模擬器)上運行的 “instrumentation tests”,以及需要構建的獨立、測試性的 APK。

基本知識和配置

正如前面所提到的,緊鄰main _sourceSet_的就是androidTest sourceSet,默認路徑在src/androidTest/下。 在這個(gè)測試_sourceSet_中會(huì )構建一個(gè)使用Android測試框架,并且可以部署到設備上的測試apk來(lái)測試應用程序。這里面包含單元測試,集成測試,和后續UI自動(dòng)化測試。 這個(gè)測試sourceSet不應該包含AndroidManifest.xml文件,因為這個(gè)文件會(huì )自動(dòng)生成。

下面這些值可能會(huì )在測試應用配置中使用到:

  • testPackageName
  • testInstrumentationRunner
  • testHandleProfiling
  • testfunctionalTest

正如前面所看到的,這些配置在defaultConfig對象中配置:

    android {
        defaultConfig {
            testPackageName "com.test.foo"
            testInstrumentationRunner "android.test.InstrumentationTestRunner"
            testHandleProfiling true
            testFunctionalTest true
        }
    }

在測試應用程序的manifest文件中,instrumentation節點(diǎn)的targetPackage屬性值會(huì )自動(dòng)使用測試應用的package名稱(chēng)設置,即使這個(gè)名稱(chēng)是通過(guò)defaultConfig或者_Build Type_對象自定義的。這也是manifest文件需要自動(dòng)生成的一個(gè)原因。

另外,這個(gè)測試_sourceSet_也可以擁有自己的依賴(lài)。 默認情況下,應用程序和他的依賴(lài)會(huì )自動(dòng)添加的測試應用的classpath中,但是也可以通過(guò)以下來(lái)擴展:

    dependencies {
        androidTestCompile 'com.google.guava:guava:11.0.2'
    }

測試應用通過(guò)assembleTest task來(lái)構建。assembleTest不依賴(lài)于main中的assemble task,需要手動(dòng)設置運行,不能自動(dòng)運行。

目前只有一個(gè)_Build Type_被測試。默認情況下是debug Build Type,但是這也可以通過(guò)以下自定義配置:

    android {
        ...
        testBuildType "staging"
    }

運行測試

正如前面提到的,標志性task connectedCheck要求一個(gè)連接的設備來(lái)啟動(dòng)。 這個(gè)過(guò)程依賴(lài)于androidTest task,因此將會(huì )運行androidTest。這個(gè)task將會(huì )執行下面內容:

  • 確認應用和測試應用都被構建(依賴(lài)于assembleDebugassembleTest)。
  • 安裝這兩個(gè)應用。
  • 運行這些測試。
  • 卸載這兩個(gè)應用。

如果有多于一個(gè)連接設備,那么所有測試都會(huì )同時(shí)運行在所有連接設備上。如果其中一個(gè)測試失敗,不管是哪一個(gè)設備算失敗。

所有測試結果都被保存為XML文檔,路徑為:

    _build/androidTest-results_

(這類(lèi)似于JUnit的運行結果保存在build/test-results)

同樣,這也可以自定義配置:

    android {
        ...

        testOptions {
            resultsDir = "$project.buildDir/foo/results"
        }
    }

這里的android.testOptions.resultsDir將由Project.file(String)獲得。

測試 Android 庫

測試Android庫項目的方法與應用項目的方法類(lèi)似。

唯一的不同在于整個(gè)庫(包括它的依賴(lài))都是自動(dòng)作為依賴(lài)庫被添加到測試應用中。結果就是測試APK不單只包含它的代碼,還包含了庫項目自己和庫的所有依賴(lài)。 庫的manifest被組合到測試應用的manifest中(作為一些項目引用這個(gè)庫的殼)。

androidTest task的變改只是安裝(或者卸載)測試APK(因為沒(méi)有其它APK被安裝)。

其它的部分都是類(lèi)似的。

測試報告

當運行單元測試的時(shí)候,Gradle會(huì )輸出一份HTML格式的報告以方便查看結果。 Android plugin也是基于此,并且擴展了HTML報告文件,它將所有連接設備的報告都合并到一個(gè)文件里面。

獨立項目

一個(gè)項目將會(huì )自動(dòng)生成測試運行。默認位置為:build/reports/androidTests

這非常類(lèi)似于JUnit的報告所在位置build/reports/tests,其它的報告通常位于build/reports/< plugin >/。

這個(gè)路徑也可以通過(guò)以下方式自定義:

    android {
        ...

        testOptions {
            reportDir = "$project.buildDir/foo/report"
        }
    }

報告將會(huì )合并運行在不同設備上的測試結果。

多項目報告

在一個(gè)配置了多個(gè)應用或者多個(gè)庫項目的多項目里,當同時(shí)運行所有測試的時(shí)候,生成一個(gè)報告文件記錄所有的測試可能是非常有用的。

為了實(shí)現這個(gè)目的,需要使用同一個(gè)依賴(lài)文件(譯注:指的是使用android gradle插件的依賴(lài)文件)中的另一個(gè)插件??梢酝ㄟ^(guò)以下方式添加:

    buildscript {
        repositories {
            mavenCentral()
        }

        dependencies {
            classpath 'com.android.tools.build:gradle:0.5.6'
        }
    }

    apply plugin: 'android-reporting'

這必須添加到項目的根目錄下,例如與settings.gradle文件同個(gè)目錄的build.gradle文件中。

之后,在命令行中導航到項目根目錄下,輸入以下命令就可以運行所有測試并合并所有報告:

    gradle deviceCheck mergeAndroidReports --continue

注意:
這里的--continue選項將允許所有測試,即使子項目中的任何一個(gè)運行失敗都不會(huì )停止。如果沒(méi)有這個(gè)選項,第一個(gè)失敗測試將會(huì )終止全部測試的運行,這可能導致一些項目沒(méi)有執行過(guò)它們的測試。

Lint 支持

Lint支持,譯者注:Lint是一個(gè)可以檢查Android項目中存在的問(wèn)題的工具

從0.7.0版本開(kāi)始,你可以為項目中一個(gè)特定的Variant(變種)版本運行lint,也可以為所有Variant版本都運行lint。它將會(huì )生成一個(gè)報告描述哪一個(gè)Variant版本中存在著(zhù)問(wèn)題。

你可以通過(guò)以下lint選項配置lint。通常情況下你只需要配置其中一部分,以下列出了所有可使用的選項:

    android {
        lintOptions {
            // set to true to turn off analysis progress reporting by lint
            quiet true
            // if true, stop the gradle build if errors are found
            abortOnError false
            // if true, only report errors
            ignoreWarnings true
            // if true, emit full/absolute paths to files with errors (true by default)
            //absolutePaths true
            // if true, check all issues, including those that are off by default
            checkAllWarnings true
            // if true, treat all warnings as errors
            warningsAsErrors true
            // turn off checking the given issue id's
            disable 'TypographyFractions','TypographyQuotes'
            // turn on the given issue id's
            enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
            // check *only* the given issue id's
            check 'NewApi', 'InlinedApi'
            // if true, don't include source code lines in the error output
            noLines true
            // if true, show all locations for an error, do not truncate lists, etc.
            showAll true
            // Fallback lint configuration (default severities, etc.)
            lintConfig file("default-lint.xml")
            // if true, generate a text report of issues (false by default)
            textReport true
            // location to write the output; can be a file or 'stdout'
            textOutput 'stdout'
            // if true, generate an XML report for use by for example Jenkins
            xmlReport false
            // file to write report to (if not specified, defaults to lint-results.xml)
            xmlOutput file("lint-report.xml")
            // if true, generate an HTML report (with issue explanations, sourcecode, etc)
            htmlReport true
            // optional path to report (default will be lint-results.html in the builddir)
            htmlOutput file("lint-report.html")

       // set to true to have all release builds run lint on issues with severity=fatal
       // and abort the build (controlled by abortOnError above) if fatal issues are found
       checkReleaseBuilds true
            // Set the severity of the given issues to fatal (which means they will be
            // checked during release builds (even if the lint target is not included)
            fatal 'NewApi', 'InlineApi'
            // Set the severity of the given issues to error
            error 'Wakelock', 'TextViewEdits'
            // Set the severity of the given issues to warning
            warning 'ResourceAsColor'
            // Set the severity of the given issues to ignore (same as disabling the check)
            ignore 'TypographyQuotes'
        }
    }