博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Gradle权威指南》--Android Gradle测试
阅读量:4948 次
发布时间:2019-06-11

本文共 8071 字,大约阅读时间需要 26 分钟。

No1:

Android既可以用传统的JUnit测试,也可以用Android的instrument测试。

No2:

当我们运行测试的时候,androidTest SourceSet会被构建成一个可以安装到设备上的测试apk,这个测试apk里有很多我们写好的测试用例,它们会被执行,来测试我们的app。

No3:

android{    defaultConfig{        testApplicationId "org.flysnow.app.example121.test"        testInstrumenttationRunner "android.test.InstrumentationTestRunner"        testHandleProfiling true        testFunctionalTest true    }}

testApplicationId--测试apk的包名

testFunctionTest--是否启用功能测试

testHandleProfiling--是否启用性能分析

testInstrumentationRunner--运行测试使用的Instrumentation Runner

-----------------------------------

最后根据配置生成AndroidManifest.xml文件

targetPackage会使用被测试App的包名自动填充

No4:

依赖

dependencies{    androidTestCompile 'com.android.support:support-annotation:23.0.1'    androidTestCompile 'com.android.support:test:runner:0.4.1'    androidTestCompile 'com.android.support.test:rules:0.4.1'}

会被编译到测试apk中,正式的apk包里没有这些jar库

No5:

测试apk默认是debug模式,但也可以改为release模式

android{    ...    testBuildType "release"}

No6:

运行测试代码:使用./gradlew connectedCheck运行。内部步骤是:

1)使用adnroidAndroidTest任务构建好测试应用和被测试应用,其中欧冠被测试应用又是被assembleDebug任务构建的

2)通过install任务安装这两个应用

3)运行我们写好的测试用例,等运行完之后,卸载两个应用

4)最后测试的结果会被保存在build/androidTest-results目录下

注:测试Application项目不会有被测试的apk生成,只有一个测试apk生成

No7:

本地单元测试--不依赖Android框架或者只有非常少的依赖,直接运行在本地开发机器上,不需要设备或模拟器

比较常用的模拟框架有Mockito和JMock

No8:

针对特定的BuildType和特定的Flavor测试。每一种BuildType,每一种Flavor都有对应的测试用例存放目录

比如:

src/main/java/对应的是src/test/java

src/debug/java/对应的是src/testDebug/java/

src/google/java/对应的是src/testGoogle/java/

No9:

JUnit3和JUnit4的区别:

JUnit的测试用例需要都集成junit.framework.TestCase,并且测试方法要以test为前缀。JUnit4就没有这些限制,测试方法也只需要使用@Test注解进行标注就好了

package org.flysnow.app.example122;import org.junit.Test;import static org.hamcrest.CoreMatchers.is;import static org.junit.Assert.assertThat;public class EmailValidatorTest{    @Test    public void emailValidator_CorrectEmailSimple_ReturnsTrue(){        assertThat(EmailValitor.isValidEmail("name@email.com"),is(true));    }    @Test    public void emailValidator_CorrectEmailSimple_ReturnsFalse(){        assertThat(EmailValidator.isValidEmail("name"),is(false));    }}

执行

./gradlew :example122:test

测试结果在build/reports/tests目录下

No10:

使用Mockito框架

dependencies{    testCompile 'junit:junit:4.12'    testCompile 'org.mockito:mockito-core:1.10.19'}
package org.flysnow.app.example122;import android.content.Context;public class Utils{    private Context mContext;        public Utils(Context context){        this.mContext = context;    }    public String getAppName(){        return String.valueOf(mContext.getString(R.string.app_name));    }}
package org.flysnow.app.example122;import android.content.Context;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.Mock;import org.mockito.runners.MockitoJUnitRunner;import static org.hamcrest.CoreMatchers.*;import static org.junit.Assert.*;import static org.mockito.Mockito.*;@RunWith(MockitoJUnitRunner.class)public class UtilsTest{    private static final String APP_NAME = "Example122";        @Mock    Context mMockContext;    @Test    public void readAppNameFromContext(){        when(mMockContext.getString(R.string.app_name)).thenReturn(APP_NAME);                Utils utils = new Utils(mMockContext);        String appName = utils.getAppName();        assertThat(appName,is(APP_NAME));    }}

1)告诉JUnit4要使用MockitlJUnitRunner

2)模拟Context的对象mMockContext

3)when.thenReturn逻辑,when一定要和Utils里的getAppName方法的逻辑一样,thenReturn告知模拟器期望返回的值

4)使用./gradlew :example 122:test执行查看结果

No11:

Instrument测试--运行在真实的安卓物理机或模拟器上。要生成一个测试apk。下面以AndroidJUnitRunner为例

android{    defaultConfig{        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        testApplicationId "con.example.app.test"    }}dependencies{    compile fileTree(dir: 'libs',include:['*.jar'])    androidTestCompile 'com.android.support.test:runner:0.4.1'    androidTestCompile 'com.android.support.test:rules:0.4.1'}
package org.flysnow.app.example123;import android.support.test.rule.ActivityTestRule;import android.support.test.runner.AndroidJUnit4;import android.test.suitebuilder.annotation.LargeTest;import org.junit.Before;import org.junit.Rule;import org.junit.Test;import org.junit.runner.RunWith;@RunWith(AndroidJUnit4.class)@LargeTestpublic class MainActivityTest{    @Rule    public ActivityTestRule
mActivityRule = new ActivityTestRule<>(MainActivity.class); @Before public void initSomethind(){} @Test public void validSomething(){ mActivityRule.getActivity().findViewById(android.R.id.test1).performClick(); }}

