Junit4详解一:Junit总体介绍
2015-09-19 13:23
211 查看
Junit4详解一:Junit总体介绍
Junit是一个可编写重复测试的简单框架,是基于Xunit架构的单元测试框架的实例。Junit4最大的改进是大量使用注解(元数据),很多实际执行过程都在Junit的后台做完了,而且写testcase的类不需要继承TestCase,只需要在所要做testcase的方法前加@Test注解即可。
如:
1importstaticorg.junit.Assert.*; 22publicclassTestCaculatorClass{ 33@Test 44publicvoidtest()throwsIOException,RuntimeException{ 55CaculatorClassForTestcal=newCaculatorClassForTest(); 66assertEquals(30,cal.sum(10,20)); 77} 88}
直接点击右键,runas...JunitTest即可运行此testcase。
Assert类里面有很多assert方法,包括:assertEquals(),assertNotNull(),assertTtrue(),assertFalse(),assertThat()等,其中assertThat用的是match的形式。
因此,Junit提供很多中Match,其中CoreMatchers是其中一个比较完善的实现类。具体有上面方法可以查阅CoreMatchers类。
1importstaticorg.hamcrest.CoreMatchers.allOf; 2importstaticorg.hamcrest.CoreMatchers.anyOf; 3importstaticorg.hamcrest.CoreMatchers.equalTo; 4importstaticorg.hamcrest.CoreMatchers.not; 5importstaticorg.hamcrest.CoreMatchers.sameInstance; 6importstaticorg.hamcrest.CoreMatchers.startsWith; 7importstaticorg.junit.Assert.assertThat; 8importstaticorg.junit.matchers.JUnitMatchers.both; 9importstaticorg.junit.matchers.JUnitMatchers.containsString; 10importstaticorg.junit.matchers.JUnitMatchers.everyItem; 11importstaticorg.junit.matchers.JUnitMatchers.hasItems; 12 13importjava.util.Arrays; 14 15importorg.hamcrest.core.CombinableMatcher; 16importorg.junit.Test; 17 18publicclassAssertTests{ 19@Test 20publicvoidtestAssertArrayEquals(){ 21byte[]expected="trial".getBytes(); 22byte[]actual="trial".getBytes(); 23org.junit.Assert.assertArrayEquals("failure-bytearraysnotsame",expected,actual); 24} 25 26@Test 27publicvoidtestAssertEquals(){ 28org.junit.Assert.assertEquals("failure-stringsnotsame",5l,5l); 29} 30 31@Test 32publicvoidtestAssertFalse(){ 33org.junit.Assert.assertFalse("failure-shouldbefalse",false); 34} 35 36@Test 37publicvoidtestAssertNotNull(){ 38org.junit.Assert.assertNotNull("shouldnotbenull",newObject()); 39} 40 41@Test 42publicvoidtestAssertNotSame(){ 43org.junit.Assert.assertNotSame("shouldnotbesameObject",newObject(),newObject()); 44} 45 46@Test 47publicvoidtestAssertNull(){ 48org.junit.Assert.assertNull("shouldbenull",null); 49} 50 51@Test 52publicvoidtestAssertSame(){ 53IntegeraNumber=Integer.valueOf(768); 54org.junit.Assert.assertSame("shouldbesame",aNumber,aNumber); 55} 56 57//JUnitMatchersassertThat 58@Test 59publicvoidtestAssertThatBothContainsString(){ 60org.junit.Assert.assertThat("albumen",both(containsString("a")).and(containsString("b"))); 61} 62 63@Test 64publicvoidtestAssertThathasItemsContainsString(){ 65org.junit.Assert.assertThat(Arrays.asList("one","two","three"),hasItems("one","three")); 66} 67 68@Test 69publicvoidtestAssertThatEveryItemContainsString(){ 70org.junit.Assert.assertThat(Arrays.asList(newString[]{"fun","ban","net"}),everyItem(containsString("n"))); 71} 72 73//CoreHamcrestMatcherswithassertThat 74@Test 75publicvoidtestAssertThatHamcrestCoreMatchers(){ 76assertThat("good",allOf(equalTo("good"),startsWith("good"))); 77assertThat("good",not(allOf(equalTo("bad"),equalTo("good")))); 78assertThat("good",anyOf(equalTo("bad"),equalTo("good"))); 79assertThat(7,not(CombinableMatcher.<Integer>either(equalTo(3)).or(equalTo(4)))); 80assertThat(newObject(),not(sameInstance(newObject()))); 81} 82 83@Test 84publicvoidtestAssertTrue(){ 85org.junit.Assert.assertTrue("failure-shouldbetrue",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,那么如果执行这个类,就会把所有的测试类一起执行。
1importorg.junit.runner.RunWith; 2importorg.junit.runners.Suite; 3 4@RunWith(Suite.class) 5@Suite.SuiteClasses({ 6TestFeatureLogin.class, 7TestFeatureLogout.class, 8TestFeatureNavigate.class, 9TestFeatureUpdate.class 10}) 11 12publicclassFeatureTestSuite{ 13//theclassremainsempty, 14//usedonlyasaholderfortheaboveannotations 15}
2.Parameterized:根据所设计的参数来执行测试。假设我们要测试某一个方法,它有两个参数,每个参数需要设计不同值,那么我们最开始就是需要为每个参数设计一个测试方法,这样就很麻烦,10种case就得10个方法,但是有了Parameterized
runner,我们可以设计一个方法,多种参数来执行testcase。
1packagecom.citi.risk.core.test.impl; 2 3publicclassCaculatorClassForTest{ 4 5privateinto1; 6privateinto2; 7publicintgetO1(){ 8returnthis.o1; 9} 10publicvoidsetO1(intvalue){ 11this.o1=value; 12} 13publicintgetO2(){ 14returnthis.o2; 15} 16publicvoidsetO2(intvalue){ 17this.o2=value; 18} 19 20 21publicCaculatorClassForTest(){} 22publicCaculatorClassForTest(into1,into2){ 23this.o1=o1; 24this.o2=o2; 25} 26 27publicintsum(into1,into2){ 28if(o1>200){ 29thrownewRuntimeException("o1istoobig"); 30} 31if(o2>200){ 32thrownewRuntimeException("o2istoobig"); 33} 34intsum; 35sum=o1+o2; 36returnsum; 37} 38}
1packagecom.citi.risk.core.test.impl; 2 3importstaticorg.junit.Assert.*; 4 5importjava.io.IOException; 6importjava.util.List; 7 8importorg.junit.Rule; 9importorg.junit.Test; 10importorg.junit.rules.ExpectedException; 11importorg.junit.runner.RunWith; 12importorg.junit.runners.Parameterized; 13importorg.junit.runners.Parameterized.Parameter; 14importorg.junit.runners.Parameterized.Parameters; 15 16importcom.google.common.collect.Lists; 17 18@RunWith(Parameterized.class) 19publicclassTestCaculatorClass{ 20@Rule 21publicExpectedExceptionthrown=ExpectedException.none(); 22 23@Parameters 24publicstaticList<Object[]>data(){ 25returnLists.asList(newObject[]{-1,1,0},newObject[][]{{20,20,40},{30,30,60},{-5,-5,-10}}); 26} 27@Parameter(value=0) 28publicinto1; 29@Parameter(value=1) 30publicinto2; 31@Parameter(value=2) 32publicintexpector; 33 34@Test 35publicvoidtest()throwsIOException,RuntimeException{ 36CaculatorClassForTestcal=newCaculatorClassForTest(); 37assertEquals(expector,cal.sum(o1,o2)); 38} 39 40@Test 41publicvoidtestO1Exception(){ 42CaculatorClassForTestcal=newCaculatorClassForTest(); 43thrown.expect(RuntimeException.class); 44thrown.expectMessage("o1istoobig"); 45cal.sum(300,100); 46} 47@Test 48publicvoidtestO2Exception(){ 49CaculatorClassForTestcal=newCaculatorClassForTest(); 50thrown.expect(RuntimeException.class); 51thrown.expectMessage("o2istoobig"); 52cal.sum(100,300); 53} 54 55}
以上两个类就是测试了Parameterizedrunner,参数会自动匹配。它其实就是,看我们传入几种case,也就是List.size(),然后,把类里面的方法,循环重复执行size()数目。
3.Categories:容易理解就是分类执行。假设我们有一种case:我们写好了两个测试类,类A,类B,A有两个方法a(),b(),这时候我们有一个类来执行这两个类的testcase,但是我们在类A里只想执行A.b(),但却不执行A.a(),这个时候我们可以用Categories
runner。
1publicinterfaceFastTests{/*categorymarker*/} 2publicinterfaceSlowTests{/*categorymarker*/} 3 4publicclassA{ 5@Test 6publicvoida(){ 7fail(); 8} 9 10@Category(SlowTests.class) 11@Test 12publicvoidb(){ 13} 14} 15 16@Category({SlowTests.class,FastTests.class}) 17publicclassB{ 18@Test 19publicvoidc(){ 20 21} 22} 23 24@RunWith(Categories.class) 25@IncludeCategory(SlowTests.class) 26@SuiteClasses({A.class,B.class})//NotethatCategoriesisakindofSuite 27publicclassSlowTestSuite{ 28//WillrunA.bandB.c,butnotA.a 29} 30 31@RunWith(Categories.class) 32@IncludeCategory(SlowTests.class) 33@ExcludeCategory(FastTests.class) 34@SuiteClasses({A.class,B.class})//NotethatCategoriesisakindofSuite 35publicclassSlowTestSuite{ 36//WillrunA.b,butnotA.aorB.c 37}
4.Enclosed:如果我们把tests放在了内部类,这时候执行外部类是无法执行里面的testcases,这种情况下,就应该在outerclass用Enclosedrunner。
要测试的类Address:
1packageabstractions.domain;
2
3importjava.io.Serializable;
4
5importcom.google.common.collect.ComparisonChain;
6
7publicclassAddressimplementsSerializable,Comparable<Address>{
8
9privatestaticfinallongserialVersionUID=1L;
10privatefinalStringaddress1;
11privatefinalStringcity;
12privatefinalStringstate;
13privatefinalStringzip;
14
15privateAddress(Builderbuilder){
16this.address1=builder.address1;
17this.city=builder.city;
18this.state=builder.state;
19this.zip=builder.zip;
20}
21
22publicStringgetAddress1(){
23returnaddress1;
24}
25
26publicStringgetCity(){
27returncity;
28}
29
30publicStringgetState(){
31returnstate;
32}
33
34publicStringgetZip(){
35returnzip;
36}
37
38@Override
39publicintcompareTo(Addressthat){
40returnComparisonChain.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@Override
45publicbooleanequals(Objectobj){
46if(obj==null){returnfalse;}
47if(getClass()!=obj.getClass()){returnfalse;}
48finalAddressthat=(Address)obj;
49
50returncom.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@Override
57publicinthashCode(){
58returncom.google.common.base.Objects.hashCode(getAddress1(),getCity(),getCity(),getState(),getZip());
59}
60
61@Override
62publicStringtoString(){
63returncom.google.common.base.Objects.toStringHelper(this).addValue(getAddress1()).addValue(getCity()).addValue(getState()).addValue(getZip()).toString();
64}
65
66publicstaticclassBuilder{
67
68privateStringaddress1;
69privateStringcity;
70privateStringstate;
71privateStringzip;
72
73publicBuilderaddress1(Stringaddress1){
74this.address1=address1;
75returnthis;
76}
77
78publicAddressbuild(){
79returnnewAddress(this);
80}
81
82publicBuildercity(Stringcity){
83this.city=city;
84returnthis;
85}
86
87publicBuilderstate(Stringstate){
88this.state=state;
89returnthis;
90}
91
92publicBuilderzip(Stringzip){
93this.zip=zip;
94returnthis;
95}
96}
97}
test
case:
1packageabstractions.domain;
2
3importstaticorg.hamcrest.Matchers.is;
4importstaticorg.junit.Assert.assertThat;
5
6importjava.io.Serializable;
7
8importorg.junit.Before;
9importorg.junit.Test;
10importorg.junit.experimental.runners.Enclosed;
11importorg.junit.runner.RunWith;
12
13importtesthelpers.ComparabilityTestCase;
14importtesthelpers.EqualsHashCodeTestCase;
15importtesthelpers.SerializabilityTestCase;
16
17/**
18*TheClassAddressTest.
19*/
20@RunWith(Enclosed.class)
21publicclassAddressTest{
22
23/**
24*TheClassAddressComparabilityTest.
25*/
26publicstaticclassAddressComparabilityTestextendsComparabilityTestCase<Address>{
27
28@Override
29protectedAddresscreateEqualInstance()throwsException{
30returnnewAddress.Builder().address1("2802SouthHavanaStreet").city("Aurora").state("CO").zip("80014").build();
31}
32
33@Override
34protectedAddresscreateGreaterInstance()throwsException{
35returnnewAddress.Builder().address1("9839CarlisleBoulevardNE").city("Albuquerque").state("NM").zip("87110").build();
36}
37
38@Override
39protectedAddresscreateLessInstance()throwsException{
40returnnewAddress.Builder().address1("14BroadSt").city("Nashua").state("NH").zip("03064").build();
41}
42}
43
44/**
45*TheClassAddressEqualsHashCodeTest.
46*/
47publicstaticclassAddressEqualsHashCodeTestextendsEqualsHashCodeTestCase{
48
49@Override
50protectedAddresscreateInstance()throwsException{
51returnnewAddress.Builder().address1("2802SouthHavanaStreet").city("Aurora").state("CO").zip("80014").build();
52}
53
54@Override
55protectedAddresscreateNotEqualInstance()throwsException{
56returnnewAddress.Builder().address1("9839CarlisleBoulevardNE").city("Albuquerque").state("NM").zip("87110").build();
57}
58}
59
60/**
61*TheClassAddressSerializabilityTest.
62*/
63publicstaticclassAddressSerializabilityTestextendsSerializabilityTestCase{
64
65@Override
66protectedSerializablecreateInstance()throwsException{
67returnnewAddress.Builder().address1("9839CarlisleBoulevardNE").city("Albuquerque").state("NM").zip("87110").build();
68}
69}
70
71publicstaticclassAddressMiscTest{
72
73privateAddressaddress;
74
75/**
76*Setup.
77*
78*@throwsExceptiontheexception
79*/
80@Before
81publicvoidsetUp()throwsException{
82address=newAddress.Builder().address1("9839CarlisleBoulevardNE").city("Albuquerque").state("NM").zip("87110").build();
83}
84
85/**
86*Testbuilder.
87*/
88@Test
89publicvoidtestBuilder(){
90assertThat(address.getAddress1(),is("9839CarlisleBoulevardNE"));
91assertThat(address.getCity(),is("Albuquerque"));
92assertThat(address.getState(),is("NM"));
93assertThat(address.getZip(),is("87110"));
94}
95
96@Test
97publicvoidtestToString(){
98assertThat(address.toString(),is("Address{9839CarlisleBoulevardNE,Albuquerque,NM,87110}"));
99}
100}
101}
问题三:不想执行某个类的testcase有什么方法?
回答:用@Ignore,如果要让某个类都不执行,@Ignore放在类里,如果不想执行某一个方法,只需要放在方法上。
1@Ignore
2publicclassTestClass{
3
4@Ignore("Testisignoredasademonstration")
5@Test
6publicvoidtestSane(){
7assertThat(1,is(1));
8}
9}
问题四:某个testcase执行时间太长,有什么办法终止?
回答:Junit4提供了timeout属性。
1@Test(timeout=1000)
2publicvoidtestWithTimeout(){
3...
4}
Junit4还有更重要的@Rule和执行顺序。且听下回分解。
相关文章推荐
- 对GitHub的认识
- Effective C++ —— 模板与泛型编程(七)
- select、poll、epoll之间的区别总结[整理]
- UML系列图--用例图
- Scala深入浅出实战经典:23,Scala高阶函数实战详解
- IO多路复用之epoll总结
- GitHub 上都有哪些值得关注学习的 iOS 开源项目?
- 采用proguard困惑android代码
- Struts拦截百度编辑器解决方法
- VC文件扩展名解读大全
- Servlet 工作原理解析
- Activiti入门教程二(熟悉数据库设计)
- IO多路复用之poll总结
- 剑指offer 栈和队列
- 剑指offer 树
- XCode7使用AFNetworking无法访问网络解决办法
- ASP.NET三层架构的分析
- django 1.8 官方文档翻译:9-1-4 格式本地化
- Scala深入浅出实战经典:22,Scala中的闭包实战详解
- Git 常用命令