Android单元测试系列

来源:互联网 发布:excel数据被保护 编辑:程序博客网 时间:2024/05/16 04:13

前沿:
Android SDK 测试类是基于Junit3来进行扩展的,因此我们有必要了解Junit3,本文将详细介绍Junit3的相关知识。

1.什么是 JUnit

这里写图片描述

2.JUnit 的运作模式

1.定义测试代码:这也就是 JUnit 中所谓的 TestCase,根据源代码的测试需要定义每个TestCase,并将 TestCase 添加到相应的 TestSuite 方便管理。

2.管理测试用例:修改了哪些代码,这些代码的修改会对哪些部分有影响,通过 JUnit 将这次的修改做个完整测试。这也就 JUnit 中所谓的 TestSuite。

3.定义测试环境:在 TestCase 测试前会先调“环境”(如:参数化测试环境,套件测试环境)配置,在测试中使用,当然也可以在测试用例中直接定义测试环境。

4.检测测试结果:对于每种正常、异常情况下的测试,运行结果是什么、结果是否是我们预期的等都需要有个明确的定义,JUnit 在这方面提供了强大的功能。

简单来说就是: TestCase -> TestSuite -> TestRunner ==> TestResult

3.如何在AndroidStudio上搭建Junit测试环境

版本:Window 7旗舰版
IDE:Android studio 2.2.3
gradleVersion :gradle 2.2.3

3.1 我们需要先搭建一个Junit的运行环境,由于我们是基于Android的单元测试系列,所以我们将介绍如何在Android Studio中搭建Junit运行环境:

这里写图片描述

在Adroid 视图模式下,可以看到一个test 和 androidTest两个文件夹。Test文件夹是进行本地测试,而androidTest 是功能性测试,在本文属于单元测试,不需要连接具体的模拟器或者真机,单元测试代码写在Test文件夹里面。

编写一个简单的Junit3测试用例

1.选中待测试类中具体的方法。右击goto—>Test 弹出如下窗口进行简单操作,就可以生成一个junit3的单元测试。(更改选项卡也可以生成 junit4 的单元测试)

这里写图片描述

public class MathUtilTest extends TestCase {    public void setUp() throws Exception {        super.setUp();      System.out.print("开始.......\n");    }    public void testAdd() throws Exception {        System.out.print(".testAdd      \n");        assertEquals(2, MathUtil.add(1, 1));    }    public void testAdd1() throws Exception {        System.out.print(".testAdd1      \n");        assertEquals(2, MathUtil.add(2, 2));    }    public void tearDown() throws Exception {        System.out.print("结束.......\n");    }}

1.在Junit3,为了更好的管理项目,建议将测试类放在与源代码同包名下的目录下

这里写图片描述

2.命名建议原类名+TestCase
3.unit3中规定具体运行的测试方法必须要以test开头,后面的自己另起。于是就有了测试方法test_add()(为了清晰,我个人习惯用下划线命名规则来命名测试方法)
4.测试 的方法有了,那么我们根据什么来判断这个测试方法是否通过呢,没错,就是通过assertEquals(期望值,实际值)方法来进行断言,由于我们知道1+1肯定等于2,于是我们就断言如果方法MathUtil.add(1, 1)的结果肯定为2,于是就有了assertEquals(2, MathUtil.add(1, 1));

运行
右击方法就方法选择Run->testadd()

这里写图片描述

6.运行结果,因为实际值与期望值相同所以就通过了

这里写图片描述

7.当然如果和期望的值不相等就会出现异常情况。

这里写图片描述

可以看到测试用例结果显示,一个通过一个没有通过。没有通过原因也写出来了,Expected 值和Actual值不相等。

这里写图片描述

junit3测试有几明显的地方。

1.测试方法必须以test开头否则无法识别
2.需要继承TestCase类。

断言

TestCase类是继承自Assert,因此默认拥有下面的断言方法,具体也可以参考源码(junit.framework.Assert)中支持的断言方法

这里写图片描述

setUp&&tearDown

Junit3中TestCase提供了 setUp 和 tearDown方法:

