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

发表于:2009-5-22 11:35

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

  1、介绍

  在较早的文章Test Infected: Programmers Love Writing Tests)中,我们描述了如何用一个简单的框架编写可重复的测试;本文则说明这个框架是如何构造的。

  仔细地学习JUnit框架,从中可以看出我们是如何设计这个框架的。我们看到不同层次的JUnit教程,但在本文中,我们希望更清楚地说明问题。弄清JUnit的设计思路是非常有价值的。

  我们先讨论一下Junit的目标,这些目标会在JUnit的每个细小之处得到体现。围绕着JUnit的目标,我们给出Junit框架的设计和实现。我们会用模式和程序实现例子来描述这个设计。我们还会看到,在开发这个框架时,当然还有其它的可选途径。

  2、目标

  什么是JUnit的目标?

  首先,我们回到开发的前提假设。我们假设如果一个程序不能自动测试,那么它就不会工作。但有更多的假设认为,如果开发人员保证程序能工作,那么它就会永远正常工作,与与这个假设相比,我们的假设实在是太保守了。

  从这个观点出发,开发人员编写了代码,并进行了调试,还不能说他的工作完成了,他必须编写测试脚本,证明程序工作正常。然而,每个人都很忙,没有时间去进行测试工作。他们会说,我编写程序代码的时间都很紧,那有时间去写测试代码呢?

  因此,首要的目标就是,构建一个测试框架,在这个框架里,开发人员能编写测试代码。框架要使用熟悉的工具,无需花很多精力就可以掌握。它还要消除不必要的代码,除了必须的测试代码外,消除重复劳动。

  如果仅仅这些是测试要作的,那么你在调试器中写一个表达式就可以实现。但是,测试不仅仅这些。虽然你的程序工作很好,但这不够,因为你不能保证集成后的即使一分钟内你的程序是否还会正常,你更不能保证5年内它还是否正常,那时你已经离开很久了。

  因此,测试的第二个目标就是创建测试,并能保留这些测试,将来它们也是有价值的,其它的人可以执行这些测试,并验证测试结果。有可能的话,还要把不同人的测试收集在一起,一起执行,且不用担心它们之间互相干扰。

  最后,还要能用已有的测试创建新的测试。每次创建新的测试设置或测试钳(test fixture)是很花费代价的,框架能复用测试设置,执行不同的测试。

  3、JUnit设计

  最早,JUnit的设计思路源于"用模式生成架构(Patterns Generate Architectures)"一文。它的思想就是,从0开始设计一个系统,一个一个地应用模式,直到最后构造出这个系统的架构,这样就完成一个系统的设计。我们马上提出要解决的架构问题,用模式来解决这个问题,并说明如何在JUnit中应用这些模式的。

  3.1、从测试用例TestCase开始

  首先我们创建一个对象来表示基础概念:测试用例(TestCase)。测试用例常常就存在于开发人员的

  头脑中,他们用不同的方式实现测试用例:

  •   打印语句
  •   调试表达式
  •   测试脚本

  如何我们想很容易地操纵测试,那么就必须把测试作为对象。开发人员脑海中的测试是模糊的,测试作为对象,就使得测试更具体了,测试就可以长久保留以便将来有用,这是测试框架的目标之一。同时,对象开发人员习惯于对象,因此把测试作为对象就能达到让编写测试代码更具吸引力的目的。

  在这里,命令模式(command)满足我们的需要。该模式把请求封装成对象,即为请求操作生成一个对象,这个对象中有一个“执行(execute)”方法。命令模式中,请求者不是直接调用命令执行者,而是通过一个命令对象去调用执行者,具体说,先为命令请求生成一个命令对象,然后动态地在这个命令对象中设置命令执行者,最后用命令对象的execute方法调用命令执行者。这是TestCase类定义代码:〔此处译者有添加〕

  public abstract class TestCase implements Test {

  ...

  }

  因为我们希望通过继承复用这个类,我门把它定义成“public abstract”。现在我们先不管它实现Test接口,在此时的设计里,你只要把TestCase看成是一个单个的类就行了。

  每个TestCase有一个名字属性,当测试出现故障时,可以用它来识别是哪个测试用例。

  public abstract class TestCase implements Test {

  private final String fName;

  public TestCase(String name) {

  fName= name;

  }

  public abstract void run();

  …

  }

  为了说明JUnit的演化进程,我们用图来表示各个设计阶段的架构。我们用简单的符号,灰色路标符号表明所使用的模式。当这个类在模式中的角色很明显时,就在路标中只指明模式名称;如果这个类在模式中的角色不清晰,则在路标中还注明该类对应的参与模式。这个路标符号避免了混乱,见图1所示。

图1 TestCase类应用了命令模式

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号