Junit4 单元测试框架的常用方法介绍
Junit 介绍:
Junit是一套框架(用于JAVA语言),由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),即用于白盒测试。
本文介绍的内容:
1 Junit Myeclipse测试类的生成
2 JUnit 4 常用的几个annotation 介绍与使用 (@Before @After @Test @Ignore @BeforeClass @AfterClass)
3 常用的断言介绍
4 特殊的处理 (限时测试,异常测试)
5 参数化配置 (@Parameters)
准备测试代码
测试的方法(正确、错误方法、死循环、抛异常)
LogicService
package com.logic; public class LogicService { public int add(int x ,int y){ //加法
return x+y;
} public int sub(int x ,int y){ //减法
return x-y;
} public int div(int x ,int y){ //除法
return x/y;
} public int div2(int x ,int y){ //除法 做了异常判断
try {
int z = x/y;
} catch (Exception e) {
e.printStackTrace();
}
return x/y;
} public void loop(int x ,int y){ //死循环
for(;;)
x=y;
} public void unCompleted(int x ,int y){ //未完成的模块
//还在开发中
} }
一 Myeclipse测试类的生成
1 对需要测试的类点右键 NEW 一个Junit Test Case
2 点击NEXT
注意 1 选择NEW Junit 4 test
2 source folder 是默认会填写上之前右键NEW的那个类,如果不是的话,请自行进行修改
3 package 默认会填写当前的包名 个人建议重新开个测试包-即在包后面加上.test 表示是单元测试用例专用包与源代码分离
4 name 默认会在之前右键NEW的那个类的基础的后面加上Test 如果不是的话,建议自行进行修改,便于标示
5 初始化的方法,我一般会勾上个setUp,这个请随意。
3 继续点击NEXT
1 这里可以选择需要测试的方法,我一般都是全选的然后在生成的测试类中再做处理
2 点击finish完成
4 生成的单元测试类
package com.logic.test; import static org.junit.Assert.*; import org.junit.Before;
import org.junit.Test; public class LogicServiceTest { @Before
public void setUp() throws Exception {
} @Test
public void testAdd() {
fail("Not yet implemented");
} @Test
public void testSub() {
fail("Not yet implemented");
} @Test
public void testDiv() {
fail("Not yet implemented");
} @Test
public void testDiv2() {
fail("Not yet implemented");
} @Test
public void testLoop() {
fail("Not yet implemented");
} @Test
public void testUnCompleted() {
fail("Not yet implemented");
} }
二 JUnit 4 常用的几个annotation 介绍与使用 (@Before @After @Test @Ignore @BeforeClass @AfterClass)
1 常用的annotation介绍
@Before:初始化方法,在任何一个测试执行之前必须执行的代码;
@After:释放资源,在任何测试执行之后需要进行的收尾工作。在每个测试方法执行之后执行一次,该annotation只能修饰public void 方法;
@Test:测试方法,表明这是一个测试方法。在Junit中将会自动被执行。该annotation只你呢个修饰public void 方法。
@Ignore:忽略的测试方法,标注的含义就是“某些方法尚未完成,暂不参与此次测试”;
@BeforeClass:针对所有测试,只执行一次,且必须为public static void;一般用于初始化必要的消耗较大的资源,例如数据库连接等
@AfterClass:针对所有测试,将会在所有测试方法执行结束后执行一次,且必须为public static void;
2 常用的annotation测试
修改单元测试类LogicServiceTest
package com.logic.test; import static org.junit.Assert.*; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; public class LogicServiceTest { @Before
public void setUp() throws Exception {
System.out.println("@Before");//测试@Before
} @After
public void end() throws Exception {
System.out.println("@After");//测试@@After
} @BeforeClass
public static void init() throws Exception {
System.out.println("@BeforeClass");//测试@BeforeClass
} @AfterClass
public static void disstroy() throws Exception {
System.out.println("@AfterClass");//测试@AfterClass
} @Test
public void testAdd() {
System.out.println("@Test testAdd");//测试@Test
} @Test
public void testSub() {
System.out.println("@Test testSub");//测试@Test
} @Ignore
public void testDiv() {
System.out.println("@Ignore ");//测试@Ignore
} @Ignore
public void testDiv2() {
System.out.println("@Ignore ");//测试@Ignore
} @Ignore
public void testLoop() {
System.out.println("@Ignore ");//测试@Ignore
} public void testUnCompleted() {
System.out.println("@Ignore ");//测试未标注
} }
执行结果
执行结果分析
1 @BeforeClass和@AfterClass只执行一次,在所有方法开始前/后
2 @Before和@After在每个@Test标注的方法前后各执行一次
3 @Test 标注的方法都会执行一次(表示要测试的方法)
4 @Ignore方法不会被执行,没有annotation的方法也不会被执行
5 总结 @BeforeClass –> (@Before –> @Test –> @After) –> @AfterClass
理解了以上注解后就可以尝试着在日常的项目中使用Junit进行单元测试了。
3 常用的断言介绍
assertEquals(String msg, Object expectRes, Object Res) -------- 用于值判断
判断expectRes.equals(Res) ,表示值等于的判断,失败则抛MSG
assertSame(String msg, Object expectRes, Object Res) -------- 用于地址判断
判断expectRes==Res,表示地址等于的判断,失败则抛MSG
assertTrue(String msg,Boolean result) ----------------------------用于Boolean判断
判断result是true还是false,失败则抛MSG
assertNull(String msg,Object result)-------------------------------用于NULL判断
判断result是否为NULL,失败则抛MSG
fail(String msg);---------------------------------------------------直接中止方法运行
直接中止方法运行,抛出MSG
测试代码
package com.logic.test; import static org.junit.Assert.*; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import com.logic.LogicService; public class LogicServiceTest {
LogicService logserv ; @Before
public void setUp() throws Exception {
logserv = new LogicService();
} @Test
public void testAdd() {
String a = "aa";
String t = "a";
String b = "a"+t;
assertEquals("assertEquals", a, b) ; //A与B的关系是值相等,地址不相等,这个用例会成功
} @Test
public void testSub() {
String a = "aa";
String t = "a";
String b = "a"+t;
assertSame("assertSame", a, b) ; //A与B的关系是值相等,地址不相等,这个用例会失败
} @Test
public void testDiv() {
assertTrue("assertTrue",true);//用例成功
assertTrue("第二个为false失败",false);//用例失败
} @Test
public void testDiv2() {
assertNull("assertNull",null);//用例成功
assertNull("第二个为notNull失败","a");//用例失败
} @Ignore
public void testLoop() {
} @Ignore
public void testUnCompleted() {
} }
执行结果分析
这里我不再截图了
1 成功
2 失败,返回MSG为assertSame
3 第一个成功,第二个失败,返回MSG为第二个为false失败
4 第一个成功,第二个失败,返回MSG为第二个为notNull失败
断言是用来判断被测方法执行的结果与预期结果是否匹配
4 特殊的处理 (限时测试,异常测试)
1 Junit提供限时处理的机制。
@Test(timeout=1000) 单位毫秒
当方法用时超过1000毫秒时,此方法会自动中止并执行失败
package com.logic.test; import static org.junit.Assert.*; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import com.logic.LogicService; public class LogicServiceTest {
LogicService logserv ; @Before
public void setUp() throws Exception {
logserv = new LogicService();
} @Ignore
public void testAdd() {
} @Ignore
public void testSub() {
} @Ignore
public void testDiv() {
} @Test(timeout=1000)
public void testDiv2() {
System.out.print("我不会超过1000毫秒的");
} @Test(timeout=1000)
public void testLoop() {
logserv.loop(1, 1);//此方法使用的是死循环实现,所以一定会超过限时,超过限时后此方法会自动中止
} @Ignore
public void testUnCompleted() {
} }
执行结果
loop方法超时报错,div2方法不超时成功
2 Junit提供异常处理的机制。
@Test(expected=Exception.class) 其中Exception.class可以写的更加具体
测试
@Test(expected=Exception.class)
public void testDiv() {
System.out.print(logserv.div(3, 0));
} @Test(expected=Exception.class)
public void testDiv2() {
System.out.print(logserv.div(3, 0));
}
执行结果
两个都通过
测试
@Test(expected=Exception.class)
public void testDiv() {
System.out.print(logserv.div(3, 0));
} @Test
public void testDiv2() {
System.out.print(logserv.div(3, 0));
}
执行结果
第一个通过 第二个不通过 异常为除数不能为zero
5 参数化配置 (@Parameters) 重要
进行单元测试的时候,通常一个方法需要好几个case进行测试,Junit提供参数化便于我们对方法进行多种参数的组合测试
如果不使用参数化进行测试的话,那么我们的测试类会做的很臃肿
例如
@Test
public void testAdd() {
assertEquals("1+1 失败",2,logserv.add(1, 1) );
}
@Test
public void testAdd1() {
assertEquals("1+2 失败",3,logserv.add(1, 2) );
}
@Test
public void testAdd2() {
assertEquals("1+3 失败",3,logserv.add(1, 3) );
}
@Test
public void testAdd3() {
assertEquals("1+4 失败",3,logserv.add(1, 4) );
}
这样的测试类显然看起来不是很理想,代码过于重复
参数化的实现过程(重要)
1 在测试类上增加
@RunWith(Parameterized.class)并引入
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
2 写上构造类的函数及定义入参
例如
@RunWith(Parameterized.class)
public class LogicServiceTest {
LogicService logserv ;
int parm1 ;//定义入参
int parm2 ;//定义入参
int res;//定义入参 public LogicServiceTest(int parm1,int parm2,int res){//定义构造函数
this.parm1=parm1;
this.parm2=parm2;
this.res=res;
}
3 定义一个返回结果为collection类型的方法并写上@Parameters
注意 Arrays.asList()里面NEW的Object的要与定义的参数一一对应
例如
public class LogicServiceTest {
LogicService logserv ;
int parm1 ;//定义入参
int parm2 ;//定义入参
int res;//定义入参 public LogicServiceTest(int parm1,int parm2,int res){//定义构造函数
this.parm1=parm1;
this.parm2=parm2;
this.res=res;
} @Parameters
public static Collection<Object[]> initParm(){
return Arrays.asList(new Object[][]{
{1,1,2},{1,2,3},{1,3,4},{1,3,5}//{}里的参数一定要和构造函数一一对应
});
}
4 编写测试方法,调用参数
@Test
public void testAdd() {
assertEquals(res,logserv.add(parm1, parm2));
}
5 测试类代码全景(准备执行)
package com.logic.test; import static org.junit.Assert.*; import java.util.Arrays;
import java.util.Collection; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters; import com.logic.LogicService; @RunWith(Parameterized.class)
public class LogicServiceTest {
LogicService logserv;
int parm1;// 定义入参
int parm2;// 定义入参
int res;// 定义入参 public LogicServiceTest(int parm1, int parm2, int res) {// 定义构造函数
this.parm1 = parm1;
this.parm2 = parm2;
this.res = res;
} @Parameters
public static Collection<Object[]> initParm() {
return Arrays.asList(new Object[][] { { 1, 1, 2 }, { 1, 2, 3 },
{ 1, 3, 4 }, { 1, 3, 5 } // {}里的参数一定要和构造函数一一对应
});
} @Before
public void setUp() throws Exception {
logserv = new LogicService();
} @Test
public void testAdd() {
assertEquals(res, logserv.add(parm1, parm2));
} @Ignore
public void testSub() {
}
}
6 执行结果
总结:使用了参数化后测试类的代码简化了不少,而且执行起来效果很不错
收尾
通过本文可以了解到:
1 Junit Myeclipse测试类的生成
2 JUnit 4 常用的几个annotation 介绍与使用 (@Before @After @Test @Ignore @BeforeClass @AfterClass)
3 常用的断言介绍
4 特殊的处理 (限时测试,异常测试)
5 参数化配置 (@Parameters)
Junit4 单元测试框架的常用方法介绍的更多相关文章
- JavaScript单元测试框架JsUnit基本介绍和使用
JavaScript单元测试框架JsUnit基本介绍和使用 XUnit framework XUnit是一套标准化的独立于语言的概念和结构集合,用于编写和运行单元测试(Unit tests). 每一个 ...
- Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 本文是Java反射学习总结系列的最后一篇了,这里贴出之前文章的链接,有兴趣的可以打开看看. ...
- Python+selenium之简单介绍unittest单元测试框架
Python+selenium之简单介绍unittest单元测试框架 一.unittest简单介绍 unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是 ...
- Python+Selenium框架设计篇之-简单介绍unittest单元测试框架
前面文章已经简单介绍了一些关于自动化测试框架的介绍,知道了什么是自动化测试框架,主要有哪些特点,基本组成部分等.在继续介绍框架设计之前,我们先来学习一个工具,叫unittest. unit ...
- go 单元测试框架介绍
最近项目在补充单元测试,这里介绍以下几个go里流行的单元测试框架. gomock gostub monkey Convey 下面介绍下各个框架的主要用途 convey 主要用途是用来组织测试用例的 g ...
- 27. Unittest单元测试框架的介绍与使用
unittest单元测试框架 先贴一下unittest官网地址.unittest文档开头介绍了四个重要的概念:test fixture,test case, test suite, test runn ...
- 推荐:一个写的相当好的介绍C++单元测试框架Google Test (gtest) 教程
原文来自:http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html 虽然有点晚了,还是一口气读完了全部文章.作者言简意赅和明快的风格 ...
- JUnit单元测试框架的使用
http://blog.csdn.net/mao520741111/article/details/51462215 原文地址 http://www.open-open.com/lib/view/op ...
- 走进JavaWeb技术世界11:单元测试框架Junit
JUnit你不知道的那些事儿 转自 老刘 码农翻身 2016-02-24 话说有一次Eric Gamma 坐飞机的时候偶遇Kent Beck(对,就是极限编程和TDD的发起人) , 两位大牛见面寒暄 ...
随机推荐
- 使用Mybatis连接到Mysql报错,WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be esta
在Eclipse中使用springboot整合Mybatis,连接到5.7版本Mysql报错WARN: Establishing SSL connection without server's ide ...
- 如何做好一个优秀的web项目心得
最近利用空余的时间(坐公交车看教程视频),想了很多自己做的做果项目的优缺点,重新了解了前后端分离,前端工程化等概念学习,思考如何打造好一个优秀的web前端项目. 前端准备篇 前端代码规范:制定前端开发 ...
- PHP操作redis之String(字符串)、List(列表)(一)
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key – value 缓存产品有以下三个特点: Redis支持数据的持久 ...
- Error: JAVA_HOME is incorrectly set. Please update F:\hadoop\conf\hadoop-env.cmd解决方法
啥都不说!直接上干货! 打开对应路径下的hadoop-env.cmd 将 set JAVA_HOME=%JAVA_HOME% 更换为绝对路径↓ set JAVA_HOME="E:\Devel ...
- 树莓派3B+学习笔记:9、更改软件源
树莓派系统安装完成后,由于默认软件源服务器访问速度慢,安装软件耗时会很长,可以通过更改软件源来加快软件的安装速度. 系统安装完成后默认软件源如下: 更改镜像源前需要自行查找镜像源,并记下网址: 1.阿 ...
- 《nginx源代码解析》系列分享专栏
<nginx源代码解析>系列分享专栏 解析nginx源代码,从main函数开始,一步步解读nginx运行原理,同时进行nginx第三方模块的开发,努力做到知其然,知其所以然 <ngi ...
- Java线程等待与唤醒
class ThreadA extends Thread{ public ThreadA(String name) { super(name); } public void run() { synch ...
- Springboot启动报Multiple Dockets with the same group name are not supported. The following duplicate groups were discovered.
解决方法: 属于bean重复,根据错误提示剔除多于的Bean引用!
- 20155212 mybash的实现
mybash的实现 题目 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 准备 通过man命令了解fork ...
- 【CS】知识索引汇总
Chapter 7 hello.o -> hello (链接) 一.静态链接 主要是将符号对应起来 两个主要任务:符号解析(符号引用与符号定义的对应).重定位(符号定义与内存位置的对应) 1. ...