首个单元测试
public void asserTrue(boolean condition){
if(!condition){
abort();
}
}
由于某种原因,当调用assertTrue()的时候条件不成立,那么程序将被终止,事实上你可以用断言来判断所有的事物.
既然我们经常需要检测是否相等,如果能够有一个专门针对于数字的断言将会更为方便.例如为了检测二个整数是否相等,我们可以编写如下的断言.
public void assertEquals(int a, int b){
assertTrue(a==b);
}
为了使得概念更加具体,让我们来编写一个"寻找最大数"的函数,并对它进行测试.
public class Largest {
/**
* return the Largest element of the list
*
* @param list A list of integers
* @return The Largest number in the given List
*/
public static int largest(int[] list){
int index,max=Integer.MAX_VALUE;
for(index=0; index<list.length;index++){
if(list[index]>max){
max=list[index];
}
}
return max;
}
}
你想有多少个测试?
显然对于一个List而言,元素的位置对该方法的结果并不会产生影响;于是你马上会想到如下的测试(在下面我们将把输入输出写成"输入--->你所期望的输出"这样的格式)。
[7,8,9]----->9
[8, 9,7]----->9
[9,7,8 ]----->9
如果List中存在二个相等的最大值,将会出现什莫情况。
[7,8,9,9,7]--->9
如果这些元素是int类型,而不是对象类型,你可能不能不在意那个9会作为结果返回,只要返回其中的一个就行了。
如果List中只有一个元素,那末结果会是什莫?
[1]----->1
如果List包含负数,结果有回是怎样?
[-9,-8,-7]------->-7
*测试一个简单的方法。
首个测试非常的简单,因为除了代码以外还有许多的因素需要被测试:凌乱的类名,程序库的位置,还要确定代码能否被编译。在你的首个测试里假设一切都成立。
首先,让我们传递一个没有重复的简单数组给函数,并对这种情况进行测试,下面是详细的代码。
import junit.framework.TestCase;
public class TestLarget extends TestCase {
public TestLarget(String name){
super(name);
}
public void testSimply(){
assertEquals(9,Largest.largest(new int[] {7,8,9}));
}
public void assrtEquals(int a, int b){
assertTrue(a==b);
}
}
运行刚才的代码后,你可能看到类似于下面的错误信息(在eclipse上的运行结果):
junit.framework.AssertionFailedError: expected:<9> but was:<2147483647>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:282)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:201)
at junit.framework.Assert.assertEquals(Assert.java:207)
at TestLarget.testSimply(TestLarget.java:8)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
whoops!为什莫和我们期望的不一致那?原来max=Integer.MAX_VALUE;这行代码出现了错误,应该是max=0,我们的想法是初始化max这样的一个值,任何的数字和其比较之后,可以立刻的取代它。修改以后重新的编译,并最终通过测试。
如果最大数位于List的不同位置,那末将会产生什莫样的情况,显然bug经常出现在边界位置,上面的例子中边界是指list的首个、最后一个位置,下面的代码中,我们把三个断言写在一个测试中,但是我们每次只添加一个断言。
public void testOrder(){
assertEquals(9,Largest.largest(new int[] {9,8,7}));
assertEquals(9,Largest.largest(new int[] {7,9,8}));
assertEquals(9,Largest.largest(new int[] {7,8,9}));
}
junit.framework.AssertionFailedError: expected:<9> but was:<8>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:282)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:201)
at junit.framework.Assert.assertEquals(Assert.java:207)
at TestLarget.testOrder(TestLarget.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
当我们测试到最后一个断言的时候,我们发现函数的最大值为什莫会是8那?好像代码根本没有考虑List的最后一个元素,原来代码中for循环结束太早了,一个典型的off-by-one错误的一个例子。在我们的代码中:
for(index=0; index<list.length-1;index++){
实际应该是:
for(index=0; index<=list.length-1;index++){
for(index=0; index<list.length;index++){
在继承了c的语言(包括java)中,第二中表述方式比较常用并且容易阅读。修改代码后从新测试运行。
现在检测存在重复最大值的情况,编写并运行下面的代码。
public void testDups(){
assertEquals(9,Largest.largest(new int[] {9,7,8,9}));
}
测试的结果和我们期望的一致。接下来我们需要测试仅仅存在一个元素的List.
public void testOne(){
assertEquals(1,Largest.largest(new int[] {1}));
}
Hey,他通过了!你正在朝着正确的方向前进,并确定我们的例子中的bug已经被除去了。我们再来调试全部为负值的List.
public void testNegative(){
assertEquals(-7,Largest.largest(new int[] {-7,-8,-9}));
}
junit.framework.AssertionFailedError: expected:<-7> but was:<0>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:282)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:201)
at junit.framework.Assert.assertEquals(Assert.java:207)
at TestLarget.testNegative(TestLarget.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
whoops!这个零是从哪里来得那?看来用0初始化max是个错误的做法,因为我们实际需要初始 max=Integer.MIN_VALUE;从而使它比任何的负数都小.
TAG:
我的栏目
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | ||||||
5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
26 | 27 | 28 | 29 | 30 | 31 |
数据统计
- 访问量: 9773
- 日志数: 6
- 图片数: 2
- 文件数: 16
- 建立时间: 2007-04-19
- 更新时间: 2007-11-20