junit4使用了注解进行操作,相比于junit3更为方便,对于其他框架的集成也更便于搭建。
一:junit搭建
导包:可以通过eclipse自带的junit4包,但是推荐自己找一个junit 4 的包,便于团队开发的使用
搭建:在项目中建立一个静态资源文件夹(source folder)test,在该文件夹下建立测试类,包名同被测试类的包名,类名最好后缀加Test
例:被测试类在java文件夹下包名为conver.tools; 类名 Demo
测试类在test文件夹下包名为convert.tools;类名 DemoTest
二:测试分类及基本使用
待测试的类:
package convert.tools;
/**
* 单元测试待测方法示例
* @author Aikes
*
*/
public class Demo {
public int sum(int a,int b){
return a+b;
}
public int mul(int a,int b){
return a*b;
}
public int sqr(int x) {
return x*x;
}
/**
* 超时测试
*/
public void timeout() {
for(;;) {
}
}
/**
* 异常测试
*/
public void nullPointer() {
String str = null;
System.out.println(str.length());
}
}
对应的测试类:
package convert.tools;
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 convert.tools.Demo;
import junit.framework.Assert;
/**
* 本类讲述junit单元测试的基础使用方法:
*
* 测试类包名需要与被测试类包名相同
*
* @author Aikes
*
*/
public class DemoTest {
public Demo d;
public static int start;
public static int end;
/**
* 测试类加载后首先执行得方法,运行期仅执行一次,用于公共资源的加载
*/
@BeforeClass
public static void BeforeClass() {
System.out.println("@BeforeClass: onceExecutedBeforeAll");
}
/**
* 该方法在每个test方法前均会执行
*/
@Before
public void before() {
d = new Demo();
System.out.println("@Before: executedBeforeEachMethod--第" + (++start) + "个测试方法开始执行");
}
//***************************常用的测试方法*****************************
/**
* 1---->超时测试
* Timeout 参数表明了你要设定的时间,单位为毫秒,因此 1000 就代表 1 秒。
* 若超过时间测试程序会终止
* 指定时间内执行完,测试程序通过
*/
@Test(timeout = 1000)
public void Test1() {
System.out.println("@Test: -----------------------------Test1");
d.timeout();
}
/**
* 2---->异常测试
* 如下述代码所示,我们需要使用@Test标注的expected属性,将我们要检验的
* 异常传递给他,这样JUnit框架就能自动帮我们检测是否抛出了我们指定的异常。
* 若没有抛出指定异常,测试程序终止
* 抛出指定异常,测试程序通过
*/
@Test(expected = NullPointerException.class)
public void Test2() {
System.out.println("@Test: -----------------------------Test2");
d.nullPointer();
}
/**
* 3---->参数化测试--->ParameterTest.java
*
* 4---->打包测试测试--->SuiteTest.java
*
*/
/**
* 5---->断言的使用
* 所谓断言,即预测的程序结果和真实运行的结果进行比较。
* 断言比较若判断false,测试程序终止,后续测试代码不执行
*/
@Test
public void Test3() {
System.out.println("@Test: -----------------------------Test3");
String strNotNull = "1";
String strNull = null;
// Assert.assertNull(java.lang.Object object) 检查对象是否为空
Assert.assertNull(strNull);
// Assert.assertNotNull(java.lang.Object object) 检查对象是否不为空
Assert.assertNotNull(strNotNull);
// Assert.assertEquals(long expected, long actual) 检查long类型的值是否相等
Assert.assertEquals(1, 2);
// Assert.assertEquals(double expected, double actual, double delta) 检查指定精度的double值是否相等(允许delta的误差)
Assert.assertEquals(1, 2 , 0.1);
// Assert.assertFalse(boolean condition) 检查条件是否为假
Assert.assertFalse(true);
// Assert.assertTrue(boolean condition) 检查条件是否为真
Assert.assertTrue(true);
// Assert.assertSame(java.lang.Object expected, java.lang.Object actual) 检查两个对象引用是否引用同一对象(即对象是否相等)
Assert.assertSame(new String(),new String());
// Assert.assertNotSame(java.lang.Object un expected, java.lang.Object actual) 检查两个对象引用是否不引用统一对象(即对象不等)
Assert.assertNotSame(new String(),new String());
}
/**
* 不加注解的测试方法不会执行
*/
public void Test4() {
System.out.println("@Test: -----------------------------Test4");
}
/**
* 忽略该方法的测试,一般用于打包测试中使用(批量执行多个测试类中,部分测试方法需要被忽略)
*/
@Ignore
public void executionIgnored() {
System.out.println("@Ignore: This execution is ignored");
}
/**
* 该方法在每个test方法后均会执行
*/
@After
public void after() {
System.out.println("@After: executedAfterEachMethod----第" + (++end) + "个测试方法执行结束");
}
/**
* 测试类运行结束前最后执行的方法,运行期仅执行一次,用于公共资源的释放
*/
@AfterClass
public static void AfterClass() {
System.out.println("@AfterClass: onceExecutedAfterAll");
}
}
参数化测试:
这里需要注意,无论被测试的方法有多少参数,都是可以这样使用的,之前在网上没有找到相关方法,所以一直以为只能测试单参数方法。
实际上object数组中可以添加成多个参数,只要在测试类中定义相应数量的全局变量即可。
package convert.tools;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* 参数化测试
* 通过传入不同的参数测试一段程序逻辑是否完整
* @author Aikes
*
*/
@RunWith(Parameterized.class)//这个是指定使用的单元测试执行类,一般参数化测试指定用该类进行测试
public class ParameterTest {
private Demo demo ;
//待测试的方法需要传入几个参数就在该类中定义几个全局变量
//本例中待测方法有两个参数,所以定义为paramA和paramB
private int paramA;
private int paramB;
//预期结果
private int result;
@Before
public void init(){
demo = new Demo();
}
/**
*
* 1.使用@Parameters注解的方法必须是
* 返回值为集合的静态方法
* 2.在该方法中向集合里添加object二维数组,每一组中为
* 需要测试用到的参数以及预期的结果
* new Object[]{param11,param12,result1}
*
* @return
*/
@Parameters
public static Collection<Object[]> d() {
List<Object[]> list = new ArrayList<Object[]>();
//设定三种参数形式 参数,参数,预期结果
list.add(new Object[] { 2 , 3, 5 });
list.add(new Object[] { 0, 0, 0 });
list.add(new Object[] {-3, -3, 9 });
return list;
}
// 构造函数,对变量进行初始化,包括方法中需要传入的参数和预期结果
public ParameterTest(int paramA,int paramB, int result) {
this.paramA = paramA;
this.paramB = paramB;
this.result = result;
}
/**
* 测试方法的参数用全局变量
*/
@Test
public void TestSum() {
int a = demo.sum(paramA,paramB);
System.out.println(paramA+":"+paramB+":"+result);
assertEquals(result, a);
}
}
打包测试:
用于批量执行多个测试类中的测试方法
package convert.tools;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
/**
* Junit 4允许通过使用测试套件类批量运行测试类.
* @author Aikes
*/
//指定测试程序执行类为Suite.class
@RunWith(Suite.class)
//测试套件将执行这两个class中的所有测试方法
@SuiteClasses({DemoTest.class,ParameterTest.class})
public class SuitTest {
}
虽然我们大部分时候都不用单元测试,有简单的main方法就可以实现为什么还要这么复杂呢?
但是通过junit测试可以让测试记录保留下来,在之后代码出错也可以很快的排查,使用参数化测试也可以更加全面的对程序进行检测,通过大量数据对程序逻辑的严谨性进行测评,最重要的是这样有序的测试让团队开发变得更加井然有序,从方方面面培养出程序员的基本规范。
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。