51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 2384|回复: 0

[讨论] [Android技术专题]每个开发者都应该懂一点单元测试

[复制链接]
  • TA的每日心情
    无聊
    2023-12-19 11:16
  • 签到天数: 40 天

    连续签到: 1 天

    [LV.5]测试团长

    发表于 2018-5-30 17:04:38 | 显示全部楼层 |阅读模式
    一、什么是单元测试?

    为了测试某个类中的某一个方法能否正常工作,而写的测试代码。

    单元的定义:代码中可度量的最小单元(函数/方法);

    是否正常工作:不同的输入对应的输出是否与预期一致。

    二、单元测试有必要吗?

    1 对是否有必要写单元测试的疑惑

    没有价值:不做单元测试一样地开发,并没有什么问题(解释:);

    浪费时间:写单元测试需要大量的时间,还不如写具体的实现,具体的实现能看到明显的效果,但单元
    测试可能耽误正常的迭代进度;

    无法测试:比如无返回值的方法、UI等;

    2 不写单元测试会存在的一些问题:

    要有足够的耐心:改一个参数,需要重新运行一遍程序;

    没有足够的自信:每次提测和发布,心惊胆战,对自己写的程序没有信心;

    要有足够的时间:必须要等到测试发现bug后才去改善;

    bug太多,程序很难稳定:可以看下你自己开发的应用,如果有做异常采集,上报的大多数异常问题,
    都是因为程序没有做好容错导致的,比如空指针、被除数为0、数组越界等;

    3 单元测试能够解决的问题

    效率:如果没有单元测试就必须把程序运行起来测试;运行一次单元测试,最多几分钟,cover得比较
    全面,相比于执行程序,效率高很多很多;

    质量:对于每个最小单元,针对不同输入对应的输出有与预期做对比,能够减少因为参数导致的异常
    问题,同时提测和发布版本的时候,有信心;

    提升设计能力:为了每个单元都可测,需要将每个方法拆得尽量独立,如果不拆得足够独立,就无法
    测试,间接可以提高程序设计能力;

    代码重用:跑过单元测试的代码,稳定性能够得到保证,可以在其它项目或者项目重构时重复利用;

    缩短测试周期:程序自测(开发人员写单元测试、手动跑基本功能、跑monkey都属于自测)可以提高
    产品提测的质量,避免返工;同时核心功能的稳定有助于缩短黑盒测试的周期。

    三、哪些可以做单元测试?

    任何方法都可以做单元测试;

    从必要性来讲,针对UI相关的做单元测试必要性不大,并且很多东西需要主观判断;所以只针对Model和
    Control层做测试;

    私有方法同样可以测试(反射,或者在测试时改为public方法),但非public方法是这个类的实现细节,
    其它类并不关心,不用测试;

    四、关于单元测试的一些概念

    1 分类

    按测试内容分:

    功能测试:和UI无关,测试IO操作、算法、流程等;

    UI测试:测试UI交互逻辑,比如点击、登陆等;

    按是否依赖设备分

    不依赖Android设备,只需要运行在JVM上的;→真正的单元测试,执行快,效率高;

    依赖Android设备(模拟器/真机),需要程序运行时状态信息的,比如获取磁盘空间、四大组件的上下
    文信息、异步任务、消息传递等;→其实是集成测试,需要运行整个程序,执行慢,效率低;

    2 测试框架

    如果没有框架该如何做单元测试

    自己写程序进行逻辑判断(麻烦、加入测试程序有bug怎么办?);

    在console中观察测试结果;

    测试框架能够提高测试效率

    JUnit、Instrumentation test、Espresso、UI Automator、Robolectric、Appium、Robotium

    JUnit:能够直接在PC上执行;

    AndroidTest:需要依赖Android设备;

    Robolectric:在不需要依赖Android环境的前提下,实现在PC上直接运行Android的单元测试;

    Robotium:第三方UI测试框架;

    Espresso:Google推出的UI测试框架;

    UI Automator:流程的UI测试框架;

    3 覆盖率

    衡量单元测试质量,通过覆盖率测试,可以明确知道哪部分代码已经被单元测试覆盖到,哪部分没有进
    行单元测试;常用的单元测试插件有Emma、JaCoCo;
    4 JUnit框架中的常用方法

    setUp/@Before:在每个单元测试方法执行之前调用;

    tearDown/@After:在每个单元测试方法执行后调用;

    setUpBeforeClass/@BeforeClass:在每个单元测试类运行前调用;

    tearDownAfterClass/@AfterClass:在每个单元测试类运行完成后调用。

    Junit3中每个测试方法必须以test打头,Junit4中增加了注解,对方法名没有要求,@Test就可以。

    5 一个单元测试的流程

    setUp:设置前提条件,比如初始化;

    执行动作:调用被测方法,并得到返回结果;

    验证结果:验证获取的结果和预期是否一致;

    6 关于Mock

    在写单元测试的过程中,我们可能会发现需要和系统内的某个模块或系统外某个实体交互,而这些模块
    或实体在您做单元测试的时候可能并不存在,比如您遇到了数据库、遇到了驱动程序等。这时开发人员
    就需要使用mock技术来完成单元测试。

    mock就是创建一个类的虚假的对象,在测试环境中,用来替换掉真实的对象,以达到两个目的:

    验证这个对象的某些方法的调用情况,调用了多少次,参数是什么等等;

    指定这个对象的某些方法的行为,返回特定的值,或者是执行特定的动作。

    要使用mock技术,就需要使用mock框架,Mockito和Jmockit是android平台两个常用的mock框架,其中
    Mockito不能mock static method和final class、final method,但Jmockit可以。

    7 依赖注入在单元测试中的使用

    上文中提到的Mock技术就是创建一个类的虚假的对象,在测试环境中用来替换掉真实的对象,但如何在
    测试环境下,将某个类替换成mock的对象就需要使用到依赖注入了,他的基本理念是,某一个类(比如
    说DataActivity),用到的内部对象(比如说DataModel)的创建过程不在DataActivity内部去new,而是
    由外部去创建好DataModel的实例,然后通过某种方式set给DataActivity。这种模式应用是非常广泛的,
    尤其是在测试的时候。常见的依赖注入框架有:Roboguice、Dagger、Dagger2。

    在实际写单元测试的过程中,mock技术会经常用到,所有非常有必要熟悉其中一种依赖注入框架,关
    于依赖注入的详细解释可以参见公共技术点之依赖注入。

    五、单元测试集成到Jenkins

    Jenkins上不需要任何改动,执行现有的gradle命令会自动执行单元测试,测试不通过会报编译错误;
    六、说明

    不要指望对某个方法的单元测试一次能够写得足够完美,单元测试也是需要持续迭代的(比如入参考虑得
    不全面、单元测试粒度没有足够细等);

    并不是所有针对源码级别写的测试代码都叫单元测试,针对具体某一个方法的测试叫单元测试,涉及到UI
    层面、必须要运行程序才能跑的测试叫集成测试,比如很多基于android平台的第三方UI测试框架;

    test和androidTest文件夹的区别:如果你是用Android Studio做开发,在创建工程的时候,src文件夹下会
    同时生成三个文件夹main、test、androidTest,其中test和androidTest是专门针对源码级别的白盒测试的
    ,test文件夹用于写不依赖设备环境的单元测试,即直接在PC上即可运行的测试,特点是测试效率高;an
    droidTest文件夹用于写需要在设备上才能运行的测试,比如测试依赖android API和设备环境的时候(conte
    xt、IO操作、UI测试等),就需要在这个文件夹下面写单元测试了,其特点是必须要编译生成APK后才能
    测试,效率低;

    测试驱动开发(TDD)的这种软件开发方法提倡先写测试程序,再才编码实现具体的功能;



    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-3-29 07:21 , Processed in 0.064974 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表