前言
JUnit 是一个 Java 编程语言的单元测试框架,用于编写可复用测试集的简单框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。 xUnit 是一套基于测试驱动开发的测试框架,有 PythonUnit 、 CppUnit 、 JUnit 等。
Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。
一、基本用法示例
打开需要测试的类,通过按快捷键ctrl + shift + t
,选择Create New Test
,在出现的对话框的下面 Member 内勾选要测试的方法。
待测方法:
public class Caculator {
public int add(int a, int b) {
//将加法器故意设置为错误
return a + b -1;
}
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;
}
}
编写测试代码:
public class CaculatorTest {
Caculator caculator = new Caculator();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void add() {
int result = caculator.add(2, 3);
/*
* @param
* message:错误提示信息
* expected:预期值
* actual:实际值
*/
Assert.assertEquals("something wrong with function add()", 5, result);
}
@Test
public void subtract() {
int result = caculator.subtract(3, 1);
Assert.assertEquals("something wrong with function subtract()", 2, result);
}
@Test
public void multiply() {
}
@Test
public void divide() {
}
}
测试结果:
二、使用详解
1. JUnit 断言
Junit所有的断言都包含在 Assert 类中。
这个类提供了很多有用的断言方法来编写测试用例。只有失败的断言才会被记录。Assert 类中的一些方法列式如下:
void assertEquals(boolean expected, boolean actual):检查两个变量或者等式是否平衡
void assertTrue(boolean expected, boolean actual):检查条件为真
void assertFalse(boolean condition):检查条件为假
void assertNotNull(Object object):检查对象不为空
void assertNull(Object object):检查对象为空
void assertSame(boolean condition):assertSame() 方法检查两个相关对象是否指向同一个对象
void assertNotSame(boolean condition):assertNotSame() 方法检查两个相关对象是否不指向同一个对象
void assertArrayEquals(expectedArray, resultArray):assertArrayEquals() 方法检查两个数组是否相等
2. JUnit 注解
@Test:这个注释说明依附在 JUnit 的 public void 方法可以作为一个测试案例。
@Before:有些测试在运行前需要创造几个相似的对象。在 public void 方法加该注释是因为该方法需要在 test 方法前运行。
@After:如果你将外部资源在 Before 方法中分配,那么你需要在测试运行后释放他们。在 public void 方法加该注释是因为该方法需要在 test 方法后运行。
@BeforeClass:在 public void 方法加该注释是因为该方法需要在类中所有方法前运行,static修饰。
@AfterClass:它将会使方法在所有测试结束后执行,可以用来进行清理活动,static修饰。
@Ignore:所修饰的测试方法会被测试运行器忽略
JUnit 注解执行过程
beforeClass(): 方法首先执行,并且只执行一次。
afterClass():方法最后执行,并且只执行一次。
before():方法针对每一个测试用例执行,但是是在执行测试用例之前。
after():方法针对每一个测试用例执行,但是是在执行测试用例之后。
//在 before() 方法和 after() 方法之间,执行每一个测试用例。
3. JUnit 时间测试
如果一个测试用例比起指定的毫秒数花费了更多的时间,那么 Junit 将自动将它标记为失败。timeout参数(单位为毫秒)和 @Test 注释一起使用。
@Test(timeout=1000)
4.JUnit测试套件
将要运行的测试类集成在我们的测试套件中,比如一个系统功能对应一个测试套件,一个测试套件中包含多个测试类,每次测试系统功能时,只要执行一次测试套件就可以了。捆绑几个单元测试用例并且一起执行他们。在 JUnit 中,@RunWith
和@Suite
注释用来运行套件测试。
@Runwith(Suite.class)
@Suite.SuiteClasses({
Test1.class,
Test2.class
})//Suite.SuiteClasses()中放入测试套件的测试类,以数组的形式{class1,class2,......}作为参数
public class TestSuite{
//...
}
三、参数化设置
步骤:
①要进行参数化测试,需要在类上面指定如下的运行器:
@RunWith (Parameterized.class)
②然后,在提供数据的方法上加上一个@Parameters注解,这个方法必须是静态static的,并且返回一个集合Collection。
③在测试类的构造方法中为各个参数赋值,(构造方法是由JUnit调用的),最后编写测试类,它会根据参数的组数来运行测试多次。
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class GetRowTest {
//测试功能:四子棋游戏中,返回当前玩家确认在第col列落子后棋子所在的行row
//表示当前待测棋盘矩阵
@Parameterized.Parameter(0)
public int[][] checkBoard;
//表示落子所属列
@Parameterized.Parameter(1)
public int colum;
//预期的返回所在行数
@Parameterized.Parameter(2)
public int expected;
//被检测的对象
Board board;
@Parameterized.Parameters(name = "{index}:getRow[{0},{1}]={2}")
public static Collection data() {
return Arrays.asList(new Object[][]{
//第一个参数为当前棋盘,第二和第三个参数为当前选择落子列与预期返回行
//在第5列(colum=4)落子,应该返回行数为第3行(expected=2)
{new int[][]{{1, 2, 1, 2, 1, 2, 1},
{2, 1, 2, 1, 2, 1, 2},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}}, 4, 2},
//在第7列(colum=6)落子,应该返回行数为第1行(expected=0)
//这里把expected改为1试试
{new int[][]{{1, 1, 1, 1, 0, 0, 0},
{2, 2, 2, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}}, 6, 1},
}
@Before
public void setUp() throws Exception {
board = new Board();
System.out.println("setUp");
}
@After
public void tearDown() throws Exception {
board = null;
System.out.println("tearDown");
}
@Test
//完成测试方法,会自动完成对多组数据的测试
public void getRow() {
board.setBoard(checkBoard);
assertEquals(expected, board.getRow(colum));
}
}
测试结果:
注:上述代码中,此段相当于实现了测试类的构造函数。
@Parameterized.Parameter(0)
public int[][] checkBoard;
@Parameterized.Parameter(1)
public int colum;
@Parameterized.Parameter(2)
public int expected;
@Parameterized.Parameters
public static Collection data(){
//···
}
可以用以下代码代替:
public int[][] checkBoard;
public int colum;
public int expected;
public GetRowTest( int[][] checkBoard,int colum, int expected) {
this.expected = expected;
this.checkBoard = checkBoard;
this.colum = colum;
}
总结
课件笔记