Junit4详解一:Junit总体介绍
来源:互联网 发布:xp关闭445端口 编辑:程序博客网 时间:2024/05/29 19:46
Junit4详解一:Junit总体介绍
Junit是一个可编写重复测试的简单框架,是基于Xunit架构的单元测试框架的实例。Junit4最大的改进是大量使用注解(元数据),很多实际执行过程都在Junit的后台做完了,而且写test case 的类不需要继承TestCase,只需要在所要做test case的方法前加@Test 注解即可。
如:
1 import static org.junit.Assert.*;2 2 public class TestCaculatorClass {3 3 @Test4 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 @Test20 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 @Test27 public void testAssertEquals() {28 org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);29 }30 31 @Test32 public void testAssertFalse() {33 org.junit.Assert.assertFalse("failure - should be false", false);34 }35 36 @Test37 public void testAssertNotNull() {38 org.junit.Assert.assertNotNull("should not be null", new Object());39 }40 41 @Test42 public void testAssertNotSame() {43 org.junit.Assert.assertNotSame("should not be same Object", new Object(), new Object());44 }45 46 @Test47 public void testAssertNull() {48 org.junit.Assert.assertNull("should be null", null);49 }50 51 @Test52 public void testAssertSame() {53 Integer aNumber = Integer.valueOf(768);54 org.junit.Assert.assertSame("should be same", aNumber, aNumber);55 }56 57 // JUnit Matchers assertThat58 @Test59 public void testAssertThatBothContainsString() {60 org.junit.Assert.assertThat("albumen", both(containsString("a")).and(containsString("b")));61 }62 63 @Test64 public void testAssertThathasItemsContainsString() {65 org.junit.Assert.assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));66 }67 68 @Test69 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 assertThat74 @Test75 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 @Test84 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.class10 })11 12 public class FeatureTestSuite {13 // the class remains empty,14 // used only as a holder for the above annotations15 }
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 @Rule21 public ExpectedException thrown = ExpectedException.none();22 23 @Parameters24 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 @Test35 public void test() throws IOException, RuntimeException{36 CaculatorClassForTest cal = new CaculatorClassForTest();37 assertEquals(expector, cal.sum(o1, o2));38 }39 40 @Test41 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 @Test48 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 @Test12 public void b() {13 }14 }15 16 @Category({SlowTests.class, FastTests.class})17 public class B {18 @Test19 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 Suite27 public class SlowTestSuite {28 // Will run A.b and B.c, but not A.a29 }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 Suite35 public class SlowTestSuite {36 // Will run A.b, but not A.a or B.c37 }
4. Enclosed:如果我们把tests放在了内部类,这时候执行外部类是无法执行里面的test cases,这种情况下,就应该在outer class 用Enclosed runner。
要测试的类 Address:
1 package abstractions.domain; 2 3 import java.io.Serializable; 4 5 import com.google.common.collect.ComparisonChain; 6 7 public class Address implements Serializable, Comparable<Address> { 8 9 private static final long serialVersionUID = 1L;10 private final String address1;11 private final String city;12 private final String state;13 private final String zip;14 15 private Address(Builder builder) {16 this.address1 = builder.address1;17 this.city = builder.city;18 this.state = builder.state;19 this.zip = builder.zip;20 }21 22 public String getAddress1() {23 return address1;24 }25 26 public String getCity() {27 return city;28 }29 30 public String getState() {31 return state;32 }33 34 public String getZip() {35 return zip;36 }37 38 @Override39 public int compareTo(Address that) {40 return ComparisonChain.start().compare(this.zip, that.zip).compare(this.state, that.state)41 .compare(this.city, that.city).compare(this.address1, that.address1).result();42 }43 44 @Override45 public boolean equals(Object obj) {46 if (obj == null) { return false; }47 if (getClass() != obj.getClass()) { return false; }48 final Address that = (Address) obj;49 50 return com.google.common.base.Objects.equal(this.address1, that.address1)51 && com.google.common.base.Objects.equal(this.city, that.city)52 && com.google.common.base.Objects.equal(this.state, that.state)53 && com.google.common.base.Objects.equal(this.zip, that.zip);54 }55 56 @Override57 public int hashCode() {58 return com.google.common.base.Objects.hashCode(getAddress1(), getCity(), getCity(), getState(), getZip());59 }60 61 @Override62 public String toString() {63 return com.google.common.base.Objects.toStringHelper(this).addValue(getAddress1()).addValue(getCity()).addValue(getState()).addValue(getZip()).toString();64 }65 66 public static class Builder {67 68 private String address1;69 private String city;70 private String state;71 private String zip;72 73 public Builder address1(String address1) {74 this.address1 = address1;75 return this;76 }77 78 public Address build() {79 return new Address(this);80 }81 82 public Builder city(String city) {83 this.city = city;84 return this;85 }86 87 public Builder state(String state) {88 this.state = state;89 return this;90 }91 92 public Builder zip(String zip) {93 this.zip = zip;94 return this;95 }96 }97 }
test case:
1 package abstractions.domain; 2 3 import static org.hamcrest.Matchers.is; 4 import static org.junit.Assert.assertThat; 5 6 import java.io.Serializable; 7 8 import org.junit.Before; 9 import org.junit.Test; 10 import org.junit.experimental.runners.Enclosed; 11 import org.junit.runner.RunWith; 12 13 import testhelpers.ComparabilityTestCase; 14 import testhelpers.EqualsHashCodeTestCase; 15 import testhelpers.SerializabilityTestCase; 16 17 /** 18 * The Class AddressTest. 19 */ 20 @RunWith(Enclosed.class) 21 public class AddressTest { 22 23 /** 24 * The Class AddressComparabilityTest. 25 */ 26 public static class AddressComparabilityTest extends ComparabilityTestCase<Address> { 27 28 @Override 29 protected Address createEqualInstance() throws Exception { 30 return new Address.Builder().address1("2802 South Havana Street").city("Aurora").state("CO").zip("80014").build(); 31 } 32 33 @Override 34 protected Address createGreaterInstance() throws Exception { 35 return new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build(); 36 } 37 38 @Override 39 protected Address createLessInstance() throws Exception { 40 return new Address.Builder().address1("14 Broad St").city("Nashua").state("NH").zip("03064").build(); 41 } 42 } 43 44 /** 45 * The Class AddressEqualsHashCodeTest. 46 */ 47 public static class AddressEqualsHashCodeTest extends EqualsHashCodeTestCase { 48 49 @Override 50 protected Address createInstance() throws Exception { 51 return new Address.Builder().address1("2802 South Havana Street").city("Aurora").state("CO").zip("80014").build(); 52 } 53 54 @Override 55 protected Address createNotEqualInstance() throws Exception { 56 return new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build(); 57 } 58 } 59 60 /** 61 * The Class AddressSerializabilityTest. 62 */ 63 public static class AddressSerializabilityTest extends SerializabilityTestCase { 64 65 @Override 66 protected Serializable createInstance() throws Exception { 67 return new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build(); 68 } 69 } 70 71 public static class AddressMiscTest { 72 73 private Address address; 74 75 /** 76 * Setup. 77 * 78 * @throws Exception the exception 79 */ 80 @Before 81 public void setUp() throws Exception { 82 address = new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build(); 83 } 84 85 /** 86 * Test builder. 87 */ 88 @Test 89 public void testBuilder() { 90 assertThat(address.getAddress1(), is("9839 Carlisle Boulevard NE")); 91 assertThat(address.getCity(), is("Albuquerque")); 92 assertThat(address.getState(), is("NM")); 93 assertThat(address.getZip(), is("87110")); 94 } 95 96 @Test 97 public void testToString() { 98 assertThat(address.toString(), is("Address{9839 Carlisle Boulevard NE, Albuquerque, NM, 87110}")); 99 }100 }101 }
问题三:不想执行某个类的test case 有什么方法?
回答: 用@Ignore, 如果要让某个类都不执行,@Ignore放在类里,如果不想执行某一个方法,只需要放在方法上。
1 @Ignore2 public class TestClass{3 4 @Ignore("Test is ignored as a demonstration")5 @Test6 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 和 执行顺序。且听下回分解。
- Junit4详解一:Junit总体介绍
- JUnit4总体介绍
- Struts2(一) 总体介绍
- Junit3和Junit4对比及Junit介绍
- Selenium简介(一)--总体介绍
- HDFS 总体介绍(一)
- SpringMVC框架总体介绍(一)
- Spring(一) 总体介绍
- Junit原理详解一
- ANT:与Junit的整合(一):Junit4
- Junit 学习之路一 junit3与junit4的区别
- JUNIT4.11源码阅读(一)--org.junit.Assert类
- D-Bus学习(一):总体介绍
- HDFS读书笔记-总体介绍(一)
- Struts2(一)——总体介绍
- Spring(一)——总体介绍
- D-Bus学习(一):总体介绍
- HDFS读书笔记-总体介绍(一)
- GitHub 上都有哪些值得关注学习的 iOS 开源项目?
- select、poll、epoll之间的区别总结[整理]
- 优秀的开源库
- 制作 二维码/条形码
- Scala深入浅出实战经典:24,Scala中SAM转换实战详解
- Junit4详解一:Junit总体介绍
- MySQL学习7_You must SET PASSWORD before executing this statement解决方法
- 数据库操作序列“事务”
- 1001. 害死人不偿命的(3n+1)猜想 (15)
- 二倍空间的线段树
- Scala深入浅出实战经典:25,Scala中Curring实战详解
- 黑马程序员——Java基础——面向对象的特征(二)
- MinHeap MaxHeap using Queue (PriorityQueue)
- 捕鱼问题