Calutor.java
@Before –> @Test –> @ After
package com.sc.zy;
public class Calutor {
public int add(int num1,int num2){
return num1+num2;
}
public int sub(int num1,int num2){
return num1-num2;
}
public int mul(int num1,int num2){
return num1*num2;
}
public int div(int num1,int num2){
if(num2==0){
throw new MyException();
}
return num1/num2;
}
}
MyException.java
package com.sc.zy;
public class MyException extends RuntimeException {
}
CalutorTest.java
package com.sc.zy;
import junit.framework.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 CalutorTest {
private Calutor c;
@BeforeClass
public static void setUpBeforeClass(){
System.out.println("=====static init=======");
}
@AfterClass
public static void tearDownAfterClass(){
System.out.println("=====static destory=======");
}
@Before
public void setUp(){
System.out.println("=======@before=======");
c=new Calutor();
}
@After
public void tearDown(){
System.out.println("=======@after=======");
}
@Test
public void testAdd(){
int sum=c.add(1, 2);
Assert.assertEquals(3, sum);
}
@Test(expected=com.sc.zy.MyException.class)
public void testDiv(){
c.div(1, 0);
}
@Ignore
public void testDiv1(){
int d=c.div(1, 5);
Assert.assertEquals(0, d);
}
}
Junit4.x单元测试
l
单元测试的重要性
l
Junit
是什么?
l
如何书写
Junit4
测试例子?
l
Junit4
中常见注解
l
测试运行器,测试套件
l
参数化测试
单元测试能带来:
l
更
高的代码质量
l
更
少的
Debug
时间
l
自动化
快速测试
l
更多
…
什么是JUnit?
l
为
Java
设计的单元测试框架
l
方便
开发者编写单元测试并运行
l
也
是第一个单元测试框架
l
首先写一个功能类
Calculator.java
l
编写测试类,一般测试类我们习惯如图放置,测试类的名字一般是原类名
+Test
组成,如图:
l
@
Before:Junit
在每个测试方法执行之前都要执行
@Before
注解的方法,完成初始化测试环境。方法名一般叫:
setUp
();
l
@
After:Junit
在每个测试方法执行之后都要执行
@After
注解的方法,完成清理测试环境。方法名一般叫:
tearDown
();
注:上述方法必须是public void 方法名(),方法名随意。
l
@
BeforeClass
:针对所有测试,只执行一次,且必须为
static
void
。方法名一般叫:
setUpBeforeClass
。
l
@
AfterClass:
针对
所有测试,只执行一次,且必须为
static
void
。
方法
名一般叫
:
tearDownAfterClass
。
注:上述方法必须是publicstatic void 方法 名()。
l
@Test
:测试方法,在这里可以测试期望异常和超时
时间。
l
@Ignore
:忽略的测试方法
l
一
个
JUnit
4
的单元测试用例执行顺序为:
@ BeforeClass –> @Before –> @Test –>@After –> @ AfterClass
每
一个测试方法的调用顺序为:@ BeforeClass –> @Before –> @Test –>@After –> @ AfterClass
@Before –> @Test –> @ After
又一个新概念出现了——测试运行器,JUnit中所有的测试方法都是由它负责执行的。JUnit为单元测试提供了默认的测试运行器,但 JUnit并没有限制您必须使用默认的运行器。相反,您不仅可以定制自己的运行器(所有的运行器都继承自org.junit.runner.Runner),而且还可以为每一个测试类指定使用某个具体的运行器。指定方法也很简单,使用注解org.junit.runner.RunWith
如果测试类没有显式的声明使用哪一个测试运行器,JUnit会启动默认的测试运行器执行测试类(比如上面提及的单元测试代码)。一般情况下,默认测试运行器可以应对绝大多数的单元测试要求;当使用JUnit提供的一些高级特性(例如即将介绍的两个特性)或者针对特殊需求定制 JUnit测试方式时,显式的声明测试运行器就必不可少了。
l
在实际项目中,随着项目进度的开展,单元测试类会越来越多,可是直到现在我们还只会一个一个的单独运行测试类,这在实际项目实践中肯定是不可行的。为了解决这个问题,
JUnit
提供了一种批量运行测试类的方法,叫做测试套件。这样,每次需要验证系统功能正确性时,只执行一个或几个测试套件便可以了。测试套件的写法非常简单,您只需要遵循以下规则:
l
创建一个空类作为测试套件的入口。
l
使用注解
org.junit.runner.RunWith
和
org.junit.runners.Suite.SuiteClasses
修饰这个空类。
l
将
org.junit.runners.Suite
作为参数传入注解
RunWith
,以提示
JUnit
为此类使用套件运行器执行。
l
将需要放入此测试套件的测试类组成数组作为注解
SuiteClasses
的参数。
l
保证这个空类使用
public
修饰,而且存在公开的不带有任何参数的构造函数。
l
我们把测试类
TestWordDealUtil
放入了测试套件
RunAllUtilTestsSuite
中,在
Eclipse
中运行测试套件,可以看到测试类
TestWordDealUtil
被调用执行了。测试套件中不仅可以包含基本的测试类,而且可以包含其它的测试套件,这样可以很方便的分层管理不同模块的单元测试代码。但是,
您一定要保证测试套件之间没有循环包含关系,否则无尽的循环就会出现在您的面前
……
。
l
为了保证单元测试的严谨性,我们模拟了不同类型的字符串来测试方法的处理能力,为此我们编写大量的单元测试方法。可是这些测试方法都是大同小异:代码结构都是相同的,不同的仅仅是测试数据和期望值。有没有更好的方法将测试方法中相同的代码结构提取出来,提高代码的重用度,减少复制粘贴代码的烦恼?在以前的
JUnit
版本上,并没有好的解决方法,而现在您可以使用
JUnit
提供的参数化测试方式应对这个问题。
l
测试类必须由
Parameterized
测试运行期修饰
l
准备
数据。数据的准备需要在一个方法中进行
,
该方法需要满足以下条件:
1.
该方法必须由
Parameters
注解修饰
2.
该方法必须是
public static
的
3.
该方法必须返回
Collection
类型
4.
该方法名字不要求,必须是无参的
l
写一个类
由
Parameterized
测试运行期
修饰
l
编写数据准备方法
l
编写类的有参构造方法,该方法与数据准备方法中数组数据的顺序一致。
return Arrays.asList(newObject[][]{
{3,1,2},{5,2,3},{8,1,7},{11,9,1}});
l
编写测试方法
l
例子见备注
package com.anbo.dao;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import static org.junit.Assert.assertEquals;;
@RunWith(Parameterized.class)
public class CalculatorTest {
private int expected;
private int a;
private int b;
public CalculatorTest(int expected,int input1,int input2){
this.expected=expected;
this.a=input1;
this.b=input2;
}
@Parameters
public static Collection dataCo(){
return Arrays.asList(new Object[][]{
{3,1,2},{5,2,3},{8,1,7},{11,9,1}
});
}
@Test
public void testAdd(){
assertEquals(expected,a,b);
}
}