android 单元测试Android单元测试技术

Android单元测试——初探

2016-11-08  本文已影响1636人  红灰李

引言

这篇文章主要是总结一下我自己在学习Android单元测试过程中的收获及感悟,同时也希望可以帮助到正在学习Android单元测试的小伙伴们.由于时间及经验有限,文中可能存在错误与不足,欢迎大家指出,我会在第一时间对文章进行修改纠正.
本文主要包含以下内容:

什么是单元测试

首先总结一下什么是单元测试,单元测试中的单元在Android或Java中可以理解为某个类中的某一个方法,因此单元测试就是针对Android或Java中某个类中的某一个方法中的逻辑代码进行验证即测试该方法是不是可以正常工作。
还有一点就是要区分单元测试与集成测试(功能测试、UI测试),单元测试是针对单元即方法的测试,被测单元粒度要小并且具备独立性,而集成测试是测试多个单元(方法)组合成的功能模块。

为什么需要进行单元测试

public boolean checkPhoneNum(String phoneNum){
  //判断phoneNum是否为空(实际的判断会稍微复杂一点,为了举例做了简化)       
  if(phoneNum == null || "".equals(phoneNum)){
    return false;
  }
        
  return true;
}

如何进行单元测试

在Android中进行单元测试有很多方案,主要可以分为两类

根据实际情况,可以灵活切换以上两种方案

如何在Android中进行单元测试

Paste_Image.png

    在Eclipse中需要为被测工程添加JUnit依赖,在被测工程右键点击Properties,在窗口左侧选择Java Build Path,选中右侧Libraries,点击Add Library,选择JUnit

Paste_Image.png Paste_Image.png

更好的做法是新建一个测试工程,将被测工程作为测试工程的依赖,再为测试工程进行如上配置,方便我们对测试代码的管理。

一个单元测试大概可以分为三个部分:
setup:即new 出待测试的类,为测试设置一些前提条件
执行动作:即调用被测类的被测方法,并获取返回结果
验证结果:验证获取的结果跟预期的结果是一样的

代码示例如下:

public class Calculator {
    
    /**
     * 将两个数相加
     * @param a
     * @param b
     * @return a + b
     */
    public int add(int a,int b){
        return a+b;
    }
    
    /**
     * 将两个数相减
     * @param a 被减数
     * @param b 减数
     * @return a - b
     */
    public int subtract(int a,int b){
        //将被减数与减数互换,模拟Bug
        return b - a ;
    }
}

Calculator 为被测类,Calculator 中有两个方法,也就是测试单元。add方法做加法计算、subtract方法做减法计算(subtract中将被减数与减数互换,模拟Bug)

public class JUnitTest {
    private Calculator mCalculator;
    
    @Before
    public void setUp(){
        mCalculator = new Calculator();
    }
    
    @Test
    public void testAdd(){      
        int result = mCalculator.add(1, 3);
        Assert.assertEquals(4, result); 
    }
    
    @Test 
    public void testSubtract(){
        int result  =  mCalculator.subtract(6, 4);
        Assert.assertEquals(2, result); 
    }
}

JUnitTest 为测试类,该类的创建过程可与正常类创建过程一致。
其中以@Before注解的方法中的代码对应前文中提到的三个步骤中的setUp,为以@Test注解的测试方法设置一些共有的前提条件,在这个例子中就是new出被测试类。而实际情况中可能还有相关参数与配置相关依赖或通过Mock框架进行依赖隔离等操作。
以@Test注解的方法之间是互相独立的,不存在执行上的因果关系
以testSubtract()为例

int result = mCalculator.subtract(6, 4);

对应三个步骤中的执行动作,即执行Calculator中的add方法并获得add方法的执行结果

Assert.assertEquals(2, result); 

对应三个步骤中的验证结果,Assert为JUnit提供的类,内部有一系列用于验证被测单元返回值是否与期望值一致的方法,在本例中通过Assert.assertEquals(4, result),验证mCalculator.subtract(6, 4)的执行结果result是否与预期值4相等

接下来就是运行测试类JUnitTest Android Studio中右键点击 Run ‘JUnitTest ’ 会执行JUnitTest 中所有以@Test注解的方法,并会输出验证报告
在Eclipse中需要进行配置,才能进行纯Junit的单元测试,在被测类中右键点击Run As,点击Run Configurations

Paste_Image.png

在出现的窗口中选中右侧的Classpath,默认情况下Bootstrap Entries节点下应该为Android SDK,而这里需要把Android SDK替换为JRE System Library。替换流程如下图,先将Bootstrap Entries节点下的Android SDK Remove,之后选中Bootstrap Entries节点,点击右侧的Advanced,选中Add Library,选择JRE System Library,Next 直到结束

Paste_Image.png Paste_Image.png Paste_Image.png

配置完成后就可以在被测类中右键点击 Run As JUnit Test,运行完成之后就会输出测试报告如下图(下图为Eclipse中的测试报告,Android Studio中类似)

Paste_Image.png

从上往下看上图,首先Failures表示有一个测试没有通过,本例中的运行时间基本可以忽略不计为(0.019s),相对于运行到真机上差别是非常大的。testSubtract测试方法没有通过,因为在被测方法中为了模拟Bug将减数与被减数互换,导致预期结果(6 - 4 = 2)expected:<2> 与实际运行结果(4 - 6 = -2)<-2>不一致.根据上图我们就能快速的将Bug定位到被测类Calculator 的subtract方法中(快速定位Bug)。

在实际的项目代码的情况会相对比较复杂,因此可以通将纯Java的逻辑代码抽离出来,具体方案有通过MVP架构将逻辑代码与Android 组件(比如:Activity)解耦,或者像上面的例子中将纯Java逻辑代码封装到类似Calculator的Utils类中,不过要尽量避免使用静态方法,这样的访问方式。(提升项目代码质量)


小结

这边只简单总结了我自己目前在学习Andorid单元测试中的感悟和收获,Andorid单元测试中其实还涉及到很多其他的技术,比如Mock的概念以及Mockito框架(隔离依赖,保证被测单元的独立性)、Dagger2依赖注入框架,配合Mockito让我们更便利的在Android中进行单元测试、MVP架构。

参考文献

上一篇下一篇

猜你喜欢

热点阅读