(4.5.4.3)使用Android Studio进行本地单元测试(Local Unit Tests)

由于目前Google已经停止了对Eclipse ADT插件的更新,因此迫使Android的开发者迁移到Android Studio中。Android Studio基于JetBrains IntelliJ IDEA,后者号称世界上最聪明最好用的Java开发IDE。虽然Android Studio提供了很多选项可以为Eclipse的工程迁移以及开发提供便利,但是,对于习惯了Eclipse的开发者来说,这还是需要一个比较痛苦的适应过程。今天给大家分享的就是在Android Studio中进行单元测试的方法。

在Android Studio中可以进行两种单元测试,第一种方式是Local Unit Tests,这种单元测试主要用于对于Android平台没有依赖或者依赖较少的功能的测试,运行在pc上的JVM环境中,不需要依赖与设备或者模拟器,因此测试方便,效率很高。但是如果测试需要依赖Android环境,可以第二种是Instrumented Unit Tests,这种测试方法需要在真实设备或者模拟器中运行。本文主要简单介绍第一种测试方法。

一 环境搭建

由于Local Unit Tests需要用到Junit,如果你的测试代码需要部分依赖android api,你还需要用到mockito,如果要增加测试代码的可读性,官方还建议使用hamcrest。因此你的gradle需要添加声明以下的测试依赖,其中junit是必须的,其他两个可以根据需要添加.

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">dependencies {

            <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">...</span>

            // Unit testing dependencies
            testCompile <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">'junit:junit:4.12'</span>
            // Set this dependency <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> you want to use Mockito
            testCompile <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">'org.mockito:mockito-core:1.10.19'</span>
            // Set this dependency <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> you want to use Hamcrest matching
            androidTestCompile <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">'org.hamcrest:hamcrest-library:1.1'</span>
        }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li></ul>

这个过程由于涉及到从远端下载依赖包,因此根据网络环境不同,可能需要的时间不同。对于时间较长的朋友,可以尝试从其他地方下载好junit等的jar包,然后放到工程的libs目录下,这样就不用声明这些依赖了。

在Android Studio工程建立的时候,会默认在src目录下生成一个androidTest目录,这个目录其实主要是用于存放Instrumented Unit Tests测试代码的目录。为了保持一个清晰的代码结构,在进行Local Unit Tests的时候建议在src目录下新建一个test/java目录,下面存放测试代码,而且建议测试代码的路径最好和被测试代码的路径保持一致,例如,如果你要测试com.example.calsstobetest.SimpleCalculator.java,那么它的本地测试代码最好放在/src/java/test/com/example/classtobetest/目录下,取名叫SimpleCalculatorTest.java。其实在junit4之前,这些要求都是强制的,而且还要求测试方法必须以test开头,不过自从junit4之后,就没有这些要求了,但是推荐还是继续遵守这些规范。

之后,到android studio的主界面中找到Build Variants,将其中的Test Artifact切换为Unit Test, 这个时候可以看到,src/test/java目录变成了浅绿色,表示Android Studio已经将这个目录识别为代码目录了。如下图所示:

环境设置

二 编写测试代码

由于本文主要是说明进行本地单元测试的基本步骤,因此使用一个简单的被测试类来说明,代码如下:

代码路径:src/main/java/com/example/classtobetest/SimpleCalculator.java

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">SimpleCalculator</span> {</span>

            <span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
             * add
             *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> a
             *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> b
             *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span>
             */</span>
             <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">add</span>(<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a, <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b) {

                 <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> a + b;
             }

        }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li></ul>

之后,右键在文件中单机,选择Go To -> Test,再点击create new test file,在弹出的弹窗中选择junit4,然后选择要生成的方法和要测试的方法,如图所示。 
选择测试方法

选择完成后,可以看到,已经在src/test/java目录下自动生成了和被测试代码包名对应的测试类了,基本代码如下:

代码路径:src/test/java/example/classtobetest/SimpleCalculatorTest.java

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">SimpleCalculatorTest</span> {</span>

        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Before</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">setUp</span>() <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {

        }

        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@After</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">tearDown</span>() <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {

        }

        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Test</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">testAdd</span>() <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {

        }
    }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li></ul>

junit4现在使用annotation的方法来指明测试过程中不同阶段的代码块,常用的有如下的几种annotation:

  • @Before: 标志在每次测试之前的初始化阶段需要调用的函数,可以声明多个,一般可以在这些函数中做一些变量初始化之类的操作。
  • @After: 和@Before表示的意义相反,在每次测试结束后调用,也可以声明多个,一般可以在这些函数中释放资源或者内存。
  • @Test: 实现真正的测试,可以声明多个。
  • @BeforeClass: 每一个测试类只能声明一个,用来修饰静态方法,它保证在这个测试类的其他方法被调用之前调用,且只会调用一次,一般用来进行一些复杂且耗时的操作,如数据库连接等操作。
  • @AfterClass: 和@BeforeClass的意义相反,一般用来释放在@BeforeClass中分配的资源。
  • @Test(timeout=): 和@Test方法相似,不过它声明了时间限制,如果在指定的时间类没有完成这个测试,那么就当做这次测试失败。

现在,我们故意修改一下测试类的代码,使单元测试不通过,修改的代码如下:

代码路径:src/test/java/example/classtobetest/SimpleCalculatorTest.java

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">SimpleCalculatorTest</span> {</span>

        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SimpleCalculator mCalculator;

        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Before</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">setUp</span>() <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
            mCalculator = <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SimpleCalculator();
        }

        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@After</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">tearDown</span>() <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
            mCalculator = <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
        }

        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Test</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">testAdd</span>() <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
            Assert.assertEquals(<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3</span>, mCalculator.add(<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">1</span>));
        }
    }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li></ul>

三 测试

在SimpleCalculatorTest类中点击右键,选择Run ‘SimpleCalculatorTest’,即可执行一次这个测试类的测试代码。如果要执行目录下的所有测试,可以在Project目录树下选择Run ‘All Tests’。执行一次测试后,如果有测试未通过的,会在Run的控制台输出,如图所示。 
选择全部测试 
测试结果
同时也可以在工程目录的控制台使用命令行来执行一次测试:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">./gradlew test --<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">continue</span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li></ul>

这样就完成了一次简单的测试流程,可以满足一些不依赖android api的方法或者类的测试。如果测试需要依赖android api,可以考虑使用Mockito或者Instrumented Unit Tests,这个有时间再和大家分享。

参考资料

Local Unit Test

Instrumented Unit Tests

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值