Loading

【助教】关于单元测试(一)

通俗理解单元测试?

有一个方法,编程的时候需要调用这个方法,怎么知道这个方法会不会有bug?测试一下。

怎么学单元测试?(个人观点,仅供参考

从“Hello World"做起,然后,试着把自己写的程序做几个简单的单元测试,项目驱动学习的方法,掌握的更牢固。至于它的原理,是否应该一开始很细致的了解单元测试的方方面面,不太好说,我的理解是:我的面前有一辆自行车,我想学着骑,并不一定一开始就想着它的构造。


一个简单的单元测试的例子(以Eclipse+Java+Junit为例):

故事:

  • 小张童鞋写了一个类:Core.java,里面有一个方法:add(),这个方法完成的功能是传入两个int类型的值返回两个值的和。
  • 小李童鞋要写一个小程序,里面的一个功能正好需要用到小张的方法,小张爽快答应了要求,同时怕小李担心里面有bug,小张决定做一下单元测试,确保这个方法没有bug,这样就底气更足的交给小李童鞋使用了。

小张在Eclipse下写好的Core.java的代码清单:

package com.hui.demo;

public class Core {
	public int add(int a, int b) {
		return a + b;
	}
}

接下来要在Eclipse下利用Junit对这个方法进行单元测试:

  • Eclipse下在Core.java这个文件右键:
    New--->Other...--->Wizards里输入:Junit,并且在下面的列表中选择Junit Test Case-->Next--->选择New JUnit 4 test,Package这里写:com.hui.demo.test, Name这里写:CoreTest,Class under test这里写:com.hui.demo.Core--->Next--->选中要测试的方法add(int, int)--->点击Finish
  • 在com.hui.demo.test这个包下面生成了一个CoreTest.java的类文件

CoreTest.java的代码清单:

package com.hui.demo.test;

import static org.junit.Assert.*;
import org.junit.Test;

public class CoreTest {

	@Test
	public void testAdd() {
		fail("Not yet implemented");
	}

}

fail("Not yet implemented");

这句删掉,这样我们就可以在testAdd里面写我们的测试代码了。

比如:

package com.hui.demo.test;

import static org.junit.Assert.*;
import org.junit.Test;
import com.hui.demo.Core;

public class CoreTest {

	@Test
	public void testAdd() {
		Core core = new Core();
		int a = core.add(9, -3);
		// 测一下:9和-3传入我的add方法里面,结果会不会是6?
		assertEquals(6, a); 
	}
}

运行这个测试用例:

Eclipse中,双击选中这个testAdd方法名称,右键-->Run As-->Junit Test
你会看到一条绿色的进度条,说明这次测试成功,小张很开心,把这个方法给小李用了。
......
岁月静好,直到有一天,小李的程序发生了bug,bug就出现在小张写的方法里面,小张很无辜,我已经做过单元测试了,为什么还会出bug呢?原来:小李的程序接受了两个这样的int类型的值:2147483647,2147483647 最后调用小张的方法以后得到的值为-2,为什么不是4294967294?因为int类型装不下这么大的值。 怎么处理这种情况呢?

小张通过自己学过的Java程序设计的知识,觉得可以用long来解决了这个问题,新的Core.java的代码清单为:

package com.hui.demo;

public class Core {
	public long add(int a, int b) {
		return (long)a + (long)b;
	}
}

在CoreTest.java里面写这两个测试方法:

package com.hui.demo.test;

import static org.junit.Assert.*;
import org.junit.Test;
import com.hui.demo.Core;

public class CoreTest {

	@Test
	public void testAdd() {
		Core core = new Core();
		// 我想测一测:
		// 9和-3传入我的add方法里面,
		// 得出的结果会不会是6
		long a = core.add(9,-3);
		assertEquals(6L, a); 
	}
	
	@Test
	public void testAddisOverLimited() {
		Core core = new Core();
		// 我想测一测:
		// 2147483647和2147483647传入
		// 我的add方法里面,
		// 得出的结果会不会是4294967294L
		long a = core.add(2147483647,2147483647);
		assertEquals(4294967294L, a);
	}
}

在CoreTest.java这里右键--->Run As--->JUnit Test,看到进度条变绿,说明测试这两种情况都通过了。重新把代码给小李,Ok了。

由此,完成了一个简单的单元测试。


补充:

1.为了解释方便,我在注释这里,我写了这样一段话,大家在实际单元测试中不一定要像我这样啰嗦:

// 我想测 一测:
// 2147483647和2147483647传入
// 我的add方法里面,
// 得出的结果会不会是4294967294L

实际可以通用到:

// 我想测 一测:
// 参数传入
// 我的待测方法里面,
// 得出的结果会不会是:我期待的结果

根据不同的情况,比如:

// 我想测 一测:
// "abc@hotmail.com"传入
// 我的checkEmail()方法里面,
// 得出的结果会不会是:提示你邮箱格式正确

// 我想测 一测:
// “abchotmail.com”传入
// 我的checkEmail()方法里面,
// 得出的结果会不会是:提示你邮箱格式错误(缺少了@)
......

2.assertEquals(a,b)方法
在刚才的例子中,很简单,a为期待值,b为实际值,这个方法就是告诉我们:实际得出的b这个值是不是等于我们期待的a这个值。
此外Junit还提供了很多这样的方法,大家可以参考一下Junit的API文档:
或者在Eclipse下按住:Alt+/ 会提示多种方法来供你使用。

附:
Junit API:http://www.udel.edu/CIS/software/dist/junit4.1/javadoc/
Junit视频教程:http://pan.baidu.com/s/1qWsaMVM
极简单元测试示例(C语言版):http://www.cnblogs.com/math/p/se-gzsd-2015-010.html

posted @ 2015-04-19 14:09  Grey Zeng  阅读(965)  评论(2编辑  收藏  举报