【原创】Junit4详解一:Junit总体介绍
Junit是一个可编写重复测试的简单框架,是基于Xunit架构的单元测试框架的实例。Junit4最大的改进是大量使用注解(元数据),很多实际执行过程都在Junit的后台做完了,而且写test case 的类不需要继承TestCase,只需要在所要做test case的方法前加@Test 注解即可。
如:
import static org.junit.Assert.*;
2 public class TestCaculatorClass {
3 @Test
4 public void test() throws IOException, RuntimeException{
5 CaculatorClassForTest cal = new CaculatorClassForTest();
6 assertEquals(30, cal.sum(10, 20));
7 }
8 }
View @Test Code
直接点击右键,run as... Junit Test即可运行此test case。
Assert类里面有很多assert方法,包括:assertEquals(), assertNotNull(),assertTtrue(),assertFalse(),assertThat()等,其中assertThat用的是match的形式。
因此,Junit提供很多中Match,其中CoreMatchers是其中一个比较完善的实现类。具体有上面方法可以查阅CoreMatchers类。
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.both;
import static org.junit.matchers.JUnitMatchers.containsString;
import static org.junit.matchers.JUnitMatchers.everyItem;
import static org.junit.matchers.JUnitMatchers.hasItems; import java.util.Arrays; import org.hamcrest.core.CombinableMatcher;
import org.junit.Test; public class AssertTests {
@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);
} @Test
public void testAssertEquals() {
org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);
} @Test
public void testAssertFalse() {
org.junit.Assert.assertFalse("failure - should be false", false);
} @Test
public void testAssertNotNull() {
org.junit.Assert.assertNotNull("should not be null", new Object());
} @Test
public void testAssertNotSame() {
org.junit.Assert.assertNotSame("should not be same Object", new Object(), new Object());
} @Test
public void testAssertNull() {
org.junit.Assert.assertNull("should be null", null);
} @Test
public void testAssertSame() {
Integer aNumber = Integer.valueOf(768);
org.junit.Assert.assertSame("should be same", aNumber, aNumber);
} // JUnit Matchers assertThat
@Test
public void testAssertThatBothContainsString() {
org.junit.Assert.assertThat("albumen", both(containsString("a")).and(containsString("b")));
} @Test
public void testAssertThathasItemsContainsString() {
org.junit.Assert.assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
} @Test
public void testAssertThatEveryItemContainsString() {
org.junit.Assert.assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
} // Core Hamcrest Matchers with assertThat
@Test
public void testAssertThatHamcrestCoreMatchers() {
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
} @Test
public void testAssertTrue() {
org.junit.Assert.assertTrue("failure - should be true", true);
}
}
View Assert Code
问题一,我可不可以把多个测试类放在一起执行?
回答: 可以。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,那么如果执行这个类,就会把所有的测试类一起执行。
import org.junit.runner.RunWith;
import org.junit.runners.Suite; @RunWith(Suite.class)
@Suite.SuiteClasses({
TestFeatureLogin.class,
TestFeatureLogout.class,
TestFeatureNavigate.class,
TestFeatureUpdate.class
}) public class FeatureTestSuite {
// the class remains empty,
// used only as a holder for the above annotations
}
View Suite Code
2. Parameterized:根据所设计的参数来执行测试。假设我们要测试某一个方法,它有两个参数,每个参数需要设计不同值,那么我们最开始就是需要为每个参数设计一个测试方法,这样就很麻烦,10种case就得10个方法,但是有了Parameterized runner,我们可以设计一个方法,多种参数来执行test case。
package com.citi.risk.core.test.impl;
public class CaculatorClassForTest {
private int o1;
private int o2;
public int getO1() {
return this.o1;
}
public void setO1(int value) {
this.o1 = value;
}
public int getO2() {
return this.o2;
}
public void setO2(int value) {
this.o2 = value;
}
public CaculatorClassForTest() {}
public CaculatorClassForTest(int o1, int o2) {
this.o1 = o1;
this.o2 = o2;
}
public int sum(int o1, int o2){
if(o1 > 200) {
throw new RuntimeException("o1 is too big");
}
if(o2 > 200) {
throw new RuntimeException("o2 is too big");
}
int sum;
sum = o1 + o2;
return sum;
}
}
View CaculatorClassForTest Code
package com.citi.risk.core.test.impl; import static org.junit.Assert.*; import java.io.IOException;
import java.util.List; import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters; import com.google.common.collect.Lists; @RunWith(Parameterized.class)
public class TestCaculatorClass {
@Rule
public ExpectedException thrown = ExpectedException.none(); @Parameters
public static List<Object[]> data() {
return Lists.asList(new Object[]{-1, 1, 0}, new Object[][]{{20, 20, 40},{30, 30, 60},{-5, -5, -10}});
}
@Parameter(value = 0)
public int o1;
@Parameter(value = 1)
public int o2;
@Parameter(value = 2)
public int expector; @Test
public void test() throws IOException, RuntimeException{
CaculatorClassForTest cal = new CaculatorClassForTest();
assertEquals(expector, cal.sum(o1, o2));
} @Test
public void testO1Exception(){
CaculatorClassForTest cal = new CaculatorClassForTest();
thrown.expect(RuntimeException.class);
thrown.expectMessage("o1 is too big");
cal.sum(300, 100);
}
@Test
public void testO2Exception(){
CaculatorClassForTest cal = new CaculatorClassForTest();
thrown.expect(RuntimeException.class);
thrown.expectMessage("o2 is too big");
cal.sum(100, 300);
} }
View TestCaculatorClass Code
以上两个类就是测试了Parameterized runner, 参数会自动匹配。它其实就是,看我们传入几种case, 也就是List.size(),然后,把类里面的方法,循环重复执行size()数目。
3. Categories:容易理解就是分类执行。假设我们有一种case: 我们写好了两个测试类,类A,类B,A有两个方法a(), b(),这时候我们有一个类来执行这两个类的test case,但是我们在类A里只想执行A.b(),但却不执行A.a(),这个时候我们可以用Categories runner。
public interface FastTests { /* category marker */ }
public interface SlowTests { /* category marker */ }
public class A {
@Test
public void a() {
fail();
}
@Category(SlowTests.class)
@Test
public void b() {
}
}
@Category({SlowTests.class, FastTests.class})
public class B {
@Test
public void c() {
}
}
@RunWith(Categories.class)
@IncludeCategory(SlowTests.class)
@SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
public class SlowTestSuite {
// Will run A.b and B.c, but not A.a
}
@RunWith(Categories.class)
@IncludeCategory(SlowTests.class)
@ExcludeCategory(FastTests.class)
@SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
public class SlowTestSuite {
// Will run A.b, but not A.a or B.c
}
View Categories Code
4. Enclosed:如果我们把tests放在了内部类,这时候执行外部类是无法执行里面的test cases,这种情况下,就应该在outer class 用Enclosed runner。
要测试的类 Address:
package abstractions.domain;
import java.io.Serializable;
import com.google.common.collect.ComparisonChain;
public class Address implements Serializable, Comparable<Address> {
private static final long serialVersionUID = 1L;
private final String address1;
private final String city;
private final String state;
private final String zip;
private Address(Builder builder) {
this.address1 = builder.address1;
this.city = builder.city;
this.state = builder.state;
this.zip = builder.zip;
}
public String getAddress1() {
return address1;
}
public String getCity() {
return city;
}
public String getState() {
return state;
}
public String getZip() {
return zip;
}
@Override
public int compareTo(Address that) {
return ComparisonChain.start().compare(this.zip, that.zip).compare(this.state, that.state)
.compare(this.city, that.city).compare(this.address1, that.address1).result();
}
@Override
public boolean equals(Object obj) {
if (obj == null) { return false; }
if (getClass() != obj.getClass()) { return false; }
final Address that = (Address) obj;
return com.google.common.base.Objects.equal(this.address1, that.address1)
&& com.google.common.base.Objects.equal(this.city, that.city)
&& com.google.common.base.Objects.equal(this.state, that.state)
&& com.google.common.base.Objects.equal(this.zip, that.zip);
}
@Override
public int hashCode() {
return com.google.common.base.Objects.hashCode(getAddress1(), getCity(), getCity(), getState(), getZip());
}
@Override
public String toString() {
return com.google.common.base.Objects.toStringHelper(this).addValue(getAddress1()).addValue(getCity()).addValue(getState()).addValue(getZip()).toString();
}
public static class Builder {
private String address1;
private String city;
private String state;
private String zip;
public Builder address1(String address1) {
this.address1 = address1;
return this;
}
public Address build() {
return new Address(this);
}
public Builder city(String city) {
this.city = city;
return this;
}
public Builder state(String state) {
this.state = state;
return this;
}
public Builder zip(String zip) {
this.zip = zip;
return this;
}
}
}
View Address Code
test case:
package abstractions.domain;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.io.Serializable;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import testhelpers.ComparabilityTestCase;
import testhelpers.EqualsHashCodeTestCase;
import testhelpers.SerializabilityTestCase;
/**
* The Class AddressTest.
*/
@RunWith(Enclosed.class)
public class AddressTest {
/**
* The Class AddressComparabilityTest.
*/
public static class AddressComparabilityTest extends ComparabilityTestCase<Address> {
@Override
protected Address createEqualInstance() throws Exception {
return new Address.Builder().address1("2802 South Havana Street").city("Aurora").state("CO").zip("80014").build();
}
@Override
protected Address createGreaterInstance() throws Exception {
return new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build();
}
@Override
protected Address createLessInstance() throws Exception {
return new Address.Builder().address1("14 Broad St").city("Nashua").state("NH").zip("03064").build();
}
}
/**
* The Class AddressEqualsHashCodeTest.
*/
public static class AddressEqualsHashCodeTest extends EqualsHashCodeTestCase {
@Override
protected Address createInstance() throws Exception {
return new Address.Builder().address1("2802 South Havana Street").city("Aurora").state("CO").zip("80014").build();
}
@Override
protected Address createNotEqualInstance() throws Exception {
return new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build();
}
}
/**
* The Class AddressSerializabilityTest.
*/
public static class AddressSerializabilityTest extends SerializabilityTestCase {
@Override
protected Serializable createInstance() throws Exception {
return new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build();
}
}
public static class AddressMiscTest {
private Address address;
/**
* Setup.
*
* @throws Exception the exception
*/
@Before
public void setUp() throws Exception {
address = new Address.Builder().address1("9839 Carlisle Boulevard NE").city("Albuquerque").state("NM").zip("87110").build();
}
/**
* Test builder.
*/
@Test
public void testBuilder() {
assertThat(address.getAddress1(), is("9839 Carlisle Boulevard NE"));
assertThat(address.getCity(), is("Albuquerque"));
assertThat(address.getState(), is("NM"));
assertThat(address.getZip(), is("87110"));
}
@Test
public void testToString() {
assertThat(address.toString(), is("Address{9839 Carlisle Boulevard NE, Albuquerque, NM, 87110}"));
}
}
}
View AddressTest Code
问题三:不想执行某个类的test case 有什么方法?
回答: 用@Ignore, 如果要让某个类都不执行,@Ignore放在类里,如果不想执行某一个方法,只需要放在方法上。
@Ignore
public class TestClass{ @Ignore("Test is ignored as a demonstration")
@Test
public void testSane() {
assertThat(1, is(1));
}
}
问题四:某个test case执行时间太长,有什么办法终止?
回答: Junit4提供了timeout属性。
@Test(timeout=1000)
public void testWithTimeout() {
...
}
Junit4还有更重要的@Rule 和 执行顺序。且听下回分解。
草原战狼淘宝小店:http://xarxf.taobao.com/ 淘宝搜小矮人鞋坊,主营精致美丽时尚女鞋,为您的白雪公主挑一双哦。谢谢各位博友的支持。
===============================================================================
========================== 以上分析仅代表个人观点,欢迎指正与交流 ==========================
========================== 草原战狼博客,转载请注明出处,万分感谢 ==========================
===============================================================================
【原创】Junit4详解一:Junit总体介绍的更多相关文章
- 【原创】Junit4详解二:Junit4 Runner以及test case执行顺序和源代码理解
概要: 前一篇文章我们总体介绍了Junit4的用法以及一些简单的测试.之前我有个疑惑,Junit4怎么把一个test case跑起来的,在test case之前和之后我们能做些什么? Junit4执行 ...
- Java基础学习总结(24)——Java单元测试之JUnit4详解
Java单元测试之JUnit4详解 与JUnit3不同,JUnit4通过注解的方式来识别测试方法.目前支持的主要注解有: @BeforeClass 全局只会执行一次,而且是第一个运行 @Before ...
- C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)
上一讲<C++11 并发指南四(<future> 详解一 std::promise 介绍)>主要介绍了 <future> 头文件中的 std::promise 类, ...
- Solr系列三:solr索引详解(Schema介绍、字段定义详解、Schema API 介绍)
一.Schema介绍 1. Schema 是什么? Schema:模式,是集合/内核中字段的定义,让solr知道集合/内核包含哪些字段.字段的数据类型.字段该索引存储. 2. Schema 的定义方式 ...
- [原创]mybatis详解说明
mybatis详解 2017-01-05MyBatis之代理开发模式1 mybatis-Dao的代理开发模式 Dao:数据访问对象 原来:定义dao接口,在定义dao的实现类 dao的代理开发模式 只 ...
- C++11 并发指南四(<future> 详解一 std::promise 介绍)
前面两讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread 和 std::m ...
- C++11 并发指南四(<future> 详解一 std::promise 介绍)(转)
前面两讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread 和 std::m ...
- 2020你还不会Java8新特性?方法引用详解及Stream 流介绍和操作方式详解(三)
方法引用详解 方法引用: method reference 方法引用实际上是Lambda表达式的一种语法糖 我们可以将方法引用看作是一个「函数指针」,function pointer 方法引用共分为4 ...
- junit4 详解
转:http://www.cnblogs.com/eggbucket/archive/2012/02/02/2335697.html JUnit4概述 JUnit4是JUnit框架有史以来的最大改进, ...
随机推荐
- 基础学习day05---面向对象一类,对象、封装
一.面向对象 1.1.面向对象的概念 很经典的一句话----------万物皆对象 定义:面向对象一相对面向过程而言的 面向对象和面向过程都是一种思想 面向过程-- ...
- CSS 子选择器(六)
一.子选择器 子选择器中前后部分之间用一个大于号隔开,前后两部分选择符在结构上属于父子关系. 子选择器是根据左侧选择符指定的父元素,然后在该父元素下寻找匹配右侧选择符的子元素. 二.简单例子 < ...
- IOS 网络浅析-(十三 SDWebImage 实用技巧)
IOS 网络浅析-(十三 SDWebImage 实用技巧) 首先让我描述一下为了什么而产生的实用技巧.(在TableView.CollectionView中)当用户所处环境WiFi网速不够快(不能立即 ...
- iOS 通过二进制判断图片类型
+ (NSString *)typeForImageData:(NSData *)data { uint8_t c; [data getBytes:&c length:1]; switch ( ...
- 关于破解IDEA
博客的意义就在于分享 哈哈 今天想装个 IDEA玩玩 去官网 下了个 安装包 想破解 结果度娘 帮解决了 直接po方法 很简单 就是安装好注册的时候 选择 License server ,填 http ...
- github与eclipse创建仓库及克隆仓库
1.前往github官网注册账号,并下载客户端: 2.为eclipse工程创建本地仓库: 1,目前大多eclipse都预装了egit插件,如果没有请自行安装 2,在eclipse内创建工程->右 ...
- maven问题-"resolution will not be reattempted until the update interval of MyRepo has elapsed"
最近在家里写maven程序的时候老是出现问题,有些问题到了公司就突然消失了. 在修改pom文件后保存的反应还是比较明显的,家里的网遇到有些依赖根本下载不了..墙. 但是到了公司,不但速度快,几乎啥都能 ...
- cocos2d-x之Box2d初试
物理引擎:用来模拟一套物理事件的物理代码. #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "c ...
- 烂泥:ubuntu安装vmtools
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 最近由于工作需要,需要使用桌面版的linux系统,所以就选择了ubuntu.同时为了方便使用,就在VM中安装ubuntu. 但是为了文件以及操作的方便就 ...
- Hive DDL DML SQL操作
工作中经常要用到的一些东西,一直没整理,用的多的记住了,用的不多的每次都是去查,所以记录一下. DDL(数据定义语言),那就包括建表,修改表结构等等了 建表:create hive table hiv ...