Junit4.x扩展:运行指定方法

相信很多道友搞开发的一般都会用到Junit单元测试工具,不知道大家有没有遇到一个这样的问题:

有的单元测试用例有很多@Test方法,甚至有的方法会执行很长时间,只能空等执行。而实际上我们只需要运行其中的某一些方法就可以了。然后有人会说不是有ingore注解么,可ingore需要为许多的方法添加,当测试方法达到一定数量级的时候,改起来会很烦躁,如果commit到代码服务器上甚至可能会影响别人工作。己所不欲...

之前有朋友跟我说过TestNG是支持指定执行哪些方法,本人没有亲自去实验,因为公司统一使用Junit,所以没打算在这上面花费学习成本,没有固定测试框架的朋友不妨自己了解一下。下面开始扩展:

实现思路

1、在正常运行的情况下,Junit被触发会调用org.junit.runners.BlockJUnit4ClassRunner类,加载测试类文件,执行before after childrenInvoker等方法,有兴趣的道友可以自己看下这个类的结构,今天的主角是childrenInvoker方法,这个方法调用了测试类文件的@Test方法并执行,我们要做的就是重写这个方法,根据我们自己的规则选择执行哪些方法。

2、根据上一条我们要扩展一个R我unner继承自BlockJUnit4ClassRunner,在这里进行参数过滤。

3、我们可能希望方法可以模糊匹配,也可能希望可以指定某几个固定的写法,所以需要引入一种过滤规则,这里采用正则表达式。过滤规则的传递采用注解,因为我觉得简洁,忘记注解使用的朋友可以点击这里

4、Junit4开始提供了RunWith注解,以便让用户自定义扩展Runner,我们的实现就是基于它的这个特性。比较有名的应该大家都比较熟悉spring的Junit扩展。

代码实现:

1、定义注解

package com.array7.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FilterMethods {
	String[] methods();
}

2、定义Runner

package com.array7.runner;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

import com.array7.annotations.FilterMethods;

public class SpecialMethodsRunner extends BlockJUnit4ClassRunner {
	private FilterMethods filter;
	public SpecialMethodsRunner(Class<?> clazz) throws InitializationError {
		super(clazz);
		filter = clazz.getAnnotation(FilterMethods.class);
	}

	/**
	 * EnterPoint
	 */
	@Override
	protected Statement childrenInvoker(final RunNotifier notifier) {
		if (filter == null) {	// keep original runner alone.
			return super.childrenInvoker(notifier);
		}
		return new Statement() {
			@Override
			public void evaluate() throws Throwable {
				runMethodsWithFilter(notifier, filter);
			}
		};
	}
	/**
	 * Filter the methods could be run.
	 * @param notifier
	 * @param filterMethods
	 */
	private void runMethodsWithFilter(final RunNotifier notifier, final FilterMethods filterMethods) {
		String[] filters = filterMethods.methods();
		if (filters == null || filters.length == 0) {
			throw new IllegalArgumentException(
					"Wrong parameters!Please check Annotation FilterMthods parameters...");
		}

		Set<Pattern> patternSet = new HashSet<Pattern>();
		for (String filter : filters) {
			patternSet.add(Pattern.compile(filter));
		}

		for (FrameworkMethod method : getChildren()) {
			for (Pattern pattern : patternSet) {	// loop all patterns
				if (pattern.matcher(method.getName()).matches()) {	// if matches ...break;
					runChild(method, notifier);
					break;
				}
			}
		}
	}

}

3、使用实例:

package junit_ext;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.array7.annotations.FilterMethods;
import com.array7.runner.SpecialMethodsRunner;

@RunWith(SpecialMethodsRunner.class)
@FilterMethods(methods = { "^.*2$", "^m.*", "ab21"})
public class DemoTest {
	@Test
	public void m1() {
		System.out.println(123);
	}

	@Test
	public void mmm2() {
		System.out.println(456);
	}

	@Test
	public void a2() {
		System.out.println(791);
	}

	@Test
	public void ab21() {
		System.out.println(7890);
	}
}

4、pom.xml依赖

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
</dependency>

5、代码经过测试,文章亦可随意转载,唯请保留出处。

最后,喜欢讨论技术的道友可以加入我的QQ技术群80466913,Java相关为主,希望您喜欢技术,希望您对底层源码有一定了解(NIO / CONCURRENT / NETTY / 设计模式 / NOSQL / HADOOP / TCP/IP等),期待共同进步,此群上限只会维持到100人左右。

