JUint是Java编程语言的单元测试框架,用于编写和运行可重复的自动化测试。
JUnit 促进了“先测试后编码”TDD的理念,强调建立测试数据的一段代码,可以先测试,然后再应用。这个方法就好比“测试一点,编码一点,测试一点,编码一点……”,增加了程序员的产量和程序的稳定性,可以减少程序员的压力和花费在排错上的时间。
TDD 是Test-Driven Development(测试驱动开发)的缩写。
注解 | 描述 |
---|---|
@Test | 测试注解,标记一个方法可以是测试用例 |
@Before | Before注解表示,该方法必须在类中的每个测试之前执行,以便执行某些必要的先决条件。每个测试方法都会运行一次 |
@BeforeClass | BeforeClass注解指出这是附着在静态方法必须执行一次并在类的所有测试之前,这种情况一般用于测试计算、共享配制方法(如数据库连接)。每个测试类只运行一次 |
@After | After注释表示,该方法在每项测试后执行(如执行每一个测试后重置某些变量,删除临时变量等)。每个测试方法都会运行一次 |
@AfterClass | 当需要执行所有测试在JUnit测试用例类后执行,AlterClass注解可以使用以清理一些资源(如数据库连接),注意:方法必须为静态方法。每个测试类只运行一次 |
@Ignore | 当想暂时禁用特定的测试执行可以使用这个注解,每个被注解为@Ignore的方法将不再执行 |
@Runwith | 放在测试类名之前,用来确定这个类怎么运行的。也可以不标注,会使用默认运行器。 |
@SuiteClasses | 用于套件测试 |
@Parameters | 用于使用参数化功能。 |
断言 | 描述 |
---|---|
void assertArrayEquals([String message],expectedArray,resultArray) | 断言预期数组和结果数组相等,数组类型可能是int,short,long,byte,char,Object |
void assertEquals([String message],expected value,actual value) | 断言两个值相等。值类型可能是int,short,long,byte,char,Object,第一个参数是一个可选字符串消息 |
void assertFalse([String message],boolean condition) | 断言一个条件为假 |
void assertTrue([String message],boolean condition) | 断言一个条件为真 |
void assertNotSame([String message],java.lang.Object unexpected,java.lang.Object actual) | 断言两个对象不是引用同一个对象 |
void assertSame([String message],java.lang.Object expected,java.lang.Object actual) | 断言两个对象引用相同的对象 |
void assertNull([String message],java.lang.Object object) | 断言一个对象为空(null) |
void assertNotNull([String message],java.lang.Object object) | 断言一个对象不为空(null) |
import org.junit.Assert;
import org.junit.Test;
public class AssertionTest {
@Test
public void test() {
String obj1 = "junit";
String obj2 = "junit";
String obj3 = "test";
String obj4 = "test";
String obj5 = null;
int var1 = 1;
int var2 = 2;
int[] array1 = {
1, 2, 3};
int[] array2 = {
1, 2, 3};
Assert.assertEquals(obj1, obj2);
Assert.assertSame(obj3, obj4);
Assert.assertNotSame(obj2, obj4);
Assert.assertNotNull(obj1);
Assert.assertNull(obj5);
Assert.assertTrue(var1 < var2);
Assert.assertFalse(var1 > var2);
Assert.assertArrayEquals(array1, array2);
}
}
import org.junit.*;
/**
* junit的执行过程
* @author BZR
*
*/
public class JunitTest1 {
/**
* 只执行一次
*/
@BeforeClass
public static void beforeClass() {
System.out.println("in before class");
}
/**
* 只执行一次
*/
@AfterClass
public static void afterClass() {
System.out.println("in after class");
}
/**
* 执行了多少个@Test就执行几次
*/
@Before
public void before() {
System.out.println("in before");
}
/**
* 执行了多少个@Test就执行了几次
*/
@After
public void after() {
System.out.println("in after");
}
@Test
public void testCase1() {
System.out.println("in test case 1");
}
@Test
public void testCase2() {
System.out.println("in test case 2");
}
}
import org.junit.*;
/**
* junit的忽略测试
* @author BZR
*
*/
public class JunitTest1 {
@Ignore
@Test
public void testCase2() {
System.out.println("in test case 2");
}
}
import org.junit.Test;
import java.util.concurrent.TimeUnit;
public class JunitTimeTest {
@Test(timeout = 1000) //毫秒
public void testCase1() throws InterruptedException {
TimeUnit.SECONDS.sleep(5); //秒
System.out.println("in test case 1");
}
}
import org.junit.Test;
public class JunitTestException {
@Test(expected = ArithmeticException.class)
public void testCase3() {
int a = 0;
int b = 1 / a;
}
}
Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试。你将遵循 5 个步骤来创建参数化测试:
首先要分清几个概念:测试方法、测试类、测试集、测试运行器。
1.其中测试方法就是用@Test注解的一些函数。
2.测试类是包含一个或多个测试方法的一个**Test.java文件,
3.测试集是一个suite,可能包含多个测试类。
4.测试运行器则决定了用什么方式偏好去运行这些测试集/类/方法。 而@Runwith就是放在测试类名之前,用来确定这个类怎么运行的。也可以不标注,会使用默认运行器。常见的运行器有:
5.@RunWith(Parameterized.class) 参数化运行器,配合@Parameters使用JUnit的参数化功能
6.@RunWith(Suite.class)
7.@SuiteClasses({ATest.class,BTest.class,CTest.class})
8.测试集运行器配合使用测试集功能
9.@RunWith(JUnit4.class), junit4的默认运行器
10.@RunWith(JUnit38ClassRunner.class),用于兼容junit3.8的运行器
11.一些其它运行器具备更多功能。例如@RunWith(SpringJUnit4ClassRunner.class)集成了spring的一些功能
import org.junit.Assert;
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;
/**
* 步骤一: 指定定参数运行器
*/
@RunWith(Parameterized.class)
public class PrimeNumberCheckerTest {
/**
* 步骤二:声明变量
*/
private Integer inputNumber;
private Boolean expectedResult;
private PrimeNumberChecker primeNumberChecker;
/**
* 步骤三:为测试类声明一个带有参数的公共构造函数,为变量赋值
*/
public PrimeNumberCheckerTest(Integer inputNumber,
Boolean expectedResult) {
this.inputNumber = inputNumber;
this.expectedResult = expectedResult;
}
/**
* 步骤四:为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的,返回值为
* java.util.Collection 的公共静态方法,并在此方法中初始化所有需要测试的参数对
* 1)该方法必须由Parameters注解修饰
2)该方法必须为public static的
3)该方法必须返回Collection类型
4)该方法的名字不做要求
5)该方法没有参数
*/
@Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][]{
{
2, true},
{
6, false},
{
19, true},
{
22, false},
{
23, true}
});
}
@Before
public void initialize() {
primeNumberChecker = new PrimeNumberChecker();
}
/**
* 步骤五:编写测试方法,使用自定义变量进行测试
*/
@Test
public void testPrimeNumberChecker() {
System.out.println("Parameterized Number is : " + inputNumber);
Assert.assertEquals(expectedResult,
primeNumberChecker.validate(inputNumber));
}
}
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
/**
* 这里的配置影响程序运行的顺序
*/
JunitTest2.class,
JunitTest3.class
})
public class JunitSuite {
}
import org.junit.Ignore;
import org.junit.Test;
public class JunitTest2 {
@Ignore
@Test
public void printMessage(){
System.out.println("in JunitTest2");
}
}
import org.junit.Test;
public class JunitTest3 {
@Test
public void printMessage(){
System.out.println("in JunitTest3");
}
}
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>