作者:
Keld H. Hansen
一、
介绍
二、
进入junit的天堂
三、
Round类
四、分析并获取测试用例
测试是件非常容易犯困的工作。测试他人写的程序时,感觉更加夸张。如果你同样为一名开发人员,那可能就升级为一种煎熬。作为开发人员,我们天生热衷于创造。但转念想想,为什么不自己创造一个程序来测试其它程序甚至其本身呢?诞生于自动化测试后的这种思想,正是本文主题所在。
自动化单元测试(一般来说,一个类为一个单元)其实并不是件新鲜事。多年前我们应用于大型机的一些测试方法,站在自动化单元测试的角度,它们依然有效。自动化单元测试与随机测试有着以下的不同:
一、使得在程序修改后,只对进行修改的部分重新测试的工作(常被称为“回归测试”),变得非常容易。
二、拥有一个强大的测试构架,当你编译代码或者布署应用时,能自动进行实际有效的测试。
正确的使用单元测试,可以帮助我们提高编写程序的效率,同时提升代码的质量。只有当确信单元测试是程序编写过程中重要的环节,才会被促使去设计经得起测试的代码。实际上,将注意力集中在接口与类所要实现的行为上,先编写测试代码,然后才编写程序代码,已经成为当今的趋势。不过,本文皆在简单地展示单元测试,所以被用来测试的代码实际是已经存在的。
高尔夫运动
想以生活中的一个小例子来描述自动化测试的整个过程。所以,让我们打会儿高尔夫吧!案例为:我们需要编写一个程序来记录一场高尔夫的分数。聪明过人的你,很快知道需要以下两个类:
1、球场(Course)-有以下属性:球场名称;每个洞的标准杆数
2、一场球(Round)(每一位球手的得分)-有以下属性:球手的名称(球手其实可以作为一个对象,但为了简单,故没有那样做);球场;各个洞的杆数
我们一定都想清楚地知道球场上每一位球手的表现,那么定义一个分数:高于或者低于标准杆的杆数值。因此,如果最初两个洞标准杆为4和5,而实际球手用了4杆和6杆,则分数为“1”(即高于标准杆1杆)。
球场类
球场名称和标准杆数分别用String和一个int数组来实现。除了setter-和getter-方法外,还需要一个方法来得到每一个洞所对应的标准杆数。我们就将它声明为“parUpTohole(int n)”。以下是我给出的类代码:
出于简单,没有在示例中引入方法调用错误检查(即在调用“getNumberOfHoles”方法前必须先调用“setPar”)。
package hansen.playground;
import java.util. * ;
public class Cource {
private String name; // name of cource
private int[] par; // the par for each hole
/*
* Set the name of the course
*/
public void setName(String name) {
this.name = name;
}
/*
* Set the par for the cource
*/
public void setPar(int[] par) {
this.par = par;
}
/*
* Get the number of holes for the course
*/
public int getNumberOfHoles() {
return par.length;
}
/*
* Return the par for a given hole
*/
public int parForHole(int hole) {
return par[hole-1];
}
/*
* Return the par from hole 1 and up to a given hole
*/
public int parUpToHole(int hole) {
int sum = 0;
for ( int i = 0; i < hole; i++ ) {
sum += par[i];
}
return sum;
}
对Course类的测试
通过调用Course类的方法,可以编写程序测试“parUpToHoles”方法是否能够得到预定的结果。我们假定球场为英格兰美丽、著名的“St. Andrews”:
Course c = new Course();
c.setName( " St. Andrews " );
int [] par = {4,4,4,4,5,4,4,3,4,4,3,4,4,5,4,4,4,4} ;
c.setPar(par);
第1洞与第2洞标准杆之和显然为4+4=8,所以可以编写下面这样的代码进行测试:
if ( c.parUpToHole( 2 ) != 8 ) {
System.out.println("*** Error in Course.parUpToHole: par for 2 holes not 8");
}
如果运行上面的代码获得一个错误信息的话,那我们就有一个bug需要修复了。如果她只是默默地运行,哈哈,那就一切正常。
你可以写一段代码用来测试这18个洞,但大多数程序员知道只需要测试边界值,即0个和18个洞,以及中间几个值就可以达到要求。例如:
if ( c.parUpToHole( 0 ) != 0 ) {
System.out.println("*** Error in Course.parUpToHole: par for 0 holes not 0");
}
if ( c.parUpToHole( 2 ) != 8 ) {
System.out.println("*** Error in Course.parUpToHole: par for 2 holes not 8");
}
if ( c.parUpToHole( 8 ) != 72 ) {
System.out.println("*** Error in Course.parUpToHole: par for 8 holes not 72");
}
上面的代码,比较了一些值,然后根据比较的结果进行相应的处理,尽管实际有效,却缺乏代码的艺术性。通过这个程序,可以对"parUpToHole"进行单元测试,运行后,我们将赞赏地肯定这个方法是如预定的那样工作。
其实,我们可以做得更加漂亮……