时间: 2024-10-11 22:56:11

Junit4.x扩展:运行指定方法的相关文章

无需重新编译php加入ftp扩展的解决方法

无需重新编译php加入ftp扩展的解决方法 本文为大家介绍无需重新编译php加入ftp扩展的方法,有需要的朋友可以参考下 首先,进入源码目录cd php-5.2.13/ext/ftp #运行phpize生成configure/usr/local/php/bin/phpize #编译,指定php-config,注意这里的php-config,不是php.ini./configure --with-php-config=/usr/local/php/bin/php-config#上面可以添加--en

Java JVM 运行时方法区

Run-Time Data Areas 随着VM或线程开始.结束的数据区域.官方文档是http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5 (盗用下图) The pc Register(程序计数寄存器): Program Counter Register,随着线程开始结束.VM运行的方法: 1.非Native方法,持有正在运行操作的内存地址 2.Native方法 ,没指定,但一般均可以持有平台相关的指针. 表

正确的 Composer 扩展包安装方法

问题说明 我们经常要往现有的项目中添加扩展包,有时候因为文档的错误引导,如下图来自 这个文档 的: composer update 这个命令在我们现在的逻辑中,可能会对项目造成巨大伤害. 因为 composer update 的逻辑是按照 composer.json 指定的扩展包版本规则,把所有扩展包更新到最新版本,注意,是 所有扩展包,举个例子,你在项目一开始的时候使用了 monolog,当时的配置信息是 "monolog/monolog": "1.*", 安装的

生成Excel *.xls 生成 xls的格式与文件扩展名指定的格式不一致

如果不想修改代码可以通过修改计算机配置完成  http://blog.csdn.net/g710710/article/details/21166453 用如下方法生成的xls不会提示此错误 protected static void ExportExcel(DataTable dt) { if (dt == null || dt.Rows.Count == 0) return; Microsoft.Office.Interop.Excel.Application xlApp = new Mic

关于asp.net C# 导出Excel文件 打开Excel文件格式与扩展名指定格式不一致的解决办法

转载自 阿姆的博客 关于asp.net C# 导出Excel文件打开Excel文件格式与扩展名指定格式不一致的解决办法 导致“文件格式与扩展名指定格式不一致”这个问题,是因为大多数人在导出excel文件的时候,都是默认保存excel的格式, 也就是直接workbook.Save(path)或者workbook.SaveAs(path).进而忽略了SaveAs方法里面的参数.与保存excel文件格式有 关的是它第二个参数FileForMat. FileFormat 类型:System.Object

Linux下动态安装PHP扩展的一般方法(图)

------------------------------------------------------------------------------------------------------ 首先解释下面的Linux命令: ./configure  #脚本配置工具 ./configure --help  #查看脚本配置工具configure的命令行选项 /usr/local/php/bin/phpize #phpsize命令用于在编译好的PHP中扩展模块 [email protec

NSNull floatValue intValue 找不到指定方法解决方案

近期遇到一个问题: 由于后台人员对于接口数据没有做空值处理,导致客户端接收到的有些数据为空(NSNull),而针对此类数据恰好客户端的存储结构为int和float类型,类型转换时报出了[NSNull intValue]或者[NSNull floatValue] unrecognized selector sent to instance 的错误. 解决此问题尝试了以下思路: 1 添加returnObject == [NSNull null] 判断,NSNull的元素配置一个目标类型的初始值. 问

用VBS创建Excel后,打开时却提示“您尝试打开的文件 的格式与文件扩展名指定的格式不一致”

使用此VBS代码创建Excel: Set oexcel=CreateObject("excel.application") oexcel.Workbooks.Add() oexcel.ActiveWorkbook.SaveAs("d:\xx.xls") ' oexcel.Quit Set oexcel=Nothing 但创建出的Excel打开时会提示"您尝试打开的文件 的格式与文件扩展名指定的格式不一致". 虽然点确定后也可以使用. 但是..用户

Ubuntu 16.04 安装opencv的各种方法(含opencv contrib扩展包安装方法)

Ubuntu 16.04 安装opencv的各种方法(含opencv contrib扩展包安装方法) https://blog.csdn.net/ksws0292756/article/details/79511170 本文主要介绍安装opencv C++接口和python接口的几种方法. 首先介绍C++接口的,然后介绍Python接口的 C++接口安装 采用源码编译的安装方式,基本也就是这种方法了,首先在官网下载你想安装的版本的opencv压缩包,下载连接如下: https://github.