转自:https://www.cnblogs.com/qiyexue/p/6822791.html
环境搭建
这里使用的开发工具是MyEclipse,首先新建一个Java工程,将Junit4的jar包引入,eclipse和MyEclipse都集成了Junit的jar包,详细操作如下图。
1、新增一个Junit的jar包,版本选择Junit4
Junit使用
1、Junit最简单的用法
新建一个类被测试类,里面包含一些测试方法,新建一个测试类
package junit.util;
/**
* 被测试类,通过Junit对此类的方法进行单元测试
*/
public class Claculate {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
public int divide(int a, int b) {
return a / b;
}
}
新建一个Junit的测试类用来测试上面的测试方法,新增Junit的测试类方法如下:
package junit.util;
import static org.junit.Assert.*;
import junit.util.Claculate;
import org.junit.Test;
/**
* junit的测试方法必须使用@Test注解
* 测试方法必须以public void修饰,并且不包含参数
*/
public class ClaculateTest {
@Test
public void testAdd() {
/**
* assertEquals这个方法是一个断言方法
* 第一个参数表示预期的结果
* 第二个参数表示程序的执行结果
* 当预期结果与执行结果是一致的时候,则表示单元测试成功
*/
assertEquals(4, new Claculate().add(1, 3));
}
@Test
public void testSubtract() {
assertEquals(4, new Claculate().subtract(9, 5));
}
@Test
public void testMultiply() {
assertEquals(6, new Claculate().multiply(2, 3));
}
@Test(expected=ArithmeticException.class)
public void testDivide() {
assertEquals(3, new Claculate().divide(9, 0));
}
}
上面的这个测试类,分别对被测试类Claculate的四个方法进行了测试,测试是选择使用Junit方式进行执行,如果想要执行单个测试方法,可以选择单个方法进行执行,可以通过左侧代码栏展开类选择下面的方法或者直接在代码中选中方法名进行执行。具体操作如下图:
对于一个类包含的多个测试方法,可以选中这个类,鼠标右键选择new一个JUnitTest Case,可以选择类中的所有要测试的方法,eclipse会自动帮你生成测试方法体
只需要在每个要测试的方法中添加测试代码即可,如下图;
JUnit的流程
在实际项目中,进行JUnit测试时,通常会涉及到一些初始化的东西,可能有些配置项需要在测试前进行加载的,JUnit提供了一些初始化的方法用于初始化
package junit.util;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class JunitFlowTest {
/**
* @BeforeClass:这个注解表示这个方法会在所有测试方法执行之前执行
* 因为是static修饰的静态方法,所有只会执行一次。通常用来进行一些
* 资源的加载,如通过JUnit测试Spring相关的东西时,可以在这个方法
* 中加载Spring的配置文件
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("this is before class");
}
/**
* @AfterClass:这个注解表示这个方法会在所有方法执行完毕之后执行,通常用来释放资源
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("this is after class");
}
/**
* @Before:这个注解表示这个方法会在每个测试方法执行之前执行一次
* 有多少个测试方法就会执行多少次
*/
@Before
public void setUp() throws Exception {
System.out.println("this is before");
}
/**
* @After:这个注解表示这个方法会在每个测试方法执行之后执行一次
* 有多少个测试方法就会执行多少次
*/
@After
public void tearDown() throws Exception {
System.out.println("this is Down");
}
@Test
public void test1() {
System.out.println("this is test1");
}
@Test
public void test2() {
System.out.println("this is test2");
}
}
/* outPut:
this is before class
this is before
this is test1
this is Down
this is before
this is test2
this is Down
this is after class
*/
测试套件
如果要同时测试多个类,可以新增一个测试套件,将多个所有测试类包含进去,每次执行测试套件类的时候,就会把包含的测试类全都执行一遍,测试代码如下:
package junit.util;
import org.junit.Test;
public class TaskTest1 {
@Test
public void test() {
System.out.println("this is TaskTest1");
}
}
package junit.util;
import org.junit.Test;
public class TaskTest2 {
@Test
public void test() {
System.out.println("this is TaskTest2");
}
}
package junit.util;
import org.junit.Test;
public class TaskTest3 {
@Test
public void test() {
System.out.println("this is TaskTest3");
}
}
package junit.util;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* 测试套件类
* 测试套件是用来组织多个测试类一起运行的,使用 @RunWith注解
* 更改测试运行器为Suite.class,将要测试的类作为数组传入
* 到Suite.SuiteClasses({})中,测试套件类不能包含其他测试方法
*
* 样例如下:
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({ TaskTest1.class, TaskTest2.class, TaskTest3.class })
public class SuiteTest {}
//outPut:
//this is TaskTest1
//this is TaskTest2
//this is TaskTest3
测试套件也可以包含其他的测试套件,具体用法和包含多个测试类是一样的,代码如下:
package junit.util;
import org.junit.Test;
public class TaskTest4 {
@Test
public void test() {
System.out.println("this is TaskTest4");
}
}
package junit.util;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({SuiteTest.class,TaskTest4.class})
public class SuiteTest1 {}
//outPut
//this is TaskTest1
//this is TaskTest2
//this is TaskTest3
//this is TaskTest4
参数化测试
对于一个方法需要进行多种场景进行测试时,可以通过参数化测试减少测试的工作量。用法如下:
package junit.util;
import static org.junit.Assert.assertEquals;
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;
@RunWith(Parameterized.class)
public class ParameterTest {
/**
* 1、更改测试运行器为RunWith(Parameterized.class)
* 2、声明变量用来存放预期值与结果值
* 3、声明一个返回值为Collection的公共静态方法,并使用@Parameters进行修饰
* 4、位测试类声明一个带有参数的公共构造方法,并在其中为声明变量赋值
*/
int except; //用来存储预期结果
int input1; //用来存储第一个输入参数
int input2; //用来存储第二个输入参数
@Parameters
public static Collection<Object[]> initTestData(){
return Arrays.asList(
new Object[][]{
{3,1,2},
{10,5,5},
{6,4,2},
{7,3,4}}
);
}
public ParameterTest(int except,int input1,int input2){
this.except = except;
this.input1 = input1;
this.input2 = input2;
}
@Test
public void testAdd() {
assertEquals(except, new Claculate().add(input1, input2));
}
}
总结及补充:
JUnit的一些注意事项:
- 测试方法必须使用@Test修饰
- 测试方法必须使用public void进行修饰,不能带参数
- 一般使用单元测试会新建一个test目录存放测试代码,在生产部署的时候只需要将test目录下代码删除即可
- 测试代码的包应该和被测试代码包结构保持一致
- 测试单元中的每个方法必须可以独立测试,方法间不能有任何依赖
- 测试类一般使用Test作为类名的后缀
- 测试方法使一般用test作为方法名的前缀
测试失败说明:
- Failure:一般是由于测试结果和预期结果不一致引发的,表示测试的这个点发现了问题
- error:是由代码异常引起的,它可以产生于测试代码本身的错误,也可以是被测试代码中隐藏的bug
一些常用注解:
- @Test:将一个普通方法修饰成一个测试方法
- @Test(excepted=xx.class): xx.class表示异常类,表示测试的方法抛出此异常时,认为是正常的测试通过的
- @Test(timeout=毫秒数) :测试方法执行时间是否符合预期
- @BeforeClass: 会在所有的方法执行前被执行,static方法
- @AfterClass:会在所有的方法执行之后进行执行,static方法
- @Before:会在每一个测试方法被运行前执行一次
- @After:会在每一个测试方法运行后被执行一次
- @Ignore:所修饰的测试方法会被测试运行器忽略
- @RunWith:可以更改测试运行器org.junit.runner.Runner
- Parameters:参数化注解