@LargeTest说明它有更高的权限

@Rule指定规则:要测试的是MainActivity

另外还有其他的库可以使用

dependencies{    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'}

No12:

测试选项配置testOptions闭包

android{    ...    testOptions{        reportDir = "$project.buildDir/example123/report"        resultsDir = "$project.buildDir/example123/result"        unitTests.all{            jvmArgs '-XX:MaxPermSize=256m'        }    }}

1)reportDir:用于配置生成测试报告的目录

2)resultsDir:用于配置生成测试结果的目录

3)unitTests:用于控制单元测试的执行--上面是指定启动的JVM的最大非堆内存是256M

---------------------------------------------

把每个库项目的测试报告统一合并查看:android-reporting

只需要在总的build.gradle中配置

apply plugin: 'android-reporting'

然后执行./gradlew deviceCheck mergeAndroidReports -continue

-continue是在测试失败的时候,也可以继续执行其他测试用例

No13:

代码覆盖率--testCoverageEnabled控制菜吗覆盖率统计是否开启

android{    buildTypes{        release{            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'            zipAlignEnabled true        }        debug{            testCoverageEnabled = true        }    }}

另外,要注意配置jacoco时的Android Gradle的版本号

1)如果是1.5.0之前的版本

android{    jacoco{        version = '0.6.2.201302030002'    }}

2)如果是1.5.0版本,在根项目的build.gradle里配置

buildscript{    repositories{        jcenter()    }    dependencies{        classpath 'org.jacoco:org.jacoco.core:0.7.4.201502262128'    }}

3)从2.0.0版本开始,不管在根项目,还是子项目都可以使用了

运行

./gradlew createDebugCoverageReport,报告在build/reports/coverage下

No14:

Lint支持--代码、资源的优化工具--lintOptions{}闭包

android{    lintOptions{        abortOnErroe true        warningsAsErrors true        check 'NewApi'    }}

abortOnError--boolean类型,用于配置Lint发现错误时是否退出Gradle构建

absolutPaths--boolean类型,用于配置错误的输出里是否应该显示绝对路径,默认显示的是相对路径

check--set集合

android{    lintOptions{        check 'NewApi'    }}

注:NewApi就是一个issue id,终端输入lint --list查看所有可用id,另外,lint --show可以查看详细信息

android{    lintOptions{        def checkSet = new HashSet
() checkSet.add("NewApi"); checkSet.add("InlinedApi") check = checkSet }}

缩写

android{    lintOptions{        check 'InlinedApi','NewApi'    }}

checkAllWarnings--boolean类型,True表示需要检查所有警告的issue,包括那些默认被关闭的issue,false不检查

checkReleaseBuilds--boolean类型,用于配置在release构建的过程中,Lint是否应该检查致命的错误的问题,默认true,一旦发现有‘fatal’级别的问题,release构建会被终止

disable--用来关闭给定issue id的Lint检查,和check用法一样

enable--用来配置哪些issue id启动lint check,和disable用法相反

explainIssues--boolean类型,用来配置Lint检查出的错误报告是否应该包含解释说明

htmlOutput--File类型,用于配置HTML报告输出的文件路径

android{    lintOptions{        htmlOutput new File("${buildDir}/lintReports/lint-results.html")    }}

htmlReport--boolean类型,用于配置是否生成HTML报告,默认是true

ignoreWarings--boolean类型,用于配置Lint是否忽略警告级别的检查,只检查错误级别

lintConfig--File类型,用于指定Lint的配置文件,

noLines--boolean类型,如果为true,error输出将不会包含源代码的行号

quiet--boolean类型,表示是否开启安静模式,这样Lint分析的进度或者其他信息将不会显示

severityOverrides--返回一个Map类型结果,用来获取issue的优先级。Map的key是issue id,value是优先级,包括fatal、error、warning、informational、ignore

showAll--boolean类型,用于标记是否应该显示所有的输出

textOutput--File类型,用于指定生成的test格式的报告的路径

textReport--boolean类型,用于配置是否生成text报告

warningsAdErrors--boolean类型,用于配置是否把所有的警告也当成错误处理,默认false

xmlOutput--File类型,用于设置生成xml报告的路径

xmlReport--boolean类型,用于控制是否生成xml格式的报告,默认true

error、fatal、ignore、warning、informational--用来配置issue的优先级,接受的都是issue id作为其参数。error是把给定的issue强制指定为erroe这个优先级

-------------------------

运行./gradlew lint,默认生成报告在output/lint-results.html下

转载于:https://www.cnblogs.com/anni-qianqian/p/8659825.html

你可能感兴趣的文章
iOS中的#import和class区别
查看>>
节约内存,请使用标签页管理工具:onetab、better onetab
查看>>
jQuery中的事件与动画
查看>>
页面加载骨架
查看>>
关于android系统不关屏设置
查看>>
SONY VPCS138EC降级安装XP
查看>>
[luogu4201][bzoj1063]设计路线【树形DP】
查看>>
手机抓包-手机劫持域名到指定服务器
查看>>
被放逐的皇后 金建云
查看>>
Javascript 有用参考函数
查看>>
点群的判别(三)
查看>>
GNSS 使用DFT算法 能量损耗仿真
查看>>
网页抓取 总结
查看>>
【vue】vue中v-charts的使用
查看>>
【转】Simulink模型架构指导
查看>>
MYSQL数据库的导出的几种方法
查看>>
SQL Server-5种常见的约束
查看>>
硬件之美
查看>>
[转载]java开发中的23种设计模式
查看>>
arm:启动代码判断是从nand启动还是从norflash启动,拷贝程序到内存的过程
查看>>