Junit4

Junit是一个可编写重复测试的简单框架,是基于Xunit架构的单元测试框架的实例。Junit4最大的改进是大量使用注解(元数据),很多实际执行过程都在Junit的后台做完了,而且写test case 的类不需要继承TestCase,只需要在所要做test case的方法前加@Test 注解即可。

如:


复制代码
1 import static org.junit.Assert.*;
2 2 public class TestCaculatorClass {
3 3 @Test
4 4 public void test() throws IOException, RuntimeException{
5 5 CaculatorClassForTest cal = new CaculatorClassForTest();
6 6 assertEquals(30, cal.sum(10, 20));
7 7 }
8 8 }
复制代码
直接点击右键,run as... Junit Test即可运行此test case。

Assert类里面有很多assert方法,包括:assertEquals(), assertNotNull(),assertTtrue(),assertFalse(),assertThat()等,其中assertThat用的是match的形式。

因此,Junit提供很多中Match,其中CoreMatchers是其中一个比较完善的实现类。具体有上面方法可以查阅CoreMatchers类。


复制代码
1 import static org.hamcrest.CoreMatchers.allOf;
2 import static org.hamcrest.CoreMatchers.anyOf;
3 import static org.hamcrest.CoreMatchers.equalTo;
4 import static org.hamcrest.CoreMatchers.not;
5 import static org.hamcrest.CoreMatchers.sameInstance;
6 import static org.hamcrest.CoreMatchers.startsWith;
7 import static org.junit.Assert.assertThat;
8 import static org.junit.matchers.JUnitMatchers.both;
9 import static org.junit.matchers.JUnitMatchers.containsString;
10 import static org.junit.matchers.JUnitMatchers.everyItem;
11 import static org.junit.matchers.JUnitMatchers.hasItems;
12
13 import java.util.Arrays;
14
15 import org.hamcrest.core.CombinableMatcher;
16 import org.junit.Test;
17
18 public class AssertTests {
19 @Test
20 public void testAssertArrayEquals() {
21 byte[] expected = "trial".getBytes();
22 byte[] actual = "trial".getBytes();
23 org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);
24 }
25
26 @Test
27 public void testAssertEquals() {
28 org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);
29 }
30
31 @Test
32 public void testAssertFalse() {
33 org.junit.Assert.assertFalse("failure - should be false", false);
34 }
35
36 @Test
37 public void testAssertNotNull() {
38 org.junit.Assert.assertNotNull("should not be null", new Object());
39 }
40
41 @Test
42 public void testAssertNotSame() {
43 org.junit.Assert.assertNotSame("should not be same Object", new Object(), new Object());
44 }
45
46 @Test
47 public void testAssertNull() {
48 org.junit.Assert.assertNull("should be null", null);
49 }
50
51 @Test
52 public void testAssertSame() {
53 Integer aNumber = Integer.valueOf(768);
54 org.junit.Assert.assertSame("should be same", aNumber, aNumber);
55 }
56
57 // JUnit Matchers assertThat
58 @Test
59 public void testAssertThatBothContainsString() {
60 org.junit.Assert.assertThat("albumen", both(containsString("a")).and(containsString("b")));
61 }
62
63 @Test
64 public void testAssertThathasItemsContainsString() {
65 org.junit.Assert.assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
66 }
67
68 @Test
69 public void testAssertThatEveryItemContainsString() {
70 org.junit.Assert.assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
71 }
72
73 // Core Hamcrest Matchers with assertThat
74 @Test
75 public void testAssertThatHamcrestCoreMatchers() {
76 assertThat("good", allOf(equalTo("good"), startsWith("good")));
77 assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
78 assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
79 assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
80 assertThat(new Object(), not(sameInstance(new Object())));
81 }
82
83 @Test
84 public void testAssertTrue() {
85 org.junit.Assert.assertTrue("failure - should be true", true);
86 }
87 }
复制代码
问题一,我可不可以把多个测试类放在一起执行?

回答: 可以。org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...);利用这样,把test case 的类放进去,然后放在main()方法里执行。

问题二,@RunWith这个注解有什么作用?

回答:Junit4的默认runner为BlockJunit4ClassRunner,但是Junit4包括第三方软件还提供很多其他的runner,这样如果,我们想让我们的测试类用专门的runner来运行,这时候就可以用@RunWith(Suit.class

)标注测试类。其他特殊的runner有:

1. Suite: 字面理解是一个套装,通俗地讲,就是你可以把很多测试类放在一起,然后建一个类,标注为Suite.class,那么如果执行这个类,就会把所有的测试类一起执行。


复制代码
1 import org.junit.runner.RunWith;
2 import org.junit.runners.Suite;
3
4 @RunWith(Suite.class)
5 @Suite.SuiteClasses({
6 TestFeatureLogin.class,
7 TestFeatureLogout.class,
8 TestFeatureNavigate.class,
9 TestFeatureUpdate.class
10 })
11
12 public class FeatureTestSuite {
13 // the class remains empty,
14 // used only as a holder for the above annotations
15 }
复制代码


2. Parameterized:根据所设计的参数来执行测试。假设我们要测试某一个方法,它有两个参数,每个参数需要设计不同值,那么我们最开始就是需要为每个参数设计一个测试方法,这样就很麻烦,10种case就得10个方法,但是有了Parameterized runner,我们可以设计一个方法,多种参数来执行test case。


