转载:JUNIT实施(3)

来源:互联网 发布:iptables添加端口模块 编辑:程序博客网 时间:2024/04/29 23:55
//执行测试的类(JUnit版)

import junit.framework.*;

public class testCar extends TestCase {

protected int expectedWheels;

protected Car myCar;

public testCar(String name) {

super(name);

}

protected void setUp() {

expectedWheels = 4;

myCar = new Car();

}

public static Test suite() {

/*

* the type safe way

*

TestSuite suite= new TestSuite();

suite.addTest(

new testCar("Car.getWheels") {

protected void runTest() { testGetWheels(); }

}

);

return suite;

*/

/*

* the dynamic way

*/

return new TestSuite(testCar.class);

}

public void testGetWheels() {

assertEquals(expectedWheels, myCar.getWheels());

}

}

改版后的testCar已经面目全非。先让我们了解这些改动都是

什么含义,再看如何执行这个测试。

1>import语句,引入JUnit的类。(没问题吧)

2>继承 TestCase 。可以暂时将一个TestCase看作是对某个

类进行测试的方法的集合。详细介绍请参看JUnit资料

3>setUp()设定了进行初始化的任务。我们以后会看到setUp

会有特别的用处。

4>testGetWheeels()对预期的值和myCar.getWheels()返回的

值进行比较,并打印比较的结果。assertEquals是junit.framework.

Assert中所定义的方法,junit.framework.TestCase继承了junit.

framework.Assert。

5>suite()是一个很特殊的静态方法。JUnit的TestRunner会调

用suite方法来确定有多少个测试可以执行。上面的例子显示了两种

方法:静态的方法是构造一个内部类,并利用构造函数给该测试命

名(test

name, 如 Car.getWheels ),其覆盖的runTest()方法,指明了

该测试需要执行那些方法--testGetWheels()。动态的方法是利用

内省(reflection

)来实现runTest(),找出需要执行那些测试。此时测试的名字

即是测试方法(test method,如testGetWheels)的名字。JUnit会

自动找出并调用该类的测试方法。

6>将TestSuite看作是包裹测试的一个容器。如果将测试比作叶

子节点的话,TestSuite就是分支节点。实际上TestCase,TestSuite

以及TestSuite组成了一个composite

Pattern。 JUnit的文档中有一篇专门讲解如何使用Pattern构造

Junit框架。有兴趣的朋友可以查看JUnit资料。

如何运行该测试呢?手工的方法是键入如下命令:



[Windows] d:>java junit.textui.TestRunner testCar

[Unix] % java junit.textui.TestRunner testCar

别担心你要敲的字符量,以后在IDE中,只要点几下鼠标就成了。

运行结果应该如下所示,表明执行了一个测试,并通过了测试:



.

Time: 0

OK (1 tests)

如果我们将Car.getWheels()中返回的的值修改为3,模拟出错的情

形,则会得到如下结果:



.F

Time: 0

There was 1 failure:

1) testGetWheels(testCar)junit.framework.AssertionFailedError:

expected:<4> but was:&lt;3&gt;

at testCar.testGetWheels(testCar.java:37)

FAILURES!!!

Tests run: 1, Failures: 1, Errors: 0

注意:Time上的小点表示测试个数,如果测试通过则显示OK。否则

在小点的后边标上F,表示该测试失败。注意,在模拟出错的测试中,

我们会得到详细的测试报告“expected:<4>

but was:<3>”,这足以告诉我们问题发生在何处。下面就是你调

试,测试,调试,测试...的过程,直至得到期望的结果。

Design by Contract(这句话我没法翻译)

Design by Contract本是Bertrand Meyer(Eiffel语言的创始人)

开发的一种设计技术。我发现在JUnit中使用Design

by Contract会带来意想不到的效果。Design by Contract的核心是

断言(assersion)。断言是一个布尔语句,该语句不能为假,如果为假

,则表明出现了一个bug。Design

by Contract使用三种断言:前置条件(pre-conditions)、后置条

件(post-conditions)和不变式(invariants)这里不打算详细讨论Design

by Contract的细节,而是希望其在测试中能发挥其作用。

前置条件在执行测试之前可以用于判断是否允许进入测试,即进入

测试的条件。如 expectedWheels > 0, myCar != null。后置条件用于在

测试执行后判断测试的结果是否正确。如

expectedWheels==myCar.getWheels()。而不变式在判断交

易(Transaction)的一致性(consistency)方面尤为有用。我希

望JUnit可以将Design

by Contract作为未来版本的一个增强。

Refactoring(这句话我依然没法翻译)

Refactoring本来与测试没有直接的联系,而是与软件熵有

关,但既然我们说测试能解决软件熵问题,我们也就必须说出解

决之道。(仅仅进行测试只能发现软件熵,Refactoring则可解决

软件熵带来的问题。)软件熵引出了一个问题:是否需要重新设

计整个软件的结构?理论上应该如此,但现实不允许我们这么做

。这或者是由于时间的原因,或者是由于费用的原因。重新设计

个软件的结构会给我们带来短期的痛苦。而不停地给软件打补丁甚

至是补丁的补丁则会给我们带来长期的痛苦。(不管怎样,我们总

处于水深火热之中)

Refactoring是一个术语,用于描述一种技术,利用这种技术

我们可以免于重构整个软件所带来的短期痛苦。当你refactor时,

你并不改变程序的功能,而是改变程序内部的结构,使其更易理解

和使用。如:该变一个方法的名字,将一个成员变量从一个类移到

另一个类,将两个类似方法抽象到父类中。所作的每一个步都很小

,然而1-2个小时的Refactoring工作可以使你的程序结构更适合目

前的情况。Refactoring有一些规则:

1> 不要在加入新功能的同时refactor已有的代码。在这两者间

要有一个清晰的界限。如每天早上1-2个小时的Refactoring,其余

时间添加新的功能。

2> 在你开始Refactoring前,和Refactoring后都要保证测试能顺

利通过。否则Refactoring没有任何意义。

3> 进行小的Refactoring,大的就不是Refactoring了。如果你打

算重构整个软件,就没有必要Refactoring了。

只有在添加新功能和调试bug时才又必要Refactoring。不要等到

交付软件的最后关头才Refactoring。那样和打补丁的区别不大。

Refactoring

用在回归测试中也能显示其威力。要明白,我不反对打补丁,但

要记住打补丁是应该最后使用的必杀绝招。(打补丁也需要很高的技

术,详情参看微软网站)

IDE对JUnit的支持

目前支持JUnit的Java IDE 包括

IDE | 方式 | (1-5,满分5)

Forte for Java 3.0 Enterprise Edition | plug-in | 3

JBuilder 6 Enterprise Edition | integrated with IDE | 4

Visual Age for Java | support | N/A

在IDE中如何使用JUnit,是非常具体的事情。不同的IDE有不同的使用

方法。一旦理解了JUnit的本质,使用起来就十分容易了。所以我们不

依赖于具体的IDE,而是集中精力讲述如何利用JUnit编写单元测试代码。

心急的人可参看资料。

JUnit简介

既然我们已经对JUnit有了一个大致的了解,我希望能给大家提供一

个稍微正式一些的编写JUnit测试文档的手册,明白其中的一些关键术语

和概念。但我要声明的是这并不是一本完全的手册,只能认为是一本入

门手册。同其他OpenSource的软件有同样的问题,JUnit的文档并没有商

业软件文档的那种有规则,简洁和完全。由开发人员编写的文档总是说不

太清楚问题,全整的文档需要参考&quot;官方&quot;指南,API手册,邮

件讨论组的邮件,甚至包括源代码中及相关的注释。
 
原创粉丝点击