测试驱动开发(tdd) 学习笔记(1)基本思想原则和术语

来源:互联网 发布:手机发广告软件 编辑:程序博客网 时间:2024/05/01 16:14

    这几天学习了一下测试驱动开发(tdd) 实用指南,感觉相见恨晚,收获很大。以前也听别人说过测试驱动开发,也用过dunit,但是当时不知道具体的含义,也没有仔细研究一下,真是遗憾。

   Test-Driven Development  A Practical Guide 测试驱动开发,实用指南,作者David Astels

        测试驱动开发的主要思想是 测试先行,在写一个类的具体实现之前,先写类的测试代码,类的测试代码通过调用各种public 的方法,对类进行测试。在写测试代码的过程中,思考类的调用方法,也就是类的外在表现形式。

      我觉得这种做法的很大一个好处是:因为设计一个类是从它的外部形态开始的,所以设计类的时候就会自然的考虑类的封装。

        测试驱动开发采用的主要方法之一是重构(refactoring)。重构两个字的字面意思,并不能涵括它的具体涵义,在tdd中重构具体指什么,下面通过一个简单的例子来说明:

        我们想编写一个math 类,来实现简单的加(sum)、减(minus)运算,首先我们编写math 类的初步测试方法。

public class testMath extends TestCase{

     public void testSum(){

          math math1 = new math ;

          assertEquals("3加2应该等于5",5,math1.sum(3,2));

     }

然后我们编写具体的math 类

public class math {

     public int sum(int a,int b){

          return 5;

     }

}

运行测试,测试通过。但是很明显,sum方法的算法是不对的,这是因为测试不够全面。我们重新修改测试

public class testMath extends TestCase{

     public void testSum(){

          math math1 = new math ;

          assertEquals("3加2应该等于5",5,math1.sum(3,2));

          assertEquals("0加0应该等于0",0,math1.sum(0,0));

          assertEquals("1加1应该等于2",2,math1.sum(1,1));

     }

然后我们对math类的sum方法进行重构

public int sum(int a,int b){

          return a+b;

}

        以上是一个简单的例子,如果是在实际的开发中的话,至少还要加上对临界值的测试,比如两个最大的int值相加等。在上面的例子中,重构是为了让测试通过,或者说是为了保证代码功能上的正确性;有了这些test 作保证,我们还能为了提高代码的质量而重构。

          我个人的理解,测试驱动开发的一个原则就是,编写可以信任的测试,只要测试全部通过,那么说明类的方法全部正确,如果你对代码没有信心,那说明测试代码的测试覆盖面不够,需要进一步完善。

         关于重构的方法,书上归纳的有 extract class ,extract interface,extract method,replace type code with subclasses,replace conditional with polymorphism,form template method,introduce Explaining variable,replace constructor with factory method,replace inheritance with delegation,replace magic number with symbolic constant ,replace nested conditional with guard clauses,,refaction to patterns. 这些方法有很多的目的是提高代码质量。