复制代码
1 package com.citi.risk.core.test.impl;
2
3 public class CaculatorClassForTest {
4
5 private int o1;
6 private int o2;
7 public int getO1() {
8 return this.o1;
9 }
10 public void setO1(int value) {
11 this.o1 = value;
12 }
13 public int getO2() {
14 return this.o2;
15 }
16 public void setO2(int value) {
17 this.o2 = value;
18 }
19
20
21 public CaculatorClassForTest() {}
22 public CaculatorClassForTest(int o1, int o2) {
23 this.o1 = o1;
24 this.o2 = o2;
25 }
26
27 public int sum(int o1, int o2){
28 if(o1 > 200) {
29 throw new RuntimeException("o1 is too big");
30 }
31 if(o2 > 200) {
32 throw new RuntimeException("o2 is too big");
33 }
34 int sum;
35 sum = o1 + o2;
36 return sum;
37 }
38 }
复制代码





复制代码
1 package com.citi.risk.core.test.impl;
2
3 import static org.junit.Assert.*;
4
5 import java.io.IOException;
6 import java.util.List;
7
8 import org.junit.Rule;
9 import org.junit.Test;
10 import org.junit.rules.ExpectedException;
11 import org.junit.runner.RunWith;
12 import org.junit.runners.Parameterized;
13 import org.junit.runners.Parameterized.Parameter;
14 import org.junit.runners.Parameterized.Parameters;
15
16 import com.google.common.collect.Lists;
17
18 @RunWith(Parameterized.class)
19 public class TestCaculatorClass {
20 @Rule
21 public ExpectedException thrown = ExpectedException.none();
22
23 @Parameters
24 public static List<Object[]> data() {
25 return Lists.asList(new Object[]{-1, 1, 0}, new Object[][]{{20, 20, 40},{30, 30, 60},{-5, -5, -10}});
26 }
27 @Parameter(value = 0)
28 public int o1;
29 @Parameter(value = 1)
30 public int o2;
31 @Parameter(value = 2)
32 public int expector;
33
34 @Test
35 public void test() throws IOException, RuntimeException{
36 CaculatorClassForTest cal = new CaculatorClassForTest();
37 assertEquals(expector, cal.sum(o1, o2));
38 }
39
40 @Test
41 public void testO1Exception(){
42 CaculatorClassForTest cal = new CaculatorClassForTest();
43 thrown.expect(RuntimeException.class);
44 thrown.expectMessage("o1 is too big");
45 cal.sum(300, 100);
46 }
47 @Test
48 public void testO2Exception(){
49 CaculatorClassForTest cal = new CaculatorClassForTest();
50 thrown.expect(RuntimeException.class);
51 thrown.expectMessage("o2 is too big");
52 cal.sum(100, 300);
53 }
54
55 }
复制代码


以上两个类就是测试了Parameterized runner, 参数会自动匹配。它其实就是,看我们传入几种case, 也就是List.size(),然后,把类里面的方法,循环重复执行size()数目。

3. Categories:容易理解就是分类执行。假设我们有一种case: 我们写好了两个测试类,类A,类B,A有两个方法a(), b(),这时候我们有一个类来执行这两个类的test case,但是我们在类A里只想执行A.b(),但却不执行A.a(),这个时候我们可以用Categories runner。


复制代码
1 public interface FastTests { /* category marker */ }
2 public interface SlowTests { /* category marker */ }
3
4 public class A {
5 @Test
6 public void a() {
7 fail();
8 }
9
10 @Category(SlowTests.class)
11 @Test
12 public void b() {
13 }
14 }
15
16 @Category({SlowTests.class, FastTests.class})
17 public class B {
18 @Test
19 public void c() {
20
21 }
22 }
23
24 @RunWith(Categories.class)
25 @IncludeCategory(SlowTests.class)
26 @SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
27 public class SlowTestSuite {
28 // Will run A.b and B.c, but not A.a
29 }
30
31 @RunWith(Categories.class)
32 @IncludeCategory(SlowTests.class)
33 @ExcludeCategory(FastTests.class)
34 @SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
35 public class SlowTestSuite {
36 // Will run A.b, but not A.a or B.c
37 }
复制代码

4. Enclosed:如果我们把tests放在了内部类,这时候执行外部类是无法执行里面的test cases,这种情况下,就应该在outer class 用Enclosed runner。

要测试的类 Address:

View Address Code
test case:

View AddressTest Code
问题三:不想执行某个类的test case 有什么方法?

回答: 用@Ignore, 如果要让某个类都不执行,@Ignore放在类里,如果不想执行某一个方法,只需要放在方法上。

复制代码
1 @Ignore
2 public class TestClass{
3
4 @Ignore("Test is ignored as a demonstration")
5 @Test
6 public void testSane() {
7 assertThat(1, is(1));
8 }
9 }
复制代码
问题四:某个test case执行时间太长,有什么办法终止?

回答: Junit4提供了timeout属性。

1 @Test(timeout=1000)
2 public void testWithTimeout() {
3 ...
4 }


Junit4还有更重要的@Rule 和 执行顺序。且听下回分解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值