【JUnit4.10源码分析】6.1 排序和过滤
abstract class ParentRunner<T> extends Runner implements Filterable,Sortable
本节介绍排序和过滤。
(尽管JUnit4.8.2源码分析-6.1 排序和过滤中演示了客户使用排序和过滤的方式,也有些不明确其设计意图。可是。先读懂源码为妙。说不定看着看着就明确了。
)
org.junit.runner.manipulation包
排序和过滤的相关类型。在org.junit.runner.manipulation包中。Sortable和Filterable是两个依赖注入接口。而Sorter和Filter的apply是注入方法。
1.比如Sortable是一个函数接口。yqj2065认为Sortable.sort(Sorter)不如叫Sortable.setSorter(Sorter)。
package org.junit.runner.manipulation;
public interface Sortable {
public void sort(Sorter sorter);
}
2.Filterable类似,定义了void filter(Filter filter) throws NoTestsRemainException;
3.NoTestsRemainException抱怨filter 将全部的測试都过滤掉了。
4.Sorter implements Comparator<Description>。我们知道。java.util.Comparator接口是一个策略类,定义了int compare(T o1, T o2)方法。而Sorter是一个简单的代理模式的Proxy角色。
通过构造器注入的方式Sorter(Comparator<Description>comparator)初始化realSubject角色。測试程序猿能够定义自己的排序器。并且。Sorter应用Null
Object模式,定义了NULL静态内部子类。
package org.junit.runner.manipulation;
import java.util.Comparator;
import org.junit.runner.Description;
public class Sorter implements Comparator<Description> {
/**
* NULL is a <code>Sorter</code> that leaves elements in an undefined order
*/
public static Sorter NULL= new Sorter(new Comparator<Description>() {
public int compare(Description o1, Description o2) {
return 0;
}});
public void apply(Object object) {
if (object instanceof Sortable) {
Sortable sortable = (Sortable) object;
sortable.sort(this);
}
}
}
Sorter的方法apply(Object object),将this应用于Object 身上。
5.Filter是一个抽象类。当须要过滤某些測试时。測试程序猿要定义自己的过滤器。
Filter应用Null Object模式,定义了ALL静态内部子类。静态工厂生成public static Filter matchMethodDescription(final Description desiredDescription)。而public
Filter intersect(final Filter second)同意多个Filter串接。
依照上述几个样例,我们能够写出自己的过滤器。
package sortFilter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter; /**
*排除指定的方法。
* @author yqj2065
*/
public class MethodNameFilter extends Filter {
private final Set<String> excludedMethods = new HashSet<>(); public MethodNameFilter(String... excludedMethods) {
this.excludedMethods.addAll(Arrays.asList(excludedMethods));
} @Override
public boolean shouldRun(Description description) {
String methodName = description.getMethodName();
return !excludedMethods.contains(methodName);
} @Override
public String describe() {
return this.getClass().getSimpleName() + "-excluded methods: "
+ excludedMethods;
}
}
Unit4有測试方法a() 、@Ignore b() 、c() 和d()等,
package demo; import static tool.Print.*;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import sortFilter.MethodNameFilter;
import units.Unit4; /**
*
* @author yqj2065
*/
public class FilterDemo { public static void main(String... args) {
try {
BlockJUnit4ClassRunner runner = null;
try {
runner = new BlockJUnit4ClassRunner(Unit4.class);
} catch (InitializationError e) {
}
runner.filter(new MethodNameFilter("a","b","c", "d"));//排除全部
runner.run(new RunNotifier());
} catch (NoTestsRemainException ex) {
pln(ex);
}
}
}
输出:org.junit.runner.manipulation.NoTestsRemainException
保留@Ignore b(),尽管没有运行測试。可是不抛出异常。
ParentRunner<T>与排序和过滤
ParentRunner implements Filterable,Sortable
注意到:JUnit4.8.2中ParentRunner 有域Filter fFilter= null;而JUnit4.10不再有该域。而是以过滤后的private List<T> fFilteredChildren= null代替。
因为ParentRunner<T>的类型參数T,代表其某种孩子的类型。BlockJUnit4ClassRunner的T为FrameworkMethod。Suite的T为Runner。
在ParentRunner中统一地处理T显得比較复杂。并且JUnit4.10代码变化较大。
过滤相关的代码
getFilteredChildren()惰性初始化域fFilteredChildren,当中调用getChildren()由子类给出实现,返回List<T>。
@Override filter(Filter filter),就须要差别对待FrameworkMethod和Runner。
1.JUnit没有使用instanceof。而是利用abstract Description describeChild(T child),无论T是FrameworkMethod还是Runner。总能够构造(FrameworkMethod)或获得(Runner)一个Description返回值;
2.而Filter定义的public abstract boolean shouldRun(Description description),能够统一处理两者。
3.因而。ParentRunner定义了boolean shouldRun(Filter filter, T each) ,调用前者。
可是,从实际參数看,filter.shouldRun(FrameworkMethod的Description )才进行比較和过滤;而filter.shouldRun(Runner.getDescription ),总是返回true、
于是,第5行代码if (shouldRun(filter, each))出现有意思的情况。
对于FrameworkMethod each。假设shouldRun,其代码应该为
try {
//
} catch (NoTestsRemainException e) {
iter.remove();
}
由于filter.apply(FrameworkMethod )肯定直接return;而shouldRun推断不通过,就意味着iter.remove();在fFilteredChildren中删除该方法;
对于Runner each。总是shouldRun,并且运行filter.apply(each);从而调用到each.filter(filter);能够看出。假设没有FrameworkMethod ,能够直接运行each.filter(filter);可是如今不得不打乒乓球。利用filter.apply(each)排除掉FrameworkMethod
。
private List<T> fFilteredChildren= null;
public void filter(Filter filter) throws NoTestsRemainException {
for (Iterator<T> iter = getFilteredChildren().iterator(); iter.hasNext(); ) {
T each = iter.next();
if (shouldRun(filter, each))
try {
filter.apply(each);
} catch (NoTestsRemainException e) {
iter.remove();
}
else
iter.remove();
}
if (getFilteredChildren().isEmpty()) {
throw new NoTestsRemainException();
}
}
private List<T> getFilteredChildren() {
if (fFilteredChildren == null)
fFilteredChildren = new ArrayList<T>(getChildren());
return fFilteredChildren;
}
private boolean shouldRun(Filter filter, T each) {
return filter.shouldRun(describeChild(each));
}
作为比較,JUnit4.8.2的相关代码列在以下,有时间再看。
private Filter fFilter= null;
public void filter(Filter filter) throws NoTestsRemainException {
fFilter= filter;
for (T each : getChildren())
if (shouldRun(each))
return;
throw new NoTestsRemainException();
} private List<T> getFilteredChildren() {
ArrayList<T> filtered= new ArrayList<T>();
for (T each : getChildren())
if (shouldRun(each))
try {
filterChild(each);
sortChild(each);
filtered.add(each);
} catch (NoTestsRemainException e) {
// don't add it
}
Collections.sort(filtered, comparator());
return filtered;
} private void filterChild(T child) throws NoTestsRemainException {
if (fFilter != null)
fFilter.apply(child);
} private boolean shouldRun(T each) {
return fFilter == null || fFilter.shouldRun(describeChild(each));
}
排序的非常easy。略。
【JUnit4.10源码分析】6.1 排序和过滤的更多相关文章
- 【JUnit4.10源码分析】5 Statement
假设要评选JUnit中最最重要的类型.或者说核心,无疑是org.junit.runners.model.Statement.Runner等类型看起来热闹而已. package org.junit.ru ...
- 【JUnit4.10源码分析】5.2 Rule
标注@Rule TestRule是一个工厂方法模式中的Creator角色--声明工厂方法. package org.junit.rules; import org.junit.runner.Descr ...
- 【JUnit4.10源码分析】3.4 Description与測试树
Description使用组合模式描写叙述一个測试树.组合模式中全部元素都是Composite对象. Description有成员变量private final ArrayList<Descri ...
- [Guava源码分析]Ordering:排序
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3876466.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- JUnit4.12 源码分析之TestClass
1. TestClass // 源码:org.junit.runners.model.TestClass // 该方法主要提供方法校验和注解搜索 public class TestClass impl ...
- 10.源码分析---SOFARPC内置链路追踪SOFATRACER是怎么做的?
SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...
- JUnit4.12 源码分析之Statement
1. Statement 抽象类Statement作为命令模式的Command,只有一个方法 各种Runner作为命令模式中的Invoker,将发出各种Statement,来表示它们运行JUnit测试 ...
- JUnit4.12 源码分析(二)之TestRule
1. TestRule TestRule和@Before,@After,@BeforeClass,@AfterClass功能类似,但是更加强大; JUnit 识别TestRule的两种方式: 方法级别 ...
- jQuery1.11源码分析(5)-----Sizzle编译和过滤阶段[原创]
在上一章中,我们说到在之前的查找阶段我们已经获得了待选集seed,那么这一章我们就来讲如何将seed待选集过滤,以获得我们最终要用的元素. 其实思路本质上还是不停地根据token过滤,但compile ...
随机推荐
- 【JAVA】Eclipse中使用git进行pull远程代码
当使用eclipse或者MyEclipse进行pull远程代码的时候,或者github的代码的时候报如下错误代码: 代表我们没有配置我们的Git地址,这里我教大家配置一下.首先下面是错误代码: The ...
- Java内存区域与内存异常
参考:深入理解Java虚拟机 周志明 方法区 虚拟机战 本地方法栈 堆 程序计数器 其他 设置 方法区 线程共享,加载类信息.常量.静态变量.JIT后的代码,别名Non-Heap 对于HotSpot, ...
- WCF发布方式介绍
转载出处:http://blog.csdn.net/fangxing80/article/details/6101790 从VS2005推出WCF以来,WCF逐步取代了Remoting, WebSer ...
- solr requestHandler
使用哪一个handler: 1. 可以通过在url中追加有名字的handler(以 ' / ' 开头命名)的名称来指定使用哪一个handler. 如: <requestHandler name= ...
- k8s通过label来控制pod的位置
默认情况下,scheduler会将pod调度到所有可用的Node,不过有些情况我们希望将 Pod 部署到指定的 Node,比如将有大量磁盘 I/O 的 Pod 部署到配置了 SSD 的 Node:或者 ...
- (3)java运行
java文件后后缀名为 .java 一个java文件的运行需要分为两个阶段,编译阶段和运行阶段 编译阶段 检查java源代码的语法是否错误 生成对应平台的.class文件 例如 :有个A.java的文 ...
- 2017中国大学生程序设计竞赛 - 女生专场B【DP】
B HDU - 6024 [题意]:n个教室,选一些教室建造糖果商店. 每个教室,有一个坐标xi和在这个教室建造糖果商店的花费ci. 对于每一个教室,如果这个教室建造糖果商店,花费就是ci,否则就是与 ...
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- java开发3~5年工作经验面试题
关于java基础 String,StringBuilder,StringBuffer区别是什么?底层数据结构是什么?分别是如何实现的? HashSet的底层实现是什么?它与HashMap有什么关系? ...
- Codeforces Round 254 (Div. 2)
layout: post title: Codeforces Round 254 (Div. 2) author: "luowentaoaa" catalog: true tags ...