Junit4单元测试框架的常用方法介绍
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
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)
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)。