`
flash7783
  • 浏览: 308377 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

JUnit及其相关的单元测试技术

阅读更多

在实际的工作中,很多项目都没有写单元测试用例。写单元测试用例常常是程序员十分厌倦的一个项目活动,很多人觉得没有必要、浪费时间。所有这些都是因为没有认识到测试的重要性:测试能够使我们尽量早的发现程序的bug,一个bug被隐藏的时间越长,修复这个bug的代价就越大。在《快速软件开发》一书中已引用了大量的研究数据指出:最后才修改一个bug的代价是在bug产生时修改它的代价的10倍。在现代软件开发过程中,不管是xp还是rup都是十分重视单元测试,已经把单元测试作为贯穿整个开发周期的一项重要的开发活动。单元测试如此重要,那么怎样写好单元测试用例呢?这就需要了解Junit及其相关的测试工具了。

  1. Junit简介:

  1.1 内容摘要

  Junit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regressiontestingframework),供Java开发人员编写单元测试之用。Junit测试是程序员测试,即所谓白盒测试。下面我们以一个简单的例子来介绍如何使用Junit4同Junit3编写测试用例:

  先写个简单的被测试类:

  public Class XXXX{

  public String hello(){

  return hello;

  }

  }

  对于这个类的用junit3编写测试用例:

  import junit.framework.TestCase;

  public Class XXXXTest extends TestCase{

  public void testHello(){

  asssertEqual(new XXXX().Hello(),hello);

  }

  }

  用junit4编写测试用例:

  import static org.junit.framework.assertEqual;

  import org.junit.Test;

  public Class XXXXTest{

  @Test

  public void helloTest(){

  asssertEqual(new XXXX().Hello(),hello);

  }

  }

  从上面例子我们对Junit3和Junit4有了一个初步的印象,下面我们重点介绍Junit4与Junit3的主要区别。

  1.2 Junit4与Junit3的主要区别

  1.2.1 Junit4引入了java 5.0的注释技术:

  这两个版本最大的区别在JUnit3.x中测试必须继承TestCase,并且每个方法名必须以test开头。比如:testMethod1()而在JUnit4.x中不必继承TestCase,采用了注解的方式。只要在测试的方法上加上注解@Test即可,从而不必再遵循以前的一些显式约定和反射定位测试;在JUnit4.x中如果继承了TestCase,注解就不起作用了。并且有很重要的一点就是在JUnit4.x中继承了TestCase后,在OutLine视图中测试单个方法时,结果整个类都run了。还有一点就是,在3.x中需要实现setUp和tearDown方法,而在4.x中无需这样,可以自定义需要在测试前和测试后的方法,在方法前加上@before,@after就可以了。所以在JUnit4.x不必继承TestCase用注解即可对单个方法进行测试。

  1.2.2 JUnit4引入了一个JUnit3中没有的新特性——类范围的 setUp() 和tearDown() 方法。

  任何用 @BeforeClass 注释的方法都将在该类中的测试方法运行之前刚好运行一次,而任何用@AfterClass注释的方法都将在该类中的所有测试都运行之后刚好运行一次。

  1.2.3 异常测试:

  异常测试是Junit4中的最大改进。Junit3的异常测试是在抛出异常的代码中放入try块,然后在try块的末尾加入一个fail()语句。

  例如该方法测试一个被零除抛出一个ArithmeticException:

  该方法不仅难看,而且试图挑战代码覆盖工具,因为不管测试是否通过还是失败,总有一些代码不被执行。在JUni4中,可以编写抛出异常的代码,并使用注释来声明该异常是预期的:

  如果没有异常抛出或者抛出一个不同的异常,那么测试就将失败。

  1.2.4 JUnit4添加了两个比较数组的assert() 方法:

  public static void assertEquals(Object[] expected,Object[]actual)

  public static void assertEquals(String message, Object[]expected,Object[] actual)

  这两个方法以最直接的方式比较数组:如果数组长度相同,且每个对应的元素相同,则两个数组相等,否则不相等。数组为空的情况也作了考虑。

  1.3 JUnit 4 常用的几个annotation 介绍

  ★ @Before:初始化方法,在任何一个测试执行之前必须执行的代码;

  ★ @After:释放资源,在任何测试执行之后需要进行的收尾工作;

  ★@Test:测试方法,表明这是一个测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出一个异常。至于方法内该写些什么,那就要看你需要测试些什么了;在这里可以测试期望异常和超时时间,如@Test(timeout=100),我们给测试函数设定一个执行时间,超过了这个时间(100毫秒),它们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些Bug了。

  ★@Ignore:忽略的测试方法,标注的含义就是“某些方法尚未完成,暂不参与此次测试”;这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。

  ★ @BeforeClass:针对所有测试,只执行一次,且必须为static void;

  ★ @AfterClass:针对所有测试,只执行一次,且必须为static void;

  所以一个Junit 4 的单元测试用例执行顺序为:@BeforeClass –> @Before –>@Test–> @After –> @AfterClass;每一个测试方法的调用顺序为:@Before –>@Test–> @After。

  如下面例子:

  import static org.junit.Assert.*; importorg.junit.After;importorg.junit.AfterClass;importorg.junit.Before;importorg.junit.BeforeClass;importorg.junit.Ignore;importorg.junit.Test; public class JUnit4Test{

  @Before

  public void before() {

  System.out.println(@Before);

  }

  @Test

  public void test() {

  System.out.println(@Test);

  assertEquals(5 + 5, 10);

  }

  @Ignore

  @Test

  public void testIgnore() {

  System.out.println(@Ignore);

  }

  @Test(timeout = 50)

  public void testTimeout() {

  System.out.println(@Test(timeout = 50));

  assertEquals(5 + 5, 10);

  }

  @Test(expected = ArithmeticException.class)

  public void testExpected() {

  System.out.println(@Test(expected = Exception.class));

  throw new ArithmeticException();

  }

  @After

  public void after() {

  System.out.println(@After);

  }

  @BeforeClass

  public static void beforeClass() {

  System.out.println(@BeforeClass);

  };

  @AfterClass

  public static void afterClass() {

  System.out.println(@AfterClass);

  };

  };

  右击测试类,选择Junit运行……

  输出结果如下:

  @BeforeClass

  @Before

  @Test(timeout = 50)

  @After

  @Before

  @Test(expected = Exception.class)

  @After

  @Before

  @Test

  @After

  @AfterClass

  在eclipse中junit运行结果视图中可以看到testIgnore是被忽略的,没有执行;还有其中有一个方法运行报错。

  2. 使用HttpUnit进行Web应用测试:

  上面我们介绍Junit是对应用程序代码的片段做测试,那么如何对Web应用进行测试呢?这就需要我们了解HttpUnit了。

  2.1 什么是HttpUnit:

  HttpUnit是SourceForge下面的一个开源项目,它是基于Junit的一个测试框架,主要关注于测试Web应用,解决使用Junit框架无法对远程Web内容进行测试的弊端。HttpUnit通过模拟浏览器的行为,处理页面框架(frames),cookies页面跳转(redirects)等。通过HttpUnit提供的功能,你可以和服务器端进行信息交互,将返回的网页内容作为普通文本、XMLDom对象或者是作为链接、页面框架、图像、表单、表格等的集合进行处理。HttpUnit还提供了一个模拟Servlet容器,让你可以不需要发布Servlet,就可以对Servlet的内部代码进行测试。

  2.2 如何使用HttpUnit:

  到HttpUnit的主页http://httpunit.sourceforge.net下载最新的包文件,解压后将%httpunit_home%/lib/*.jar;%httpunit_home%/jars/*.jar加入到Eclipse工程的Javabuild Path变量中。

  2.3 如何使用HttpUnit和Junit编写Web应用的测试用例:

  在HttpUnit框架中,WebConversation类是最重要的类,它用于模拟浏览器的行为,WebRequest类用于模仿客户请求,通过它可以向服务器发送信息,WebResponse类用于模拟浏览器获取服务器端的响应信息。

  下面我们用HttpUnit编写一个测试用例,测试在百度里面搜索“诚毅软件”,搜索结果里面有没有包含“我们努力使事情更简单”的内容。

  在Eclipse中运行结果中可见在百度里面搜索“诚毅软件”,搜索结果里面有包含“我们努力使事情更简单”的内容。

  3. 使用EclEmma进行覆盖测试

  3.1 什么是覆盖测试

  上面我们介绍了如何用junit和HttpUnit编写单元测试用例,那如何确定我们编写的单元测试用例能不能完整地测试我们的代码呢?这就需要看看我们的单元测试用例对我们代码的覆盖测试率了。覆盖测试是衡量测试质量的一个重要指标。在对一个软件产品进行了单元测试、组装测试、集成测试以及接受测试等繁多的测试之后,我们能不能就此对软件的质量产生一定的信心呢?这就需要我们对测试的质量进行考察。如果测试仅覆盖了代码的一小部分,那么不管我们写了多少测试用例,我们也不能相信软件质量是有保证的。相反,如果测试覆盖到了软件的绝大部分代码,我们就能对软件的质量有一个合理的信心。

  3.2 如何使用EclEmma进行覆盖测试

  EclEmm是一个帮助开发人员考察测试覆盖率的优秀的 Eclipse开源插件,EclEmma为用户提供图形界面以及对集成开发环境的支持,安装 EclEmma 插件的过程和大部分Eclipse插件相同,我们既可以通过 Eclipse 标准的 Update 机制来远程安装EclEmma插件,也可以从站点http://sourceforge.net/projects/eclemma/下载 zip文件并解压到eclipse 所在的目录中。安装完成并重新启动 Eclipse 之后,工具栏上应该出现一个新的按钮。

  下面我们用EclEmma运行我们上面Junit的例子,看看测试覆盖率是多少,点击这个新的按钮,运行Junit Test。

  可以看到EclEmma用不同的色彩标示了源代码的测试情况。其中,绿色的行表示该行代码被完整的执行,红色部分表示该行代码根本没有被执行,而黄色的行表明该行代码部分被执行。可见我们的测试用例对逻辑类LogicClass的测试达到了100%。

  有时候想一次运行中覆盖所有的代码通常比较困难,如果能把多次测试的覆盖数据综合起来进行察看,那么我们就能更方便地掌握多次测试的测试效果。EclEmma提供了这样的功能。通过Coverage视图的工具按钮来结合多次覆盖测试的结果。在弹出框中点击OK按钮,就可以看到多次测试对代码的测试覆盖率了。

  4. 如何使用Ant批量运行junit单元测试用例并生成测试报告

  我们编写完单元测试用例以后,我们就可以运行单元测试用例来检查我们的代码有没有bug,以后如果代码发生改变,我们就可以运行单元测试用例来检查我们的修改有没有带进新的bug。但如果每个测试用例都要手工运行那就比较繁琐了,下面我们介绍如何使用ant进行批量测试和生成测试报告。

  4.1 什么是ant:

  Ant是一个类似make的、用java实现的构建工具,项目的构建、包装和发布过程中几乎每一件事都可以由Ant的任务来处理。Ant凭借出色的易用性、平台无关性以及对项目自动测试和自动部署的支持,已成为众多项目构建过程中不可或缺的独立工具,并已经成为事实上的标准。

  4.2 如何使用ant批量运行junit测试用例并生成测试报告:

  随着项目的进展和项目的规模在不断的膨胀,为了保证项目的质量,有计划的执行全面的单元测试是非常有必要的。利用Ant集成Junit可以通过配置批量运行所指定的测试用例并生成测试报告,可以让开发人员及时发现代码中所隐藏的bug,及时进行修改,极大的提高工作效率,从某种意义上做到持续集成。

  Ant 内置了对 JUnit 的支持,它提供了两个 Task:junit 和 junitreport,分别用于执行JUnit单元测试和生成测试结果报告。使用这两个 Task编写构建脚本,可以很简单的完成批量运行单元测试并生成测试报告的任务。

  首先把junit的包加载到ant的编译目录下:打开 Eclipse 的window菜单,选择reference选项界面,选择Ant-> Runtime 选项,将 Junit 4.* 的 JAR 文件添加到 Classpath Tab 页中的GlobalEntries 设置项里。还有记得检查一下 Ant Home Entries 设置项中的 Ant 版本是否在1.7.0之上,如果不是请替换为最新版本的 AntJAR文件,Eclipse3.2内置的ant版本是1.65,eclipse3.4内置的ant版本是1.70,所以如果我们使用的junit版本是4以上的,最好用eclipse3.4。

  接下来是编写 Ant 构建脚本 build.xml。虽然这个过程稍嫌繁琐,但这是一件一劳永逸的事情。

  把此build.xml文件放到工程的根目录下,修改test属性的值为我们要运行的单元测试用例的包路径名,如果为空默认运行工程所有的单元测试,在Eclipse下打开此build.xml文件,在右边的outline视图下右击ant的junit任务,选择RunAsAntBuild,就可以运行此ant文件的junit任务,然后我们就可以在Eclipse的控制台上看到Ant任务的执行信息,任务执行完后,就会在工程的report目录下的“framework-${DSTAMP}-${TSTAMP}”临时文件夹下生成html类型的测试报告。

  

分享到:
评论

相关推荐

    JAVA单元测试JUnit

    ### JAVA单元测试JUnit的核心知识点详解 #### 一、JUnit概览与重要性 JUnit作为一款卓越的Java单元测试...对于开发者而言,深入理解JUnit及其背后的设计哲学,不仅能够提升测试技能,还能深化对软件工程原理的认识。

    Junit单元测试Junit单元测试Junit单元测试

    ### JUnit单元测试详解 #### 一、引言 随着软件工程的发展,单元测试的重要性日益...在未来,随着技术的不断进步,单元测试的重要性还将进一步提升,掌握JUnit等单元测试框架的使用将是每一个程序员必备的技能之一。

    软件测试winrunner loadrunner junit

    这三款工具在软件测试领域中各有所长,WinRunner适用于功能测试,LoadRunner擅长性能测试,而JUnit则是单元测试的首选。它们的结合使用,能够覆盖从代码质量验证到系统整体性能评估的全方位测试需求。在实际工作中,...

    对基于Junit的测试代码自动化生成的研究

    标题中的“对基于Junit的测试代码自动化生成的研究”表明,这个主题主要关注的是如何利用Junit这个单元测试框架来实现测试代码的自动化生成。Junit是Java编程语言中最常用的测试框架之一,它使得开发者能够方便地...

    junit单元测试

    ### JUnit单元测试知识点详解...通过学习和掌握JUnit的不同版本及其特性,开发者可以更好地进行单元测试,确保软件的稳定性和可靠性。同时,结合模拟对象、覆盖测试和持续集成等技术,可以进一步提升测试的效果和效率。

    单元测试ppt

    单元测试是软件开发过程中的一个关键环节,它主要关注的是程序的最小可测试单元,如函数、方法或类。...了解并熟练掌握单元测试及其相关的测试技术和过程,对于提升软件开发的效率和质量至关重要。

    spring3 + mybatis3 + junit4 可运行项目示例

    这个项目的核心是利用Spring作为应用的ioc(Inversion of Control,控制反转)和aop(Aspect Oriented Programming,面向切面编程)容器,MyBatis作为持久层框架,以及JUnit4用于进行单元测试和集成测试。...

    Junit代码覆盖与自动化测试

    其中,JUnit作为Java领域中最受欢迎的单元测试框架之一,在提升代码质量和实现自动化测试方面发挥着重要作用。本文将详细介绍如何通过JUnit进行代码覆盖与自动化测试,以及这一过程中的关键步骤。 #### 二、JUnit...

    软件测试与Junit实践__0

    Junit作为Java编程语言中最广泛使用的单元测试框架,对于软件测试起到了至关重要的作用。本文将深入探讨软件测试的基本概念、Junit的使用方法及其在实际项目中的实践应用。 软件测试是验证和确认软件是否满足既定...

    软件单元测试计划模板

    以下是对【标题】“软件单元测试计划模板”及其【描述】中各部分的详细解释: 1. **介绍** - **目的**:明确单元测试的目标,通常是为了尽早发现并修复代码中的错误,提高软件质量和可维护性。此外,单元测试也有...

    springboot +tkmybatis + generator+单元测试.zip

    JUnit 是Java中最流行的单元测试框架,它允许开发者编写和执行针对代码单元的测试用例,确保代码的质量和功能正确性。在SpringBoot项目中,JUnit与Mockito等工具结合,可以有效地对服务层、DAO层进行单元测试。 6....

    junit3.8.1.rar

    以下是对JUnit 3.8.1及其相关知识点的详细解释: 1. **单元测试**:单元测试是对软件中的最小可测试单元进行检查和验证,如函数、方法或类。它的目标是确保代码的每个部分都能按预期工作,独立于其他部分。 2. **...

    Android上的单元测试

    综上所述,虽然Android平台并未完全集成JUnit框架,但开发者仍然可以借助JUnit进行非UI相关的单元测试。对于涉及Android特有API或组件的测试,则需要利用Android内置的测试框架和支持,特别是`junit.framework`包中...

    JUnit的框架设计及其使用的设计模式

    JUnit是Java编程语言中最常用的单元测试框架之一,它在软件开发过程中起着至关重要的作用,确保代码的质量和可维护性。这个框架的设计基于一系列高效的设计模式,这些模式不仅提升了JUnit的灵活性,还使得开发者能够...

    spring junit

    总结来说,“spring junit”涉及到的是在Spring框架下使用JUnit进行单元测试的方法和技术,这包括如何配置测试环境、注入依赖、模拟对象、管理事务等,这些都是保证代码质量和可维护性不可或缺的实践。而与MyBatis的...

    单元测试的艺术 源代码

    《单元测试的艺术》是Roy Osherove所著的一本经典著作,主要探讨了软件开发中的单元测试技术及其重要性。源代码的提供使得读者能够更深入地理解和实践书中的理论知识。下面,我们将深入探讨单元测试的核心概念、相关...

    基于JUnit4的关于个人所得税计算的等价类与边界值分析黑盒测试和路径覆盖白盒测试

    JUnit4是Java编程语言中广泛使用的单元测试框架,它提供了一套方便的断言方法和注解,帮助开发者编写和运行测试用例。在本实验中,我们可以使用JUnit4的@Test注解定义测试方法,使用assert系列方法检查预期结果,...

Global site tag (gtag.js) - Google Analytics