Android:单元测试

前言

对于Android的单元测试一直有些弄不明白,虽然要进行单元测试并不复杂,但是其中的关系好像有点复杂,包括怎样在Eclipse进行单元测试,又怎样在Android Studio进行单元测试,怎样进行Local的测试而不需要运行真机或虚拟机,各种TestCase有什么不同,为什么Junit4好像很难work的样子…等等问题,我试着一一弄明白这些问题。这篇文章不涉及UI测试。


简介

单元测试是app的基础测试,为你的代码编写单元测试,可以很容易地验证程序的某个单元是否正确。当你改动代码之后,如果程序发生了错误,单元测试则可以帮助你快速发现这些错误。
单元测试以一种可重复的方式测试程序的最小单元,比如方法、类或者组件。为了验证特定代码单元的逻辑是否正确,你应该编写单元测试。通常情况下,单元测试与工程代码分离,测试只会影响到测试单元本身。而mocking框架可以将你的测试单元与其依赖分离。


ADT Eclipse进行单元测试

我们首先来看一下Eclipse怎样进行Android单元测试。

1、建立一个UnitTestDemo工程
2、为工程配置测试环境
这里写图片描述
然后在AndroidManifest文件Application节点下添加一条语句:

<uses-library android:name="android.test.runner" />

这样配置完成了
这里写图片描述
3、编写一个待测试的类,这个类我们会在后面多次用到。

public class Calculator {

    public int add(int a, int b) {
        return a + b;
    }

    public int dec(int a, int b) {
        return a - b;
    }

}

4、为待测试类编写单元测试类,文件放在哪随意,最好把所有测试都放在新建的一个test包啦。

import junit.framework.TestCase;

public class CalculatorTest extends TestCase {

    public void testAdd() {
        Calculator calculator = new Calculator();
        assertEquals(2, calculator.add(1, 1));
    }

    public void testDec() {
        fail("Not yet implemented");
    }

}

5、右击CalculatorTest类,Run As -> Android Junit Test,启动真机或模拟器后即可看到测试结果了。
这里写图片描述

这样我们就完成了最简单的但也很实用的单元测试了。

如果在Eclipse环境下使用过Junit的同学一定会感到奇怪,IDE没有像编写Java程序那样提示我们:
这里写图片描述

下一节来说明


认识

为什么我们Android工程只需要写了配置就可以进行单元测试,好像我们都没有导入Junit框架。原因是,Android SDK本身就内置了基于Junit3的测试框架。我们查下API历史,发现从API 1就已经内置了测试框架了。
这里写图片描述

基于Junit3,整个Android内置的测试框架如下图。
这里写图片描述

关于各种测试有何不同可以参考:

http://developer.android.com/reference/android/test/package-summary.html
http://stackoverflow.com/questions/2047261/using-android-test-framework/2055455#2055455

因为不涉及UI测试,需要用到Context就继承AndroidTestCase,有个getContext方法;不需要直接就继承TestCase和Junit3一样使用。


Android Studio进行单元测试

有了上面的认识,我们知道了Android SDK本身就内置了以Junit3为基础的Android测试框架,而Android Studio本身就默认帮我们配置好了测试环境,所以直接就可以上测试了。

1、建立一个UnitTestDemo Module
2、编写一个待测试的类,直接拷贝上面的。
3、自动生成测试类,生成的代码位置androidTest目录下,编辑测试代码。
这里写图片描述
这里写图片描述

4、右击CalculatorTest类,Run,启动真机或模拟器后即可看到测试结果了。
这里写图片描述

解决了Eclipse和AS进行基本单元测试的问题,还有两个问题值得探讨:
1、每次测试都要启动真机或者模拟器,有没办法进行本地测试;
2、难道就不能用Junit4吗?


本地测试与Junit4

首先来了解一下两个概念:

Local tests:代码被编译成运行在本地JVM的单元测试,使用Local tests无需依赖Android框架,但可以通过mock注入依赖。
Instrumented(Instrumentation) tests:运行在真机或者模拟器的单元测试,这些测试可以获得真机环境,比如context。当难以通过mock注入Android框架的依赖时,就可以使用这种测试。

现在我们知道上面提到的两个例子都是Instrumentation tests。通过继承AndroidTestCase,我们就能分分钟得到context对象啦。不过使用Instrumentation Test每次都要启动一下真机或者模拟器,消耗较多资源,理论上来讲Local Test可以大幅减少测试时间。

1、配置Local Test环境,选择Unit Tests
这里写图片描述

2、导入依赖

testCompile 'junit:junit:4.12'

3、新建一个test/java包,必须。
这里写图片描述

4、和上面一样,自动生成测试类,生成的代码位置test目录下,编辑测试代码。
这里写图片描述

5、右击CalculatorTest类,Run。这一次无需启动真机或模拟器就可以运行了。
这里写图片描述

刚才提到本地测试很大原因是为了一个字快,理论上确实应该更快,然而在我的渣机器上还不如Instrumentation Test快…

我们一下子就实现了本地测试并且使用的是Junit4,Junit4是使用注解的测试框架,无需像Junit3一样测试方法必须使用test开头。上面这个例子我们自动生成的测试类同样可以使用Junit3。
如果我们把步骤2中的Junit4依赖去掉,Junit4不能使用这是不言而喻的,原本在Instrumentation Test可以使用的Junit3呢?答案是不能的,因为单元测试需要Runner,翻到最上面Eclipse那个工程可以看到Android默认的Runner是InstrumentationTestRunner,当我们使用Local Test时因为导入了Junit4依赖,AS能找到Junit4的Runner,怎么着也应该能兼容Junit3吧;而如果把Junit4依赖去掉,AS就找不到合适的Runner来Run这个Junit3的Local Test了。
最后Instumentation Test能使用Junit4吗,答案是可以的,但是配置起来比较麻烦,这里就不多纠结了,有爱可以参考。
https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html#build


小结

1、Android内置基于Junit3的测试框架,默认Runner是InsrtumentationTestRunner。
2、Instrumentation Test需要启动真机或模拟器,默认可以使用Junit3,可以通过配置使用Junit4。
3、Local Test无需启动真机或模拟器,导入Junit4依赖后,支持Junit4兼容Junit3。Local Test不能依赖于Android框架,如果需要注入Android依赖,可以通过mock技术。

这篇文章未涉及的主题包括:
mock和UI测试。

讲了这么一大堆怎样实现单元测试,那究竟测试代码应该怎样写呢。可以参考一些牛库的测试,比如OkHttp:
https://github.com/square/okhttp/tree/master/okhttp-tests/src/test/java/okhttp3

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值