Android单元和instrumentation单元测试

Developing Android unit and instrumentation tests


Android的单元测试是基于JUnit的。可分为:

  • 1、本地单元测试 - 可以在JVM上运行测试(速度快,优先考虑)。
  • 2、Instrumented单元测试 - 需要Android系统

Android的Gradle插件支持在JVM上执行Andr​​oid单元测试。它使用特殊版本的android.jar(也称为 Android mockable jar)支持单元测试,使所有字段,方法和类可用。任何调用到Android mockable JAR默认都是异常。快速但是不能测试安卓相关内容。Instrumented可测试Android API。

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第1张图片

工程结构和测试文件夹

建议:

    app/src/main/java - 源代码

    app/src/test/java - 本地测试

    app/src/androidTest/java - Instrumented单元测试

 如果你这些约定,Android构建系统会自动在JVM上运行单元测试、在Android设备上运行安卓测试。  当然你额也可以不按照找个建立,自己拟定目录。

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第2张图片




 1、JVM单元测试( unit test

Android使用unit test这个术语描述本地JVM而非Android Runtime上运行的测试。

unit test测试组件功能。例如假设Android activity的一个按钮用于启动另一个activity。单元测试确定是否发出相应的intent,但部保证另一个activity已启动。

unit test依靠修改后的android.jar执行,这个jar文件中所有的final修饰符都被去掉。修改后允许使用mock库,如Mockito。默认这个android.jar中的所有方法抛出异常。这种缺省行为保证单元测试只会测试自己代码,不会依赖Android平台的任何特定行为。如果想使用Android平台的特定行为,可以使用mock框架替换相应调用。

单元测试约定的位置:app/src/test/目录,并需要添加相应配置到Gradle构建文件中:

dependencies {    // Unit testing dependencies    testCompile 'junit:junit:4.12'    // Set this dependency if you want to use the Hamcrest matcher library    testCompile 'org.hamcrest:hamcrest-library:1.3'    // more stuff, e.g., Mockito} 

1.1 运行方法

1、可在对应test文件上右键选择  直接运行   注意此处么没有用虚拟机即可测试方法

2、在顶部的 run工具处左侧 自定义+UnitTest

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第3张图片


测试报告在app/build/reports/tests/debug/目录。index.html是测试概述,它链接到单个测试页。

也可以配置Gradle构建系统,让android.jar中的方法均返回缺省值而不是抛出异常:

android {  // ...  testOptions {     unitTests.returnDefaultValues = true  }} 


1.2 创建步骤

1.2.1  app/build.gradle中添加JUnit依赖【似乎有时候不需要】

在 app/build.gradle中添加JUnit依赖。“testCompile 'junit:junit:4.12'” 与 "compile 'junit:junit:4.12'"

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.1.0'    compile 'junit:junit:4.12'}

1.2.2 为某个类创建Test(使用IDE自动生成test模板)或者自己手工编写

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第4张图片

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第5张图片

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第6张图片


1.2.3 编辑生成的模板 

生成的文件ConverterUtilTest.java如下:

package com.vogella.android.temperatureconverter;import junit.framework.TestCase;import org.junit.Test;import static org.junit.Assert.*;/** * Created by andrew on 15-11-8. */public class ConverterUtilTest extends TestCase {    @Test    public void testConvertFahrenheitToCelsius() throws Exception {    }    @Test    public void testConvertCelsiusToFahrenheit() throws Exception {    }}

 

修改文件ConverterUtilTest.java:

package com.vogella.android.temperatureconverter;import static org.junit.Assert.*;import org.junit.Test;public class ConverterUtilTest {    @Test    public void testConvertFahrenheitToCelsius() {        float actual = ConverterUtil.convertCelsiusToFahrenheit(100);        // expected value is 212        float expected = 212;        // use this method because float is not precise        assertEquals("Conversion from celsius to fahrenheit failed", expected,                actual, 0.001);    }    @Test    public void testConvertCelsiusToFahrenheit() {        float actual = ConverterUtil.convertFahrenheitToCelsius(212);        // expected value is 100        float expected = 100;        // use this method because float is not precise        assertEquals("Conversion from celsius to fahrenheit failed", expected,                actual, 0.001);    }}




 2、 Instrumentation - 底层的Andr​​oid测试API

Android的测试API提供钩子到Android的组件和应用生命周期。这些钩子即instrumentation API,它允许你的测试控制的生命周期和用户交互事件。

在正常情况下应用只反应生命周期和用户交互事件。例如Android的创建activity会调用onCreate()方法被调用您的活动。或用户按按钮或一个密钥和相应的代码被调用。通过instrumentation API这些事件。

InstrumentationTestRunner是Android测试的基础。它启动并加载测试方法。它通过instrumentation API与Android系统进行通信。如果你开始Android应用测试,Android系统杀死被测应用,然后加载一个新的实例。它不启动应用程序,这是的测试方法的责任。测试方法控制的应用组件的生命周期。TestRunner初始化时调用应用和在正常情况下应用只反应生命周期和用户交互事件。例如Android的创建activity会调用onCreate的onCreate()方法 和活动的onCreate()方法。

一般是调用Espresso,很少直接使用 instrumentation API。


依赖配置:

defaultConfig {       ..... more stuff        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }dependencies {    // Unit testing dependencies    androidTestCompile 'junit:junit:4.12'    // Set this dependency if you want to use the Hamcrest matcher library    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'    // more stuff, e.g., Mockito} 

建议测试添加注解@RunWith(AndroidJUnit4.class)。 AndroidJUnit4扩展JUnit4,纯Junit4语法和ActivityTestRule不是必需的。但是Espresso测试混合ActivityTestRule需要。gradle的执行方式“gradlew connectedCheck"。Android Studio的Build Variants窗口的设置如下:

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试_第7张图片

要运行单元测试,应保证选择的是”Android Instrumentation Tests”,右击待测试的类然后选择”Run”。测试报告输出到 app/build/reports/androidTests/connected/,index.html是测试概述,它链接到单个测试页。

添加mockito支持:

dependencies {    testCompile 'junit:junit:4.12'    // required if you want to use Mockito for unit tests    testCompile 'org.mockito:mockito-core:1.+'    // required if you want to use Mockito for Android instrumentation tests    androidTestCompile 'org.mockito:mockito-core:1.+'    androidTestCompile "com.google.dexmaker:dexmaker:1.2"    androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"} 


2.1、测试代码

我在这个test文件夹中添加了一个类EexampleTest,该类派生自InstrumentationTestCase,并写了一个方法,完整代码如下:

[java]  view plain  copy  
  1. public class ExampleTest extends InstrumentationTestCase {  
  2.   
  3.         public void test() throws Exception {  
  4.             final int expected = 1;  
  5.             final int reality = 1;  
  6.             assertEquals(expected, reality);  
  7.         }  
  8. }  
注意:在android studio中,所有的测试代码必须以test-作为前缀,不然android studio无法识别它为测试代码。

2.2、测试

在android studio一排按钮的最上层,点击“运行”旁边的配置按钮


打开配置对话框,选择Android Test


右侧Module选择你的工程名,这里是app

Test: 部分选择All in Package

Package:选择当前新建的test文件夹


整体配置好之后是这样的


运行出结果:

测试通过的结果是这样子的:


如果我们把test()的代码改成这样子:

[java]  view plain  copy  
  1. public void test() throws Exception {  
  2.     final int expected = 1;  
  3.     final int reality = 3;  
  4.     assertEquals(expected, reality);  
  5. }  
明显1不等于3,所以assertEquals肯定会出错!
所以出错的结果是这样子的:(在中间窗口logcat中可以定位到出错位置)





 JVM单元测试

更多相关文章

  1. Android应用程序永久获取root权限方法
  2. Android4.0和Android4.1全屏方法
  3. Android SDK更新失败的解决方法
  4. Android自动化测试框架—Robotium 4.3介绍
  5. 关于 android 输入法 adjustPan无效的解决方法
  6. Android实现EditText控件禁止输入内容的方法(附测试demo)
  7. Android RetainFragment状态保存的方法
  8. Android Volley框架使用方法详解

随机推荐

  1. Android布局管理器介绍
  2. Android(安卓)自己收集的开源项目和文章
  3. android jni方法模拟高频按键点击
  4. Android面试题(四)——动画
  5. android setTag的妙用和The key must be
  6. Android(安卓)Camera数据流分析全程记录(o
  7. Material Design: NavigationView Flaotin
  8. Android(安卓)Studio工程导入,仅需三步便
  9. EventBus在Android中的简单使用
  10. 转:android:Adapter用法总结