JUnit4 用法总结

常用注解

  • @Test
    被标注方法需要为public, 无返回值
  • @Before, @After
    在每个测试前后均执行被标注的方法
  • @BeforeClass, @AfterClass
    方法必须为静态. 每个单元测试类, 在所有测试用例前后执行一次
  • @RunWith
    • 默认情况下相当于指定了@RunWith(JUnit4.class), 以BlockJUnit4ClassRunner运行测试
    • @RunWith(Suite.class), 可配合`@Suite.SuiteClasses`, 用来执行一组测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@RunWith(Suite.class)
@Suite.SuiteClasses({
FixturesTest.Sub.class,
FixturesTest.Parent.class
})
public class FixturesTest {

public static class Sub extends Parent {

@BeforeClass
public static void subBeforeClass() {
System.out.println("sub before class +++");
}


@AfterClass
public static void subAfterClass() {
System.out.println("sub after class +++");
}

@Before
public void subBefore() {
System.out.println("sub before");
}

@After
public void subAfter() {
System.out.println("sub after");
}

@Test
public void test1() {
System.out.println("sub test1");
}

@Test
public void test2() {
System.out.println("sub test2");
}
}

public static class Parent {
@BeforeClass
public static void parentBeforeClass() {
System.out.println("parent before class ----");
}


@AfterClass
public static void parentAfterClass() {
System.out.println("parent after class ---- ");
}

@Before
public void parentBefore() {
System.out.println("parent before -");
}

@After
public void parentAfter() {
System.out.println("parent after -");
}

@Test
public void parentTest() {
System.out.println("parent test");
}
}
}

返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
parent before class ----
sub before class +++
parent before -
sub before
sub test1
sub after
parent after -
parent before -
sub before
sub test2
sub after
parent after -
parent before -
sub before
parent test
sub after
parent after -
sub after class +++
parent after class ----
parent before class ----
parent before -
parent test
parent after -
parent after class ----

断言

import static org.hamcrest.CoreMatchers.*;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Test
public void assertBaseTest() {
Assert.assertEquals("aaa", "aaa");
Assert.assertTrue(true);
Assert.assertArrayEquals(new int[]{1, 3, 5}, new int[]{1, 3, 5});

// same 用的是 == , 比较的是引用对象是否相同
Assert.assertSame(1, 1);
Assert.assertNotSame(new Integer(1), new Integer(1));

Assert.assertSame("aaa", "aaa");
Assert.assertNotSame(new String("a"), new String("a"));

}

@Test
public void assertThatTest() {
Assert.assertThat("good", allOf(
equalTo("good"), startsWith("good")
));

Assert.assertThat("good", not(allOf(
equalTo("bad"), equalTo("good")
)));

Assert.assertThat("good", anyOf(
equalTo("bad"), equalTo("good")
));

Assert.assertThat(7, not(
CombinableMatcher.either(equalTo(3)).or(equalTo(4))
));

Assert.assertThat(new Object(), not(sameInstance(new Object())));
}

异常测试

可以指定expected参数, 以下测试均会通过

1
2
3
4
5
6
7
8
9
@Test(expected = IllegalArgumentException.class)
public void exceptionTest() {
throw new IllegalArgumentException();
}

@Test(expected = RuntimeException.class)
public void exceptionTest2() {
throw new IllegalArgumentException();
}

也可以用try/catch形式

1
2
3
4
5
6
7
8
9
@Test
public void exceptionTest3() {
try {
new ArrayList<Object>().get(0);
Assert.fail();
} catch (IndexOutOfBoundsException e) {
Assert.assertEquals(e.getMessage(), "Index: 0, Size: 0");
}
}

超时时间

可指定timeout参数(单位:毫秒). 如果指定时间内测试方法未执行完成, 则终止执行. 抛出TestTimedOutException异常

1
2
3
4
@Test(timeout = 100)
public void timeOutTest() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
}

也可以通过@Rule指定全局超时时间

1
2
3
4
5
6
7
@Rule
public Timeout globalTimeout = Timeout.millis(100);

@Test
public void test() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
}

方法执行顺序

正常情况下, 单元测试不应该与方法的执行顺序有关; 但是也可通过@FixMethodOrder注解更改方法的执行顺序
默认情况下方法的执行顺序与JVM实现有关. 并不确保会按照方法的定义顺序执行.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@FixMethodOrder(MethodSorters.JVM)
public class MethodOrderTest {
@Test
public void testC(){
Assert.assertTrue(true);
}

@Test
public void test(){
Assert.assertTrue(true);
}

@Test
public void testB(){
Assert.assertTrue(true);
}

@Test
public void testA(){
Assert.assertTrue(true);
}

@Test
public void testDGetMethods(){
for(Method m:MethodOrderTest.class.getMethods()){
System.out.println(m.getName());
}
}
}

MethodSorters.NAME_ASCENDING 表示按照字典顺序执行
MethodSorters.JVM, MethodSorters.DEFAULT 执行顺序与JVM实现有关


参考:
JUnit4官网

0%