zoukankan      html  css  js  c++  java
  • 写了一个月的单元测试,总算明白大学里这门课白学了

      上大学的时候学过软件测试这门课,但是在公司实习时才真正实战了一把。先花了半个月把Junit In Action 英文版看完了(话说在公司学习效率就是比学校里高啊) 废话不多说,直接开始主题。

      为什么要写单元测试?

      两个理由:1.给我们重构的信心(give us the confidence to refactor)。一堆纠缠而无测试的代码你敢随便修改?

           2.好的单元测试就是文档(documenting expected behavior)。几个实用的例子比文档让人感兴趣的多。

      

      概念就不说了,黑盒白盒TDD,语句路径覆盖率,网上都有,直接讲讲我的收获吧。

      

      我在项目里最初就是给一些基础类(EntityModel)写测试,它是一个抽象类,内部保存Entity,并执行增删改查的操作。那么我第一个遇到的问题就是:如何测试一个抽象类?方法很简单,就是去定义一个子类,然后生成子类的实例做测试。拿测试update函数来说,有三个步骤:

      1.准备一个Entity,给他设置两个属性,age = 10,weight = 50。

      2.把它add进EntityModel,进行update操作,修改他的weight = 80。

      3.最后get出来,验证得到的Entity weight = 80 且 age = 10。

      代码如下:

      @Test
        public void testUpdateEntityWhenNotTheSameProperty() {
    
            MyEntity myEntity = createMyEntity(AGE_ID, WEIGHT_ID, 0L);
            entityModel.addEntity(myEntity);
            entityModel.updateEntity(myEntity.getClass(), myEntity.getId(), MyEntity.PROPERTY_NAME_AGE, DIFF_AGE_ID);
            assertEquals(DIFF_AGE_ID, myEntity.getAge());
        }

      而这三个步骤总结起来就是"准备-构建-验证"(《clean code》 , Unit Test chapter),测试用例都遵从这个步骤。

      写着写着,你会遇到一些问题。怎么验证我的函数里面调用了一个静态方法去记录log日志?怎么验证一个私有方法?怎么测试一个接口?怎么测试向一个数据库插入数据的操作?怎么验证我测试的程序一定会抛出一个异常?……这下就要到网上去查了,有许多现成的框架可供使用,大名鼎鼎的Junit;Mockito可以模拟接口,模拟函数返回值,验证方法调用次数;Powermock(查看需FQ)可以模拟静态方法和final方法;Java的反射机制可以模拟私有方法。

      给函数起名也有讲究。我一般用test__when__thenReturn__的结构,尽量让看的人不用看代码就能知道功能。

      不能为了省事而把不同性质的验证放在一个test中,一次只做一件事,做好一件事。

      而且最重要的是,在写单元测试过程中,我慢慢就对代码的逻辑清楚了。如果必须要覆盖每个判断,等我写完测试用例,我就已经知道这个函数的每个细节。这对于以后重构很有帮助。

      

      写的不多,但是我要坚持写下去,因为总结和思考的过程就是成长。

    ——周五晚在公司

       

    --------------------------------------------

      今天又学到一招,mock过静态方法的朋友知道,需要在类前添加

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(xxx.class)

      而如果我需要在一个类中验证两个不同类的静态方法,只需要

    @PrepareForTest({Hello.class, World.class})
    或是
    @PrepareForTest(fullyQualifiedNames = {"com.util.log4j.LogManager","com.rcm.model.risk.defs.BettingFamilies"})

    ——2015/2/2

      

  • 相关阅读:
    Github markdown页面内跳转
    github gist 无法访问
    Install pyaudio on Ubuntu
    删除链表的倒数第N个节点
    电话号码的字母组合
    最长公共前缀
    盛最多水的容器
    字符串转化整数与回文数
    Z 字形变换
    LeetCode1-5题
  • 原文地址:https://www.cnblogs.com/andrew-chen/p/4263289.html
Copyright © 2011-2022 走看看