深入JUnit4
来源:互联网 发布:健身器材 知乎 编辑:程序博客网 时间:2024/05/17 12:54
JUnit简介
JUnit是一个Java语言的单元测试框架,也是程序员使用的白盒测试框架。
JUnit4在JUnit3的基础上引入了JDK1.5的注解特性,同时兼容JUnit3的测试用例写法,本文只介绍JUnit4,尤其是平常用得很少的一些高级用法。
基础注解
- @Test测试方法
- @Ignore被忽略的测试方法
- @Before每一个测试方法之前执行一次的方法
- @After每一个测试方法之后执行一次的方法
- @BeforeClass所有测试方法之前执行一次,方法必须为static修饰
- @AfterClass所有测试方法之后执行一次,方法必须为static修饰
以上注解,只可作用于方法,而且方法必须是public void修饰。
基本上了解到以上注解,就可以使用junit4进行编写测试用例了,简单例子如下:
package jtest.samples.money;/** * * @author guor * @version 2014/6/3 */public class Money {private int fAmount;/** * Constructs a money from the given amount */public Money(int amount) {fAmount = amount;}public int amount() {return fAmount;}}
package jtest.samples.money;import org.junit.After;import org.junit.Assert;import org.junit.Before;import org.junit.Ignore;import org.junit.Test;/** * @author guor * @version 2014/6/3 */public class MoneyTest { private Money money; @Before public void setUp() throws Exception { money = new Money(26); } @After public void tearDown() throws Exception { money = null; } @Test public void testSimplify1() { Assert.assertEquals(26, money.amount()); } @Test @Ignore public void testSimplify2() { Assert.assertEquals(26, money.amount()); }}
正如上述示例,基本上掌握好以上注解,就可以编写普通的测试用例了。下面我将介绍JUnit4的一些高级用法。
高级特性
@Rule注解
@Rule注解用于标记属性或方法,其必须为public,不能为static,而且属性的类型和方法的返回值必须是org.junit.rules.TestRule或org.junit.rules.MethodRule的子类。
有了@Rule属性之后,测试用例执行的顺序为:@BeforeClass -> TestRule/MethodRule -> @Before -> @Test -> @After
从执行流程中可以看出,@Rule相当于对测试用例进行了一次拦截处理,知道这点之后,建议看看junit4为我们提供的TestRule四种默认实现,分别是ExternalResource(资源处理型)、Verifier(通知型)、TestWatcher(监听型)、Timeout(超时型),这里面也基本上就是设计模式里面的模版方法模式的应用,实际使用时,我们只需要对这四种实现进行实现即可。
下面给出Timeout的使用方法
package jtest.samples.money;import org.junit.After;import org.junit.Assert;import org.junit.Before;import org.junit.Rule;import org.junit.Test;import org.junit.rules.TestRule;import org.junit.rules.Timeout;/** * @author guor * @version 2014/6/3 */public class MoneyTest { private Money money; @Rule public TestRule globalTimeout = new Timeout(1000); // 所有测试方法执行时间不能超过1s @Before public void setUp() throws Exception { money = new Money(26); } @After public void tearDown() throws Exception { money = null; } @Test public void testSimplify() { Assert.assertEquals(26, money.amount()); }}
例子中,定义了全局变量globalTimeout,并用@Rule注解标记,则所有的测试方法执行时间不能超过1s,否则程序会自动退出。
@RunWith注解
首先要知道JUnit中所有的测试用例,其最终都是由Runner调用运行的,默认的是BlockJUnit4ClassRunner,如果需要自定义一个Runner,除了需要继承Runner抽象类实现其抽象方法之外,还需要提供一个带参构造函数,其参数为Class,默认的Runner实现保证了测试类在测试用例执行之前初始化,而且不会持有这个测试类的对象,以确保JVM的垃圾回收机制正确执行,自定义Runner时,尤其需要注意这点,一般我们选择继承BlockJUnit4ClassRunner就可以了。
现在假设有测试需求,需要指定某些测试方法的执行次数,实现如下:
1. 自定义注解RunTimes
package jtest.samples;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 执行次数注解,作用在方法上,用于决定测试方法执行次数 * @author guor * @version 2014/6/3 */@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.METHOD })public @interface RunTimes {/** * 测试用例执行次数,默认为1 * * @return */int value() default 1;}
2. 自定义Runner,处理RunTimes注解
package jtest.samples;import org.junit.runner.notification.RunNotifier;import org.junit.runners.BlockJUnit4ClassRunner;import org.junit.runners.model.FrameworkMethod;import org.junit.runners.model.InitializationError;/** * 自定义Runner,主要处理RunTimes注解的逻辑 * @author guor * @version 2014/6/3 */public class CustomRunner extends BlockJUnit4ClassRunner {public CustomRunner(Class<?> klass) throws InitializationError {super(klass);}@Overrideprotected void runChild(FrameworkMethod method, RunNotifier notifier) {RunTimes annotation = method.getAnnotation(RunTimes.class);if (annotation == null) {super.runChild(method, notifier);} else {int runTimes = annotation.value();for (int i = 0; i < runTimes; i++) {super.runChild(method, notifier);}}}}
3. 简单测试用例
package jtest.samples;import org.junit.Test;import org.junit.runner.RunWith;/** * 简单测试用例 * * @author guor * @version 2014/6/3 */@RunWith(CustomRunner.class)public class SimpleTest {@Test@RunTimes(10)// 注解说明该测试方法执行次数public void testSimplify() {System.out.println(System.currentTimeMillis());}}
- 深入JUnit4
- JUnit4
- JUnit4
- junit4
- junit4
- JUnit4
- junit4
- JUnit4
- JUNIT4
- Junit4
- JUnit4
- junit4
- Junit4
- Junit4
- Junit4
- JUnit4
- JUnit4
- junit4
- C++ Primer笔记4_类的静态成员_IO库
- Eclipse+Tomcat+Jersey 编写 REST web service
- Valid Palindrome
- 重构改善既有代码的设计--在对象之间搬移特性
- 分析jrtplib库的内存管理类
- 深入JUnit4
- Java类的继承之this的使用方法实例
- vs2012自动调整缩进
- CSDN举办开源夏令营活动 5000元奖金激励学生参与开源
- 我的敏捷观
- c++动态内存分配
- WINDOWS下安装MEMCACHE
- swift 雨燕 入门教程
- iOS: 学习笔记, 使用FMDatabase操作sqlite3