作者: Keld H. Hansen 翻译: CManLH 原文地址
一、 介绍
二、 进入junit的天堂
三、 Round类
四、分析并获取测试用例
Round类
在Round类中,需要一个方法来记录球手打过的洞所得的分数。为了知道球手当前的分数,需要定义方法“currentScore”。Round类的简单实现如下:
package
hansen.playground;
import java.util. * ;
public class Round {
private String player; // name of player
private Course course; // name of the course
private int[] score; // scores for each hole
private int currentHole = 0; // the last played hole
/*
* Set the name of the player
*/
public void setPlayer(String name) {
player = name;
}
/*
* Set the course
*/
public void setCourse(Course c) {
course = c;
score = new int[course.getNumberOfHoles()];
}
/*
* Set the number of strokes for the current hole
*/
public void newScore(int s) {
score[currentHole] = s;
currentHole++;
}
/*
* Get the number of strokes used so far
*/
public int currentStrokes() {
int sum = 0;
for ( int i = 0; i < currentHole; i++ ) {
sum += score[i];
}
return sum;
}
/*
* Get the current socre relative
* to the par of the course
*/
public int currentScore() {
return currentStrokes() - course.parUpToHole(currentHole);
}
}
import java.util. * ;
public class Round {
private String player; // name of player
private Course course; // name of the course
private int[] score; // scores for each hole
private int currentHole = 0; // the last played hole
/*
* Set the name of the player
*/
public void setPlayer(String name) {
player = name;
}
/*
* Set the course
*/
public void setCourse(Course c) {
course = c;
score = new int[course.getNumberOfHoles()];
}
/*
* Set the number of strokes for the current hole
*/
public void newScore(int s) {
score[currentHole] = s;
currentHole++;
}
/*
* Get the number of strokes used so far
*/
public int currentStrokes() {
int sum = 0;
for ( int i = 0; i < currentHole; i++ ) {
sum += score[i];
}
return sum;
}
/*
* Get the current socre relative
* to the par of the course
*/
public int currentScore() {
return currentStrokes() - course.parUpToHole(currentHole);
}
}
测试Round类
接下来,编写测试Round类的测试类或者叫测试用例。在Round类中,数个方法应该被测试。那么,我们就为Tiger Woods试图打败丹麦选手Thomas Bjorn的球赛写个测试类吧。
package
hansen.playground;
import junit.framework. * ;
public class TestRound extends TestCase {
private Course c;
private Round tb, tw;
public TestRound(String name) {
super(name);
}
protected void setUp() {
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);
tb = new Round();
tb.setPlayer("Thomas Bjorn");
tb.setCourse(c);
tw = new Round();
tw.setPlayer("Tiger Woods");
tw.setCourse(c);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(TestRound.class);
}
public void testTiger() {
// Test that beginning score is zero
assertEquals(0, tw.currentStrokes());
//Player gets a "par"
tw.newScore(4);
assertEquals(4, tw.currentStrokes());
assertEquals(0, tw.currentScore());
// Player gets a "birdie"
tw.newScore(3);
assertEquals(7, tw.currentStrokes());
assertEquals(-1, tw.currentScore());
}
public void testThomas() {
// Player gets a "boyey"
tb.newScore(5);
assertEquals(5, tb.currentStrokes());
assertEquals(1, tb.currentScore());
// Player gets an "eagle"
tb.newScore(2);
assertEquals(7, tb.currentStrokes());
assertEquals(-1, tb.currentScore());
}
}
import junit.framework. * ;
public class TestRound extends TestCase {
private Course c;
private Round tb, tw;
public TestRound(String name) {
super(name);
}
protected void setUp() {
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);
tb = new Round();
tb.setPlayer("Thomas Bjorn");
tb.setCourse(c);
tw = new Round();
tw.setPlayer("Tiger Woods");
tw.setCourse(c);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(TestRound.class);
}
public void testTiger() {
// Test that beginning score is zero
assertEquals(0, tw.currentStrokes());
//Player gets a "par"
tw.newScore(4);
assertEquals(4, tw.currentStrokes());
assertEquals(0, tw.currentScore());
// Player gets a "birdie"
tw.newScore(3);
assertEquals(7, tw.currentStrokes());
assertEquals(-1, tw.currentScore());
}
public void testThomas() {
// Player gets a "boyey"
tb.newScore(5);
assertEquals(5, tb.currentStrokes());
assertEquals(1, tb.currentScore());
// Player gets an "eagle"
tb.newScore(2);
assertEquals(7, tb.currentStrokes());
assertEquals(-1, tb.currentScore());
}
}
通过命令行方式调用TestRunner运行该测试类,将会得到以下结果:
..
Time: 0 , 06
OK ( 2 tests)
Time: 0 , 06
OK ( 2 tests)
“2 tests”意味着有两个测试方法被执行。"Time"上面的两个句点亦是此含义。
TestRunner进阶
当调用TestRunner时,应该将测试类的类名作为参数传给该测试类的构造函数。通过java技术的“introspection”(自我检测?)机制,TestRunner会装载所有名字以“test”开头的方法,并且运行它们。如果只想运行其中的几个方法,可以定义一个静态方法“suite”,并且让其返回一个“TestSuite”对象(“TestSuite”对象会运行其中包含的测试方法)。例如,如果只想测试“Tiger Woods”,则“suite”定义如下:
public
static
Test suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new TestRound("testTiger"));
return suite;
}
TestSuite suite = new TestSuite();
suite.addTest(new TestRound("testTiger"));
return suite;
}
两者都想测试:
public
static
Test suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new TestRound("testTiger"));
suite.addTest(new TestRound("testThomas"));
return suite;
}
TestSuite suite = new TestSuite();
suite.addTest(new TestRound("testTiger"));
suite.addTest(new TestRound("testThomas"));
return suite;
}
想运行所有的测试方法,可以简单的写成:
public
static
Test suite()
{
return new TestSuite(TestRound.class);
}
return new TestSuite(TestRound.class);
}
在main方法中调用TestRunner运行测试程序时,其实可以使用“suite”来代替被测试类的类名:
junit.textui.TestRunner.run(suite());
“在每个TestCase类中都定义一个suite方法”,应该将其当成一种习惯。因为,她随时可以让你在程序的编写过程中对特定测试用例进行测试。而且,suite也常常用来组织测试用例,即将分散的suite通过一层一层逐渐合并成一个大的测试用例。这样,只需运行一个suite方法就可以运行所有的测试用例了,方便吧?