@Test介绍


@Test是我们在写测试脚本时最常用到的,大部分情况下如果没用这个注解,一个方法就不能成为测试用例。如下代码是一个最普通的测试脚本:

import org.junit.Assert;
import org.junit.Test; public class GeneralTest { @Test
public void test() {
int num1 = 1;
int num2 = 2;
int sum = num1 + num2;
Assert.assertEquals(3, sum);
} }

运行一下看看:

恭喜,获得一个绿条。这个脚本包含了测试脚本基本的几个元素:参数定义、参数运算、结果校验。@Test在这个测试脚本的作用就是让一个普通的方法(Method)变成一个JUnit可识别的测试脚本。但是@Test除了标记测试脚本的功能外,还有什么功能呢?

先来看看@Test的源码:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Test { /**
* Default empty exception
*/
static class None extends Throwable {
private static final long serialVersionUID = 1L; private None() {
}
} /**
* Optionally specify <code>expected</code>, a Throwable,
* to cause a test method to succeed iff
* an exception of the specified class is thrown by the method.
*/
Class<? extends Throwable> expected() default None.class; /**
* Optionally specify <code>timeout</code> in milliseconds to
* cause a test method to fail if it
* takes longer than that number of milliseconds.
*/
long timeout() default 0L;
}

从源码可以看出,@Test还有两个属性,分别是expected()timeout(),可以从注解中看到这两个属性的作用:

  • expected():校验测试脚本抛出指定类型的异常
  • timeout():测试脚本的运行时间是否满足要求

下面举个例子看看这个两个属性如何使用:

import org.junit.Test;

public class TimeoutAndExceptionTest {

    @Test(timeout = 1000) //脚本运行时间小于1000毫秒
public void testTimeout() throws InterruptedException {
Thread.sleep(900);
} @Test(expected = IllegalArgumentException.class) //脚本抛出参数非法的异常
public void testExpectedThrowable() {
throw new IllegalArgumentException();
} @Test(timeout = 1000) //脚本运行时间小于1000毫秒
public void testTimeoutFailed() throws InterruptedException {
Thread.sleep(2000);
} @Test(expected = IllegalArgumentException.class) //脚本抛出参数非法的异常
public void testExpectedThrowableFailed() {
throw new NullPointerException();
} }

运行后发现testTimeoutFailed()testExpectedThrowableFailed()运行失败,错误提示如下:

可见JUnit已经帮助我们完成断言的工作。至此,@Test的功能已经全部介绍完了。

@Ignore介绍


@Ignore是偶尔且一定会用到的注解,从名字就能知道其作用是“忽略”,即忽略一个测试脚本,标注了@Ignore注解的测试脚本将不会被执行。用法很简单,示例如下:

import org.junit.Ignore;
import org.junit.Test; public class IgnoreTest { @Test
@Ignore
public void test() {
//some test
} }

运行一下

发现这个测试脚本的确没被运行。不过如果另外一个人来看这个脚本就会很疑惑这个测试脚本为什么要被忽略。所以必须要说明这个测试脚本被忽略的原因。那在什么地方说明呢?可以先看看@Ignore本身是否提供这个功能,所以先看看@Ignore的源码:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Ignore {
/**
* The optional reason why the test is ignored.
*/
String value() default "";
}

从源码来看,@Ignorevalue()就是为这个需求准备的,可以说明测试脚本被忽略的原因。我们可以将上面的测试脚本修改如下:

import org.junit.Ignore;
import org.junit.Test; public class IgnoreTest { @Test
@Ignore("not ready yet!")
public void test() {
//some test
} }

修改后就清楚多了,无论以后谁来维护这个测试脚本,都可以很直观的看到这个测试脚本是因为“还未准备好”而忽略的。

再运行一下

发现运行结构并没有不同,可见Eclipse并有没读取@Ignorevalue()值,不过并不是所有的IDE都是这样,可以看下IDEA的运行效果。

从运行结果发现,IDEA可以在运行结果展示被忽略的原因。

@Before@After@BeforeClass@AfterClass介绍


@Before@After@BeforeClass@AfterClass也是我们常用的注解,使用频率与@Test一样,一般每个测试脚本都会出现这些注解,用来做测试数据准备和资源回收等工作。那么,首先介绍下这些注解的执行范围。

  • @Bfore:每个测试用例(Method)运行前执行一次
  • @After:每个测试用例(Method)运行后执行一次
  • @BeforeClass:每个测试脚本(Class)运行前执行一次
  • @AfterClass:每个测试脚本(Class)运行前执行一次

每个注解对所标注的方法(Method)的要求如下:

  • @Bfore@After:公共(public)的、非静态(static)的、无返回值(void)、无参数的方法(Method)
  • @BeforeClass@AfterClass:公共(public)的、静态(static)的、无返回值(void)、无参数的方法(Method)

下面用一个简单的例子说明一下这些规则:

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; public class BeforeAndAfterTest { @BeforeClass
public static void beforeClass() {
System.out.println("BeforeClass");
} @AfterClass
public static void afterClass() {
System.out.println("AfterClass");
} @Before
public void before() {
System.out.println("Before");
} @After
public void after() {
System.out.println("After");
} @Test
public void test01() {
System.out.println("Test01");
} @Test
public void test02() {
System.out.println("Test02");
} }

运行一下

只有标注了@Test注解的方法(Method)被识别为测试用例。

再看看控制台(Console)的输出内容

BeforeClass
Before
Test01
After
Before
Test02
After
AfterClass

和上面所说的规则一致。

@RunWith介绍


基于JUnit的测试脚本都是依靠Runner去解析和执行,@Test等所有注解的执行顺序、生命周期也都是由Runner决定的,所以Runner是JUnit的核心。

