用JUnit4进行单元测试
转载:http://tonl.iteye.com/blog/1948869
参考:
http://thihy.iteye.com/blog/1771826
http://developer.51cto.com/art/201103/252490.htm
http://www.ibm.com/developerworks/cn/java/j-lo-junit4/
http://www.infoq.com/cn/articles/road-of-automated-unit-testing-practices
http://coolshell.cn/articles/8209.html
http://blog.csdn.net/andycpp/article/details/1327147
http://www.infoq.com/cn/news/2012/02/I-Hate-Unit-Test
http://coolshell.cn/category/process
用Junit进行单元测试很方便,尤其是Junit4引入了很多Annotation注解以后。看测试的示例:
待测试类:
- public class Calculator {
- public int add(int a, int b) {
- return a + b;
- }
- public int minus(int a, int b) {
- return a - b;
- }
- public int square(int n) {
- return n * n;
- }
- //Bug : 死循环
- public void squareRoot(int n) {
- for(; ;)
- ;
- }
- public int multiply(int a, int b) {
- return a * b;
- }
- public int divide(int a, int b) throws Exception {
- if (0 == b) {
- throw new Exception("除数不能为零");
- }
- return a / b;
- }
- }
单元测试类:
- import org.junit.After;
- import org.junit.AfterClass;
- import org.junit.Assert;
- import org.junit.Before;
- import org.junit.BeforeClass;
- import org.junit.Ignore;
- import org.junit.Test;
- public class CalculatorTest {
- private Calculator cal = new Calculator();
- @BeforeClass // 注意,这里必须是static...因为方法将在类被装载的时候就被调用(那时候还没创建实例)
- public static void before()
- {
- System.out.println("global");
- }
- @AfterClass
- public static void after() {
- System.out.println("global destroy");
- }
- @Before
- public void setUp() throws Exception {
- System.out.println("一个测试开始。。");
- }
- @After
- public void tearDown() throws Exception {
- System.out.println("一个测试结束");
- }
- @Test
- @Ignore
- public void testAdd() {
- int result = cal.add(1, 2);
- Assert.assertEquals(3, result);
- }
- @Test
- public void testMinus() {
- int result = cal.minus(5, 2);
- Assert.assertEquals(3, result);
- }
- @Test
- public void testMultiply() {
- int result = cal.multiply(4, 2);
- Assert.assertEquals(8, result);
- }
- @Test(timeout = 1000) // 单位为毫秒
- public void testSquareRoot() {
- cal.squareRoot(4);
- }
- @Test(expected = Exception.class)
- public void testDivide() throws Exception {
- System.out.println("teddd");
- cal.divide(4, 0);// 很简单的办法.......
- }
- // @Test
- // public void testDivide() {
- // int result = 0;
- // try {
- // result = cal.divide(10, 5);
- // } catch (Exception e) {
- // e.printStackTrace();
- // Assert.fail();// 如果这行没有执行。说明这部分正确。
- // }
- // Assert.assertEquals(2, result);
- // }
- }
在Eclipse里Run As -> JUnit Test,运行测试类,Eclipse的JUnit的View显示如:
可以看到,CalculatorTest类中总共有5个测试用例,ignore了一个,3个测试用例通过,testSquareRoot测试不通过(因为超时),所以整个的测试结果飘红了。同时,控制台的输出结果为:
- global
- 一个测试开始。。
- 一个测试结束
- 一个测试开始。。
- 一个测试结束
- 一个测试开始。。
- 一个测试结束
- 一个测试开始。。
- teddd
- 一个测试结束
- global destroy
各种注解的说明:
@Test:
表明该方法是一个测试方法
@BeforeClass 和 @AfterClass:
测试用例初始化时执行 @BeforeClass方法,当所有测试执行完毕之后,执行@AfterClass进行收尾工作。标注、@BeforeClass 和 @AfterClass的方法必须是static的,因为方法将在类被装载的时候就被调用,那时候还没创建测试对象实例。
@Before:
使用了该元数据的方法在每个测试方法执行之前都要执行一次。
@After:
使用了该元数据的方法在每个测试方法执行之后要执行一次。
@Test(expected=*.class) :
通过@Test元数据中的expected属性验证是否抛出期望的异常,expected属性的值是一个异常的类型,如果抛出了期望的异常,则测试通过,否则不通过。
@Test(timeout=xxx):
该元数据传入了一个时间(毫秒)给测试方法,如果测试方法在制定的时间之内没有运行完,则测试也失败。
@Ignore:
该元数据标记的测试方法在测试中会被忽略。同时可以为该标签传递一个String的参数,来表明为什么会忽略这个测试方法。比如:@lgnore("该方法还没有实现"),在执行的时候,仅会报告该方法没有实现,而不会运行测试方法。
在test方法内除了使用Assert的assertEquals()方法外,还能使用assertFalse()、assertTrue()、assertNull()、assertNotNull()、assertSame()、assertNotSame()等断言函数。而且如果使用的是Junit4,结合Hamcrest,使用
assertThat([value], [matcher statement])方法可以实现更灵活的断言判断(前提是引入hamcrest的jar包)。
例如:
// is匹配符表明如果前面待测的object等于后面给出的object,则测试通过
assertThat( testedObj, is( object) );
// containsString匹配符表明如果测试的字符串包含指定的子字符串则测试通过
assertThat( testedString, containsString( "developerWorks" ) );
// greaterThan匹配符表明如果所测试的数值testedNumber大于16.0则测试通过
assertThat( testedNumber, greaterThan(16.0) );
// closeTo匹配符表明如果所测试的浮点型数testedDouble在20.0±0.5范围之内则测试通过
assertThat( testedDouble, closeTo( 20.0, 0.5 ) );
//hasItem匹配符表明被测的迭代对象含有元素element项则测试通过assertThat(iterableObject, hasItem (element));
更多更详细的Hamcrest提供的断言判断参考:
http://hi.baidu.com/shenhuanyu09/item/2bcfcb981aa3188e581461b4
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////分割线
上面的Caculator待测试类里,现在我如果想给square方法多弄几个测试用例,按照上面的方法,我应该写好几个@Test方法来测试,或者每次测完再改一下输入的值和期望得到的值,好麻烦。JUnit提供如下的测试:
- import java.util.Arrays;
- import java.util.Collection;
- import org.junit.Assert;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.junit.runners.Parameterized;
- import org.junit.runners.Parameterized.Parameters;
- @RunWith(Parameterized.class)
- public class CalculatorTest2{
- private Calculator cal = new Calculator();
- private int param;
- private int result;
- //构造函数,对变量进行初始化
- //定义一个待测试的类,并且定义两个变量,一个用于存放参数,一个用于存放期待的结果。
- public CalculatorTest2(int param, int result) {
- this.param = param;
- this.result = result;
- }
- @Parameters
- public static Collection data(){
- return Arrays.asList(new Object[][]{
- {2, 4},
- {0, 0},
- {-3, 9},
- });
- }
- @Test
- public void squareTest() {
- int temp = cal.square(param);
- Assert.assertEquals(result, temp);
- }
- }
Eclipse里JUnit的运行结果显示为:
测试通过了,CalculatorTest2类里的parameter是每次的测试输入,result就是测试的结果。所有的测试输入和期望结果都在@Parameters标注的data函数的返回的Collection集合里,2的期望得到的平方结果值是4,0期望得到0,-3期望得到9。
把测试代码提交给JUnit框架后,框架如何来运行代码呢?答案就是——Runner。在JUnit中有很多个 Runner,他们负责调用测试代码,每一个Runner都有各自的特殊功能,要根据需要选择不同的Runner来运行测试代码。JUnit中有一个默认Runner,如果没有指定,那么系统自动使用默认 Runner来运行你的代码。这里参数化测试就没有再用默认的Runner了。
再看看打包测试测例子:
- import org.junit.runner.RunWith;
- import org.junit.runners.Suite;
- /**
- * 大家可以看到,这个功能也需要使用一个特殊的Runner,
- * 因此我们需要向@RunWith标注传递一个参数Suite.class。
- * 同时,我们还需要另外一个标注@Suite.SuiteClasses,
- * 来表明这个类是一个打包测试类。我们把需要打包的类作为参数传递给该标注就可以了。
- * 有了这两个标注之后,就已经完整的表达了所有的含义,因此下面的类已经无关紧要,
- * 随便起一个类名,内容全部为空既可
- *
- */
- @RunWith(Suite.class)
- @Suite.SuiteClasses({ CalculatorTest.class, CalculatorTest2.class })
- public class AllCalculatorTests {
- }
这个测试类包含了上面的CalculatorTest.class和CalculatorTest2.class里面所有的测试函数,它的目的就是进行打包所有的测试。
参考:
http://blog.csdn.net/zhuangxiu/article/details/6256893
http://blog.csdn.net/songyinan1989/article/details/7445921
http://www.jb51.net/article/15797.htm
http://jingbo2759.blog.163.com/blog/static/983753152009711103710146/
用JUnit4进行单元测试的更多相关文章
- J2EE 第二阶段项目之JUnit4进行单元测试(五)
今天学习了JUnit4进行单元测试.这样就可以不写页面直接进行过功能模块测试.也不是很深入的了解. JUnit4和自己写的代码可以分割开来. 首先呢准备两个jar包: 可以对mapper进行测试,当然 ...
- 在Eclipse中使用JUnit4进行单元测试
在Eclipse中使用JUnit4进行单元测试(初级篇) 在Eclipse中使用JUnit4进行单元测试(中级篇) 在Eclipse中使用JUnit4进行单元测试(高级篇)
- 【Java】在Eclipse中使用JUnit4进行单元测试(初级篇)
本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能 ...
- springMVC整合Junit4进行单元测试
springMVC整合Junit4进行单元测试 标签: springMVC整合Junit4junit单元测试教程springMVC入门教程 spring(10) 版权声明:本文为博主原创文章,未 ...
- (转)用JUnit4进行单元测试
场景:从开始写代码至今,对于单元测试一直没有重视,但是也厌倦了了程序中的额System.out和log日志输出.单元测试使我看到了在开发过程中的安全性和便捷性,所以下决心好好整理下. 有感而发——&l ...
- 在Eclipse中使用JUnit4进行单元测试(图文教程一)
在Eclipse中使用JUnit4进行单元测试 单元测试,JUnit4. 这两个有什么关系呢?这就好比(草)单元测试和(割草机).用这个JUnit4工具去辅助我们进行测试.其实不理解这个也没关系,听多 ...
- 在eclipse中使用JUnit4,以及使用JUnit4进行单元测试的技巧
一 在eclipse中使用JUnit4 首先在工程上右键,选择属性,找到Java Builder Path,添加JUnit4的lib,如下图: 在要测试的类上右键新建 Junit test cas ...
- Idea 使用 Junit4 进行单元测试
目录 Idea 使用 Junit4 进行单元测试 1. Junit4 依赖安装 2. 编写测试代码 3. 生成测试类 4. 运行 Idea 使用 Junit4 进行单元测试 1. Junit4 依赖安 ...
- [转]在Eclipse中使用JUnit4进行单元测试(初级篇)
首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感! 首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除 ...
- 在Eclipse中使用JUnit4进行单元测试(初级篇)
首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感! 首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除 ...
随机推荐
- 51nod1270 数组的最大代价(简单dp)
---恢复内容开始--- 1270 数组的最大代价 题目来源: HackerRank 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 数组A包含N个 ...
- PHP:parse_str()字符串函数
parse_str()-把字符串解析成多个变量. 描述:void parse_str(sring $str [, array $arr]) 如果str是URL传递入的查询字符串(query stri ...
- CSS的IE6、IE7、FF兼容性写法
blue;< /td> Firefox 背景变蓝色 red /9; IE8 背景变红色 *black;< /td> IE7 背景变黑色 _background:orange; ...
- Delphi XE5教程8:使用Delphi命名空间
// Project file declarations... //项目文件声明… program MyCompany.ProjectX.ProgramY; // Unit source file d ...
- 你必须知道的.NET
作者博客地址:http://www.cnblogs.com/anytao/archive/2008/04/09/anytao_insidenet_center.html 第1章 OO大智慧 1.1对象 ...
- TLV格式是什么格式
TLV 格式是什么格式 一种可变格式, TLV 的意思就是: Type 类型, Lenght 长度, Value 值: Type 和 Length 的长度固定,一般那是 2 . 4 个字节: Valu ...
- postgresql 开启远程访问
1.如果服务器启用了防火墙,需要在防火墙上开启 5432 端口. 2.修改 PostgreSQL 配置文件 postgresql.conf.postgresql.conf,Linux 配置文件所在路径 ...
- 《零成本实现Web自动化测试--基于Selenium》第一章 自动化测试基础
第一篇 Selenium 和WebDriver工具篇 第一章 自动化测试基础 1.1 初识自动化测试 自动化测试有两种常见方式 1.1.1 代码驱动测试,又叫测试驱动开发(TDD) 1.1.2 ...
- HotSpot Builder Utility安装指南
系统需求硬件- 一台带有1个以太网卡的电脑(宿主机)- 一个无线路由器 软件- VirtualBox 4.1或更高的版本.下载网址:http://www.virtualbox.org/- 我们提供的最 ...
- Andriod WIFI驱动模块
一:什么是WIFI WIFI是一种无线连接技术,可用于手机.电脑.PDA等终端.WIFI技术产生的目的是改善基于IEEE802.11标准的无线网络产品之间的互通性,也就是说WIFI是基于802.11标 ...