`
bruce198
  • 浏览: 235050 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(转)JUnit实战篇 (一)

    博客分类:
  • java
阅读更多

出处:http://blog.csdn.net/kanaima/archive/2003/09/15/14011.aspx

 修订者:黄 凯       <o:p></o:p>

E_mail:hk_sz@163.com<o:p></o:p>

前言<o:p></o:p>

由于现在公司进行Unit Test Case的整理阶段,所以抽空对Junit进行了一下了解,以下是集合了众家所长之精华(考虑的是按我的思路总结的,也许不能完全表达作者的思路,所以在附录中有所有我参考的文章地址,大家不妨去看看原文)。<o:p></o:p>

<o:p> </o:p>

一、测试的概念 <o:p></o:p>

    长期以来,我所接触的软件开发人员很少有人能在开发的过程中进行测试工作。大部分的项目都是在最终验收的时候编写测试文档,有些项目甚至没有测试文档。现在情况有了改变。我们一直提倡UML、RUP、软件工程、CMM,目的只有一个,提高软件编写的质量。举一个极端的例子:如果你是一个超级程序设计师,一个传奇般的人物(你可以一边喝咖啡,一边听着音乐,同时编写这操作系统中关于进程调度的模块,而且两天时间内就完成了!)。我真得承认,有这样的人(那个编写UNIX中的vi编辑器的家伙就是这种人)。然而非常遗憾的是这些神仙们并没有留下任何关于如何修成正果的README,所以我们这些凡人--在同一时间只能将注意力集中到若干点(据科学统计,我并不太相信,一般的人只能同时考虑最多7个左右的问题,高手可以达到12个左右),而不能既纵览全局又了解细节--只能期望于其他的方式来保证我们所编写的软件质量。 <o:p></o:p>

    为了说明我们这些凡人是如何的笨。有一个聪明人提出了软件熵(software entropy)的概念:一个程序从设计很好的状态开始,随着新的功能不断地加入,程序逐渐地失去了原有的结构,最终变成了一团乱麻。你可能会争辩,在这个例子中,设计很好的状态实际上并不好,如果好的话,就不会发生你所说的情况。是的,看来你变聪明了,可惜你还应该注意到两个问题:1)我们不能指望在恐龙纪元(大概是十年前)设计的结构到了现在也能适用吧;2)拥有签字权的客户代表可不理会加入一个新功能是否会对软件的结构有什么影响,即便有影响也是程序设计人员需要考虑的问题。如果你拒绝加入这个你认为致命的新功能,那么你很可能就失去了你的住房贷款和面包(对中国工程师来说也许是米饭或面条,要看你是南方人还是北方人)。 <o:p></o:p>

    另外,需要说明的是我看过的一些讲解测试的书都没有我写的这么有人情味(不好意思...)。我希望看到这篇文章的兄弟姐妹能很容易地接受测试的概念,并付诸实施。所以有些地方写的有些夸张,欢迎对测试有深入理解的兄弟姐妹能体察民情,并不吝赐教。<o:p></o:p>

    好了,我们现在言归正传。要测试,就要明白测试的目的。我认为测试的目的很简单也极具吸引力:写出高质量的软件并解决软件熵这一问题。想象一下,如果你写的软件和Richard Stallman(GNU、FSF的头儿)写的一样有水准的话,是不是很有成就感?如果你一直保持这种高水准,我保证你的薪水也会有所变动。 <o:p></o:p>

    测试也分类,白箱测试、黑箱测试、单元测试、集成测试、功能测试...。我们先不管有多少分类,如何分类。先看那些对我们有用的分类,关于其他的测试,有兴趣的人可参阅其他资料。白箱测试是指在知道被测试的软件如何(How)完成功能和完成什么样(What)的功能的条件下所作的测试。一般是由开发人员完成。因为开发人员最了解自己编写的软件。本文也是以白箱测试为主。黑箱测试则是指在知道被测试的软件完成什么样(What)的功能的条件下所作的测试。一般是由测试人员完成。黑箱测试不是我们的重点。本文主要集中在单元测试上,单元测试是一种白箱测试。目的是验证一个或若干个类是否按所设计的那样正常工作。集成测试则是验证所有的类是否能互相配合,协同完成特定的任务,目前我们暂不关心它。下面我所提到的测试,除非特别说明,一般都是指单元测试。 <o:p></o:p>

    需要强调的是:测试是一个持续的过程。也就是说测试贯穿与开发的整个过程中,单元测试尤其适合于迭代增量式(iterative and incremental)的开发过程。Martin Fowler(有点儿像引用孔夫子的话)甚至认为:“在你不知道如何测试代码之前,就不应该编写程序。而一旦你完成了程序,测试代码也应该完成。除非测试成功,你不能认为你编写出了可以工作的程序。”我并不指望所有的开发人员都能有如此高的觉悟,这种层次也不是一蹴而就的。但我们一旦了解测试的目的和好处,自然会坚持在开发过程中引入测试。因为我们是测试新手,我们也不理会那些复杂的测试原理,先说一说最简单的:测试就是比较预期的结果是否与实际执行的结果一致。如果一致则通过,否则失败。看下面的例子:

  1. //将要被测试的类    
  2. public class Car   
  3. {    
  4.     public int getWheels()    
  5.     {    
  6.         return 4;    
  7.     }    
  8. }     
  9.     
  10. //执行测试的类    
  11. public class testCar    
  12. {    
  13.     public static void main(String[] args)    
  14.     {    
  15.         testCar myTest = new testCar();    
  16.         myTest.testGetWheels();    
  17.     }    
  18.   
  19.     public void testGetWheels ()    
  20.     {    
  21.         int expectedWheels = 5;    
  22.         Car myCar =new Car();    
  23.         if (expectedWheels==myCar.getWheels())    
  24.             System.out.println("test [Car]: getWheels works perfected!");    
  25.         else    
  26.             System.out.println("test [Car]: getWheels DOESN'T work!");    
  27.     }    
  28. }   
  29.   

    如果你立即动手写了上面的代码,你会发现两个问题:<o:p></o:p>

第一,如果你要执行测试的类testCar,你必须必须手工敲入如下命令: <o:p></o:p>

[Windows] D:\>java testCar <o:p></o:p>

[Unix] % java testCar <o:p></o:p>

    即便测试如例示的那样简单,你也有可能不愿在每次测试的时候都敲入上面的命令,而希望在某个集成环境中(IDE)点击一下鼠标就能执行测试。后面的章节会介绍到这些问题。<o:p></o:p>

第二,如果没有一定的规范,测试类的编写将会成为另一个需要定义的标准。没有人希望查看别人是如何设计测试类的。如果每个人都有不同的设计测试类的方法,光维护被测试的类就够烦了,谁还顾得上维护测试类?另外有一点我不想提,但是这个问题太明显了,测试类的代码多于被测试的类!这是否意味这双倍的工作?不!<o:p></o:p>

1) 不论被测试类-Car 的 getWheels 方法如何复杂,测试类-testCar 的testGetWheels 方法只会保持一样的代码量。<o:p></o:p>

2)提高软件的质量并解决软件熵这一问题并不是没有代价的。testCar就是代价。 <o:p></o:p>

    我们目前所能做的就是尽量降低所付出的代价:我们编写的测试代码要能被维护人员容易的读取,我们编写测试代码要有一定的规范。最好IDE工具可以支持这些规范。好了,你所需要的就是JUnit。一个Open Source的项目。用其主页上的话来说就是:“ JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。用于Java开发人员编写单元测试之用。”所谓框架就是Erich Gamma 和 Kent Beck 定下了一些条条框框,你编写的测试代码必须遵循这个条条框框:继承某个类,实现某个接口。其实也就是我们前面所说的规范。好在JUnit目前得到了大多数软件工程师的认可。遵循JUnit我们会得到很多的支持。回归测试就是你不断地对所编写的代码进行测试:编写一些,测试一些,调试一些,然后循环这一过程,你会不断地重复先前的测试,哪怕你正编写其他的类,由于软件熵的存在,你可能在编写第五个类的时候发现,第五个类的某个操作会导致第二个类的测试失败。通过回归测试我们抓住了这条大Bug。 <o:p></o:p>

<o:p> </o:p>

二、JUnit简介及为什么要使用JUint<o:p></o:p>

JUnit就是对程序代码进行单元测试的一种Java框架。通过每次修改程序之后测试代码,程序员就可以保证代码的的少量变动不会破坏整个系统。要不是有Junit这样的自动化测试工具,代码的的反复测试简直会把人累死而且还可能不准确。现在好了,测试过程可以频繁进行而且还是自动的,所以你可以令程序错误降低到最少。它写的是单元测试(Unit Test):软件工程里的白盒测试,就是测试某个类的某个方法的功能。XP 中推崇的 test first design 就是基于以上的技术。  <o:p></o:p>

<o:p> </o:p>

如果你要写一段代码:<o:p></o:p>

1. 先用 junit 写测试,然后再写代码<o:p></o:p>

2. 写完代码,运行测试,测试失败<o:p></o:p>

3. 修改代码,运行测试,直到测试成功 <o:p></o:p>

如果以后对程序进行修改,优化 ( refactoring ),只要再运行测试代码,如果所有的测试都成功,则代码修改完成。 <o:p></o:p>

<o:p> </o:p>

Java 下的 team 开发,一般采用 cvs(版本控制) + ant(项目管理) + junit(集成测试) 的模式:<o:p></o:p>

1. 每天早上上班,每个开发人员从 cvs server 获取一个整个项目的工作拷贝;<o:p></o:p>

2. 拿到自己的任务,先用 junit 写今天的任务的测试代码;<o:p></o:p>

3. 然后写今天任务的代码,运行测试,直到测试通过,任务完成;<o:p></o:p>

4. 在下班前一两个小时,各个开发人员把任务提交到 cvs server;<o:p></o:p>

5. 然后由主管对整个项目运行自动测试,哪个测试出错,就找相关人员修改,直到所有测试通过。下班...<o:p></o:p>

<o:p> </o:p>

先写测试,再写代码的好处: <o:p></o:p>

从技术上强制你先考虑一个类的功能,也就是这个类提供给外部的接口,而不至于太早陷入它的细节。这是面向对象提倡的一种设计原则。好的测试其实就是一个好的文档,这个类使用者往往可以通过查看这个类的测试代码了解它的功能。特别的,如果你拿到别人的一个程序,对他写测试是最好的了解这个程序的功能的方法。 xp的原则是 make it simple,不是很推荐另外写文档,因为项目在开发过程中往往处于变动中,如果在早期写文档,以后代码变动后还得同步文档,多了一个工作,而且由于项目时间紧往往文档写的不全或与代码不一致,与其这样,不如不写。而如果在项目结束后再写文档,开发人员往往已经忘记当时写代码时的种种考虑,况且有下一个项目的压力,管理人员也不愿意再为旧的项目写文档,导致以后维护的问题。没有人能保证需求不变动,以往项目往往对需求的变动大为头疼,害怕这个改动会带来其他地方的错误。为此,除了设计好的结构以分割项目外(松耦合),但如果有了测试,并已经建立了一个好的测试框架,对于需求的变动,修改完代码后,只要重新运行测试代码,如果测试通过,也就保证了修改的成功,如果测试中出现错误,也会马上发现错在哪里,修改相应的部分,再运行测试,直至测试完全通过。 <o:p></o:p>

<o:p> </o:p>

软件公司里往往存在开发部门和测试部门之间的矛盾:由于开发和测试分为两个部门,多了一层沟通的成本和时间,沟通往往会产生错误的发生。而且极易形成一个怪圈:开发人员为了赶任务,写了烂烂的代码,就把它扔给测试人员,然后写其他的任务,测试当然是失败的,又把代码拿回去重写,而且在国内往往一个软件公司技术最差的部门就是测试部门(好的人都跑去写代码了),测试就成了一个很头疼的问题。这种怪圈的根源是责任不清,根据 xp 中的规定:写这个代码的人必须为自己的代码写测试,而且只有测试通过,才算完成这个任务(这里的测试包括所有的测试,如果测试时发现由于你的程序导致别的模块的测试失败,你有责任通知相关人员修改直至集成测试通过),这样就可以避免这类问题的发生。<o:p></o:p>

<o:p> </o:p>

参考

JUnit实施        <o:p></o:p>

作者:eric    原址:http://www.neweasier.com/article/2002-08-07/1028723459.html<o:p></o:p>

怎样使用Junit Framework进行单元测试的编写     <o:p></o:p>

作者:cinc     原址:http://www.chinaunix.net/bbsjh/14/546.html<o:p></o:p>

主要是引用了cinc的评论,至于申文波先生的《怎样使用Junit Framework进行单元测试的编写》原文我建议大家有时间看一下,写得很好,我这里没有整合进来。<o:p></o:p>

创建Junit测试案例<o:p></o:p>

作者: BUILDER.COM     原址:http://www.zdnet.com.cn/developer/code/story/0,2000081534,39033729,00.htm

分享到:
评论

相关推荐

    junit实战第二版

    《JUnit实战第二版》是一本深入探讨Java单元测试框架JUnit的专著,旨在帮助开发者熟练掌握和运用JUnit进行高效、可靠的软件测试。JUnit是Java领域中最广泛使用的单元测试框架之一,它为开发者提供了编写和执行可重复...

    junit_4.10.rar

    本篇文章将聚焦于JUnit 4.10这一重要的里程碑版本,探讨它引入的新特性以及如何在实际开发中充分利用这些特性进行高效测试。 一、JUnit简介 JUnit是基于Java的开源测试框架,最初由Ernst Meyer和Kent Beck开发,其...

    JUnit知识点滴集合笔记

    JUnit知识点滴集合笔记,这个包里面包括了好几篇文档,一定会让你对JUNIT有一个全新的认识。 JUnit 4 抢先看.doc JUnit in java 真正的测试用例实战.doc JUnit起步.doc junit实现过程.doc JUnit中如何测试异常.doc ...

    junit4入门

    这篇教程将带你走进Junit4的世界,深入理解其核心概念和使用方法。 1. **基本概念** Junit4的核心概念包括测试类、测试方法、断言和注解。测试类通常与待测试的生产代码相独立,其中包含多个测试方法。测试方法是...

    Junit-4.12.zip

    本篇文章将聚焦于JUnit 4.12版本,通过源码解析和实际应用,带你深入理解和掌握这个强大的测试工具。 一、JUnit简介 JUnit是Java开发中的一个开源测试框架,它为编写可重复运行的测试提供了简洁的API。JUnit 4.12是...

    junit总结

    三、JUnit实战应用 1. 单元测试:通过JUnit,开发者可以对单个方法或小块代码进行测试,确保其在各种情况下都能正常工作。这有助于早期发现和修复问题,提高代码质量。 2. 回归测试:当代码发生修改后,可以重新...

    JUnit -- 分析

    10. **实战示例**:结合实际项目,展示如何利用JUnit进行单元测试,解决实际问题。 而"junit.uml"这个文件名称,很可能包含了一张关于JUnit类图或组件图的统一建模语言(UML)表示,这有助于理解JUnit的架构和组件...

    JUnit入门笔记~

    这篇入门笔记将带你深入了解JUnit的基本概念、使用方法以及其在实际开发中的应用。 **一、JUnit简介** JUnit是一个开源的、基于Java的测试框架,它简化了对代码进行单元测试的过程。通过JUnit,开发者可以快速地...

    junit4-r4.12

    本篇文章将深入探讨Junit4-r4.12的核心概念、功能以及实际应用。 1. **单元测试**: 单元测试是对软件中的最小可测试单元进行检查和验证的过程。在Java中,这些单元通常是个体的方法或类。Junit4-r4.12 提供了简洁...

    Junit测试demo

    本篇将深入探讨"Junit测试demo",旨在帮助您理解如何利用JUnit进行有效的单元测试。 一、JUnit简介 JUnit是XUnit家族的一员,由Ernst von Brühl和Kent Beck在2000年创建。它提供了断言机制、测试注解、测试套件和...

    junit-4.8.2.rar

    本篇文章将深入探讨JUnit 4.8.2的核心特性、使用方法以及它在软件开发中的重要性。 一、JUnit概述 JUnit是一个开源的测试框架,由Ernst Klemens和Kent Beck在2000年推出,基于xUnit测试框架模型。它的设计目标是...

    [原]深入JUnit4.x

    这篇深入的文章将围绕JUnit4.x的核心概念、功能以及如何有效地利用它进行测试展开讨论。 1. **注解驱动的测试**: JUnit4.x弃用了JUnit3.x中的`setUp()`和`tearDown()`方法,转而采用注解的方式进行测试前后的准备...

    Spring Web Service 实战篇(1)

    本实战篇将深入探讨Spring Web Service的核心概念、架构设计以及实现步骤,旨在帮助开发者熟练掌握这一强大的工具。 首先,Spring Web Service是Spring框架的一个扩展,它允许开发人员创建基于WSDL(Web Services ...

    简单的银行转帐系统(含JUNIT测试)

    【描述】提及的博文链接指向了ITEYE博客上的一篇文章,该文章详细介绍了该项目的实现过程。博主可能分享了代码结构、主要类的功能、以及如何利用JUNIT进行单元测试以确保代码的正确性。通常,这样的系统会包括账户类...

    9.Jenkins持续集成插件实战篇

    《Jenkins持续集成插件实战篇》主要涵盖了 Jenkins 在软件开发过程中的持续集成实践,它是一种强大的自动化工具,尤其在持续集成和持续部署(CI/CD)领域具有广泛的应用。以下将详细介绍 Jenkins 及其在实际工作中的...

    junit.rar_Java编程_Java_

    "JUnit实战篇.mht"和"JUnit实战篇1.mht"很可能是两篇深入的实战文章,涵盖了在真实项目中如何运用JUnit进行测试驱动开发(TDD)或者行为驱动开发(BDD),可能包括了如何编写集成测试、如何进行测试隔离、以及如何...

    J2EE复习积累(三)-JUnit4概述(三)

    本篇文章将深入探讨JUnit4的核心概念、功能和使用方法。 **一、JUnit4简介** JUnit4是对JUnit3的重大升级,引入了注解(Annotations)来简化测试代码,使得测试类更加简洁。此外,JUnit4允许用户自定义测试规则,...

    maven 实战 所有源代码

    本篇文章将深入探讨"Maven实战"中涉及的所有源代码,帮助开发者更深入地理解和运用Maven。 ### 一、Maven的项目结构 在Maven中,项目的标准目录结构(也称为"Maven目录布局")至关重要。源代码文件通常分布在以下...

    Maven实战(入门篇)

    ### Maven实战(入门篇):全面解析Maven的构建、依赖与项目信息管理 #### Maven:构建、依赖与信息管理的全能工具 Maven,源自于希伯来语中的“Baal ha-ne'emânîm”,意指知识的积累、专家或是内行,是一个由...

Global site tag (gtag.js) - Google Analytics