setUp():在每个测试方法之前调用,一般用于初始化

tearDown():在每个测试方法执行完毕之后调用,一般用于资源回收

如果类中存在多个测试方法,那么测试执行顺序为

    1.1setUp->    1.2test_测试方法1->    1.3tearDown->    1.4setUp->    1.5test_测试方法2->    1.6tearDown->

4.TestCase

4.1 测试异常

测试的时候遇到异常可以通过在方法后面throws Exception处理,将异常抛出,在最终的测试结果中可以查看到。
那么什么时候需要抛出异常呢?
下面我举一个场景:
实际开发过程中,我们难免会设计一些方法,这些方法可能会抛出某些指定的异常,需要给上层使用者进行处理,那么在测试的时候,我们可以将这些指定的异常进行捕捉,然后针对其他异常进行抛出,作为测试结果,测试这些方法是否会有额外的异常出现。
例如下面的例子:

public class MathUtil {    /**     * 从一个浮点型字符串中获取小数部分的整数     * <p/>     * 实际上如果是一个整数或者其他不是数字的字符串,我们除了抛出无法转型的异常之外,还可能会抛出数组越界的异常     * 假设是"123",那么是没有numbers[1]的     *     * @param str     * @return     * @throws NumberFormatException     */    public static int getDecimalFromString(String str) throws NumberFormatException {//声明已经知道的异常        String[] numbers = str.split("\\.");        return Integer.valueOf(numbers[1]);    }}测试类
public class MathUtilJunit3TestCase extends TestCase {    public void test_getDecimalFromString() throws Exception {        System.out.println("---Calling test_getDecimalFromString---");        try {            assertEquals(456, MathUtil.getDecimalFromString("123.456"));            assertEquals(0, MathUtil.getDecimalFromString("abc"));            assertEquals(0, MathUtil.getDecimalFromString("123"));        } catch (NumberFormatException e) {            assertNotNull(e.getMessage());        }    }}运行结果片段,除了定义的格式异常,还会出现 OutOfBoundsException 等其它提前没有预料到的异常

这里写图片描述

经过这个测试能够过滤已知异常,对未知异常暴露在测试阶段。

4.2 测试套件

测试套件说白了就是批量测试。将独立的测试进行组装,达到一次测试多个目的。

/** * @author ywc * @since 2017-01-13  */public class UtilTestSuite extends TestSuite {    public UtilTestSuite() {        super();        addTestSuite(MathUtilTestCase.class);    }}

通过junit提供的api可以方便的实现。需要注意继承的父类是TestSuit 而不是单元测试TestCase。

4.3 测试

配置全局初始化和结束

TestSuite可以理解为一个功能单元集合,有时我们希望在测试这个单元功能时,全局初始化一些资源,以及全局回收一些资源(比如:初始化时建立数据库连接,结束时候统一结束连接),那么这个时候,采用TestCase的setUp和tearDown明显不够用了(testcase的setup和down是每次运行单个测试方法均会调用)

public class UtilTestSuite extends TestSuite {    public UtilTestSuite() {        super();        addTestSuite(MathUtilTestCase.class);    }    public Test suite() {        addTestSuite(MathUtilTestCase.class);        TestSetup wrapper = new TestSetup(this) {            protected void setUp() {                System.out.println("---Calling Global_setUp---");            }            protected void tearDown() {                System.out.println("---Calling Global_tearDown---");            }        };        return wrapper;    }

这里写图片描述

如果你进行过实际操作的话,就会发现默认的AndroidSDK中没有TestSetup类,这是因为Android SDK中仅保留极少部分的Junit3代码(主要是junit.framework的代码),其中并没有我们所用到的TestSetup类
那么TestSetup类又是从哪里来的呢,其实在使用的时候,我已经引用了Junit4.12的类库了

这里写图片描述

到这里junit3中的常用的api已经有个大概了解。接下来开始介绍令人期待的junit4了

http://caizhitao.com/2015/07/14/android-test-use-junit3/ (感谢作者)

0 0
原创粉丝点击