`
leon0122
  • 浏览: 45461 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

测试驱动开发With JUnit(一)

阅读更多
       测试驱动开发(TDD)是极限编程(XP)的重要特点,它是以持续性的测试来推动代码的开发,即可以简化代码,又可以保证质量。它改变了先编写代码,后编写测试,而是先编写测试,然后在编写代码来满足测试的方法。这样使得测试工作不仅仅是单纯的测试,而成为了设计的一部分。对于刚入门的编程者来说,也许觉得非常地别扭,但是当你习惯了这种编程方式之后,你会发现,TDD会成为你的得力助手。
      下面的内容就以学习JUnit这个测试工具来简单的介绍TDD。(注:本文主要内容是介绍JUnit的使用,顺便抛砖引玉介绍TDD的开发过程。想了解更多关于TDD,可以参考其他的一些专业书籍)。
      开发环境是:Eclipse3.2,已经集成了JUnit,所以就对Junit的配置不做介绍(网上这种文章太多了)。

第一章:JUnit快速入门:
       需求:需要一个工具类,可以实现2个数的加、减、乘、除四个功能。我们给这个类起名叫CalculateUtil。
       先编写测试代码:
 
 
  1. import junit.framework.TestCase;                //1行   
  2. public class CalculateUtilTest extends TestCase  //2行   
  3. {   
  4.     public void testCreate()                     //3行   
  5.     {   
  6.         new CalculateUtil();   
  7.     }   
  8. }  
      代码解释:
      1行:导入JUnit必须的类
      2行:任何一个测试类必须集成TestCase类。
                测试类的类名命名   方式:被测试类类名+Test。这是一种比较好的习惯,
                比如从CalculateUtilTest这个名称就知道被测试类是CalculateUtil
       3行:测试类的测试方法。所有的测试方法都必须以test单词开头,并且方法的返
                回类型为void。
       编写完测试代码之后在Eclipse中运行该测试类,发现Junit运行出错(显示了一条红色杠)

       这是在预料之中,因为我们还没有编写CalculateUtil类。为了使测试通过,那么下面开始编写CalculateUtil类。CalculateUtil类代码如下:

 
 
  1. public class CalculateUtil   
  2. {   
  3. }  

        然后再次运行测试类。这时会发现测试成功。
       
 
  1. import junit.framework.TestCase;   
  2. public class CalculateUtilTest extends TestCase   
  3. {   
  4.     public void testCreate()                    //1行   
  5.     {   
  6.         CalculateUtil ca=new CalculateUtil();       
  7.         assertEquals(5, ca.add(3,2));             //2行   
  8.     }   
  9. }  

       在这里代码稍微改变了一下,使用ca引用来指向生成的CalculateUtil对象。
       代码解释:
       1行:测试类的方法必须以单词test开头
       2行:assertEquals()方法。以assert单词开头的方法就是JUnit测试框架中的断    
                言方法。比如assertEquals(5, ca.add(3,2)); 方法就是断言ca的add(3,2)方
                法返回的结果等于5。如果add(3,2)返回5那么测试成功,否则测试失败。
         运行测试类,这时测试失败。那么向CalculateUtil中添加代码来保证测试成功:
 
 
  1. public class CalculateUtil   
  2. {   
  3.     public int add(int numOne,int numTwo)   
  4.     {   
  5.         return numOne+numTwo;   
  6.     }   
  7. }  

       为了验证add方法是否是真的返回两个数的相加的结果,我们继续在添加一行测试代码:
 
 
  1. assertEquals(7, ca.add(4,2));  
    再运行会发现测试出错
      故障跟踪中错误描述为:
      junit.framework.AssertionFailedError:expected:<7> but was <6>
      (如果你英语不是很差的话,相信这句话不用我解释也明白了)。在测试的时候,要选用一些容易出错的边界值进行测试,有正确的测试用例也要有错误的测试用例。
     在完成add方法之后,下面开始进行除法的编写。首先编写测试代码:
 
 
  1. import junit.framework.TestCase;   
  2. public class CalculateUtilTest extends TestCase   
  3. {   
  4.     public void testCreate()   
  5.     {   
  6.         CalculateUtil ca=new CalculateUtil();   
  7.         assertEquals(5, ca.add(3,2));               
  8.     }   
  9.     public void testDivision()   
  10.     {   
  11.         CalculateUtil ca=new CalculateUtil();   
  12.         assertEquals("两个数相除"2,ca.division(42));  //1行   
  13.     }   
  14. }  

      代码解释:
      1行:assertEquals("两个数相除", 2,ca.division(4, 2));和前面assertEquals方法  
               不一样,该方法多了一个参数,这个参数就是对该测试的一个简单的描述。
       如果测试失败,那么会有提示。
       为了使测试通过,就要在CalculateUtil类中添加一个division方法。代码如下:
 
  1. public class CalculateUtil   
  2. {   
  3.     public int add(int numOne,int numTwo)   
  4.     {   
  5.         return numOne+numTwo;   
  6.     }   
  7.     
  8.     public int division(int numOne,int numTwo)   
  9.     {   
  10.         return numOne/numTwo;   
  11.     }   
  12. }  

        运行测试代码,测试通过。那么这样就可以了吗?由于除法非常特殊,如果除数为0那么会怎么样呢?我们继续在testDivision()中添加一行测试代码测试除数为0的情况:
 
 
  1. public void testDivision()   
  2. {   
  3.     CalculateUtil ca=new CalculateUtil();   
  4.     assertEquals("两个数相除"2,ca.division(42));    
  5.     assertEquals("除数为0:"2,ca.division(4,0));   
  6. }  

       运行测试,会发现testDivision()方法抛出了异常。
 
       测试表明:当除数为0的时,方法division()生成了一个异常。那么我们希望在测试用例中捕获该异常。更改后的testDivision()方法如下: 
 
 
  1. public void testDivision()   
  2. {   
  3.     CalculateUtil ca=new CalculateUtil();   
  4.     assertEquals("两个数相除:"2,ca.division(4,2));   
  5.     try  
  6.     {   
  7.         assertEquals("除数为0:"2,ca.division(4,0));   
  8.         fail("除数不为0");                          //1行   
  9.     }   
  10.     catch(ArithmeticException ex){}   
  11. }  
      代码解释:fail()一旦被执行,会立即中止测试,java虚拟机不再执行任何别的代码,并且会抛出junit.framework.AssertionFailedError异常。结合上面的try-catch语句,如果产生异常,那么会忽略fail()方法,如果没有产生异常那么就会调用fail()方法使测试失败,用这种方式就可以测试是否有异常产生,如果抛出异常,那么测试通过,否则测试失败。再次运行测试用例,一条绿杠显示测试通过。
       但是这样还是不妥,因为类CalculateUtil毕竟是不知道测试类的存在,虽然在测试类中用异常捕获,但是一旦脱离测试类,那么division()方法的健壮性还是受到质疑。所以从新修改division()方法
 
 
  1. public int division(int numOne,int numTwo)throws ArithmeticException   
  2. {   
  3.     return numOne/numTwo;   
  4. }  

       再重新运行测试用例,测试通过。
注:处理异常的方式很多,这里只是其中一种做法。也可以在division()方法中写一段业务逻辑,判断numTwo是否为0,如果为0则抛出异常等……,在这里不做深入讨论。
        从刚才的几个例子中,可以大概的知道TDD的开发思路,也知道JUnit的基本用法。但当我们反观CalculateUtilTest 类中的测试方法可以发现:类中的两个测试方法都构造了CalculateUtil的对象ca,但是对于程序来说,我们只需要构造一个对象即可。我们可以对CalculateUtilTest类中的代码稍作修改。修改后代码如下:
 
 
  1. public class CalculateUtilTest extends TestCase   
  2. {   
  3.     private CalculateUtil ca;   
  4.     protected void setUp() throws Exception    //1行   
  5.     {   
  6.         ca=new CalculateUtil();                    
  7.     }   
  8.     
  9.     public void testCreate()   
  10.     {   
  11.         assertEquals(5, ca.add(3,2));   
  12.         assertEquals(7, ca.add(4,2));   
  13.     }   
  14.     
  15.     public void testDivision()   
  16.     {   
  17.         CalculateUtil ca=new CalculateUtil();   
  18.         assertEquals("两个数相除:"2,ca.division(4,2));   
  19.         try  
  20.         {   
  21.             assertEquals("除数为0:"2,ca.division(4,0));   
  22.             fail("除数不为0");                            
  23.         }   
  24.         catch(ArithmeticException ex){}   
  25.     }   
  26. }  

       代码解释:
       1行:JUnit在执行每个测试之前都先执行setUp方法,可以将公共的测试初始化代码放在setUp方法中。与setUp功能方法相反的是protected void tearDown() throws Exception方法;可以将测试结束后要执行的收尾工作放入tearDown方法中,比如:关闭数据库连接,关闭流……
分享到:
评论
2 楼 zuowangxi 2009-11-11  
Very Good!
Study。。。
1 楼 flyinglife 2008-07-27  
博主,写的相当之好,今天才看见,相见很晚。

相关推荐

    测试驱动开发with Junit(三)

    在“测试驱动开发with Junit(三)”这一主题中,我们将会深入探讨如何利用Java中的JUnit框架进行TDD实践。 JUnit是Java编程语言中最常用的单元测试框架之一,它为开发者提供了方便快捷的方式来编写和运行可重复的...

    测试驱动开发With Junit

    总结,测试驱动开发With Junit涉及到的主要知识点包括: - TDD(测试驱动开发)的概念和流程 - JUnit作为Java的单元测试框架,如何创建测试类和测试方法 - 如何使用`assert`方法进行断言,确保代码行为正确 - 创建和...

    JUnit 4测试驱动开发----junit技术讲解

    本文将深入讲解JUnit 4的关键特性和如何进行测试驱动开发。 1. 预备知识 在开始使用JUnit 4进行测试之前,了解一些预备知识是必要的。例如,Java 5引入的可变长参数(Variable-Length Arguments)允许函数接收不定...

    Pragmatic Unit Testing in Java with JUnit源码

    《Pragmatic Unit Testing in Java with JUnit》是一本专注于Java单元测试实践的书籍,其配套源代码提供了丰富的示例和实践案例,帮助读者深入理解如何有效地使用JUnit进行单元测试。JUnit是Java领域最广泛使用的...

    Junit 单元测试完整案例

    2. `@RunWith(SpringRunner.class)`:这是一个JUnit runner,它使得Spring TestContext Framework可以驱动测试执行。 3. `@SpringBootTest`:这个注解用于启动一个Spring应用上下文,可以指定配置类、web环境等。 ...

    junit4测试源码

    这个"junit4测试源码"可能包含了JUnit4框架的源代码,使得用户能够深入理解其内部工作原理,便于自定义扩展或学习测试驱动开发(TDD)的最佳实践。 首先,JUnit4引入了注解(Annotation)的概念,使得测试类和测试...

    软件测试与junit实践Java测试

    10. **TDD(测试驱动开发)**:JUnit也支持采用TDD(Test-Driven Development)模式,即先写测试,再编写能通过测试的代码,这有助于提高代码质量和可维护性。 总之,JUnit作为Java的主流测试工具,其强大功能和...

    软件测试与Junit实践 pdg

    在实际项目中,应当结合TDD(测试驱动开发)理念,先编写测试再实现功能,确保代码质量从一开始就得到保障。 总之,软件测试是保障软件质量的重要手段,而Junit作为Java的主流单元测试框架,为开发者提供了强大的...

    junit4 单元测试源码

    【标题】"junit4 单元测试源码"涉及的是Java编程中单元测试的重要工具...通过分析和运行这些源码,学习者可以掌握单元测试的基本概念,了解如何编写有效的测试用例,以及如何利用Eclipse的集成环境进行测试驱动开发。

    pragmatic unit testing in java with junit

    《Pragmatic Unit Testing in Java with JUnit》是一本专注于Java单元测试的指南,它深入讲解了如何有效地利用JUnit框架进行测试驱动开发(TDD)。JUnit是Java领域中最广泛使用的单元测试框架,它为开发者提供了编写...

    Junit单元测试指南

    Junit单元测试是Java开发中的一个关键组成部分,它允许开发者对代码进行小规模的验证,确保每个函数或方法按照预期工作。本指南将深入探讨Junit的使用,帮助你掌握如何编写、运行和理解单元测试。 一、Junit简介 ...

    xUnit for Matlab with JUnit-compatible XML output.zip

    使用这个工具,开发者可以在Matlab中实现类似Java的测试驱动开发(TDD)或行为驱动开发(BDD)实践,从而提升代码质量和维护性。同时,通过JUnit兼容的XML输出,可以方便地将Matlab项目集成到更广泛的软件开发流程中。

    Pragmatic Unit Testing In Java With Junit

    - **Al Koscielny**(软件开发者):“如果在我开始进行测试驱动开发时就有这本书就好了。” - **Andrew Thompson**(顾问,Greenbrier & Russel):“虽然我对测试并不陌生,但我仍然在很多方面感到困惑。我认为这...

    Junit 测试

    这对于测试驱动开发(TDD)非常有用,因为它允许我们专注于单个方法的逻辑,而不是依赖其他组件。 在Spring MVC框架中,JUnit同样扮演着关键角色。Spring MVC是Spring框架的一部分,专门用于构建Web应用程序。当...

Global site tag (gtag.js) - Google Analytics