自然,将Runner作为JUnit的扩展点将使JUnit更易扩展,这个将在高级篇介绍。

从JUnit4.5以后,JUnit的默认Runner改为BlockJUnit4ClassRunner,将原来的JUnit4ClassRunner改为BlockJUnit4ClassRunner继承ParentRunner<T>的形式,增强了JUnit的可扩展性。同时,JUnit也自带很多Runner来丰富自身的功能。

那么,使用其他功能的Runner呢?那就要使用@RunWith注解了,下面用一个简单的小例子演示下@RunWith的使用。

首先需要自定义一个Runner,作用是打印每个运行的测试用例的方法名(Method Name),具体Runner的实现将在高级篇中详细讨论。代码如下:

import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError; public class LoggingRunner extends BlockJUnit4ClassRunner { public LoggingRunner(Class<?> klass) throws InitializationError {
super(klass);
} @Override
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
System.out.println(method.getName());
super.runChild(method, notifier);
} }

然后通过@RunWith使用这个注解。

import org.junit.Test;
import org.junit.runner.RunWith; @RunWith(LoggingRunner.class) //在这里使用
public class RunWithTest { @Test
public void test01() {
} @Test
public void test02() {
} }

最后运行下看看结果。

test01
test02

正确打印出两个测试用例的方法。

可以看到,@RunWith用法十分简单,但是这是个十分重要的功能,因为后面的中级篇、高级篇中大部分功能都基于一个特殊功能的Runner,都需要使用@RunWith,请牢记。

摘自:http://liwx2000.github.io/junit/2013/05/15/junit-junior.html

Junit初级篇的更多相关文章

  1. Java工程师学习指南 初级篇

    Java工程师学习指南 初级篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...

  2. Java工程师学习指南(初级篇)

    Java工程师学习指南 初级篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...

  3. Python 正则表达式入门(初级篇)

    Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写. 转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达 ...

  4. python 面向对象初级篇

    Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...

  5. 25个增强iOS应用程序性能的提示和技巧(初级篇)

    25个增强iOS应用程序性能的提示和技巧(初级篇) 标签: ios内存管理性能优化 2013-12-13 10:53 916人阅读 评论(0) 收藏 举报  分类: IPhone开发高级系列(34)  ...

  6. ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇(转)

    ASP.NET MVC 随想录——开始使用ASP.NET Identity,初级篇   阅读目录 ASP.NET Identity 前世今生 建立 ASP.NET Identity 使用ASP.NET ...

  7. python_way ,day7 面向对象 (初级篇)

    面向对象 初级篇   python支持 函数 与 面向对象   什么时候实用面向对象? 面向对象与函数对比 类和对象 创建类 class 类名 def 方法名(self,xxxx) 类里面的方法,只能 ...

  8. Entity Framework 学习初级篇--基本操作:增加、更新、删除、事务(转)

    摘自:http://www.cnblogs.com/xray2005/archive/2009/05/17/1458568.html 本节,直接写通过代码来学习.这些基本操作都比较简单,与这些基本操作 ...

  9. NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者

    NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者 作者: raindy 来源:http://bbs.hanzify.org/index.php?showtopic=30029 时间: ...

随机推荐

  1. 【ios开发之疑难杂症】xcode运行出现SpringBoard 无法启动应用程序(错误:7)

    问题:xcode运行出现SpringBoard 无法启动应用程序(错误:7) 解决方案: 重启模拟器

  2. day1 python简介和入门

    Linux的yum依赖自带Python,为防止错误,此处更新其实就是再安装一个Python: 安装Python 1.下载安装包     https://www.python.org/downloads ...

  3. Hibernate (开源对象关系映射框架)

    一.基本介绍1.它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm(对象关系映射)框架,hibernate可以自动生成SQL语句,自动执行: Hibern ...

  4. 转:php防止sql注入的一点心得

    转:http://blog.csdn.net/sky_zhe/article/details/9702489 转:http://zhangxugg-163-com.iteye.com/blog/183 ...

  5. 洛谷P1503 鬼子进村 [平衡树,STL]

    题目传送门 鬼子进村 题目背景 小卡正在新家的客厅中看电视.电视里正在播放放了千八百次依旧重播的<亮剑>,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战. ...

  6. mac linux 命令笔记 - 权限管理

    壹 权限 在使用命令行工具时,可能需要临时切换到管理员/root权限,如何切换呢? 正文 进入 root 权限: sudo -i 提示输入密码,这个密码就是锁屏的解锁密码. 在操作完成之后,使用 ex ...

  7. Redux学习之解读applyMiddleware源码深入middleware工作机制

    随笔前言 在上一周的学习中,我们熟悉了如何通过redux去管理数据,而在这一节中,我们将一起深入到redux的知识中学习. 首先谈一谈为什么要用到middleware 我们知道在一个简单的数据流场景中 ...

  8. linux——(5)文件与文件系统的压缩与打包

    概念一:常见的压缩文件拓展名 .z compress程序压缩的文件. .gz gzip程序压缩的文件. .bz2 bzip2程序压缩的文件. .tar tar程序打包的数据,并没有压缩过. .tar. ...

  9. 通过openURL的方式启动其它App

    假设有两个App,项目名分别是SampleA和SampleB,需要在SampleA里点击一个Button来启动SampleB,并传递一个字符串.具体实现步骤如下: 1. 在SampleB的info.p ...

  10. 【BZOJ 2510】 2510: 弱题 (矩阵乘法、循环矩阵的矩阵乘法)

    2510: 弱题 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 374  Solved: 196 Description 有M个球,一开始每个球均有一 ...