然后再实现各个注解自定义Filter类,实现Filter的shouldRun方法定义, 以Sprint为例:
/**
* Filter rules for the annotation
{@link Sprint}
*
* @author Carl Ji
*
*/
public class FilterSprint extends Filter
{
private String tgValue = null;
private Boolean _isOnly = false;
public FilterSprint(String targetValue)
{
setTgValue(targetValue);
}
public FilterSprint(String targetValue, Boolean isOnly)
{
setTgValue(targetValue);
_isOnly = isOnly;
}
public FilterSprint()
{
// TODO Auto-generated constructor stub
}
public Boolean getIsOnly()
{
return _isOnly;
}
public void setIsOnly(Boolean isOnly)
{
this._isOnly = isOnly;
}
public String getTgValue()
{
return tgValue;
}
public void setTgValue(String tgValue)
{
this.tgValue = tgValue;
}
@Override
public boolean shouldRun(FrameworkMethod method)
{
Sprint aSprint = method.getAnnotation(Sprint.class);
return filterRule(aSprint);
}
@Override
public boolean shouldRun(Description description)
{
if(description.isTest())
{
Sprint aSprint = description.getAnnotation(Sprint.class);
return filterRule(aSprint);
}
else
{
return true;
}
}
@Override
public String describe()
{
// TODO Auto-generated method stub
return null;
}
// Implement of filter rule for Sprint Annotation
private boolean filterRule(Sprint aSprint)
{
if(_isOnly)
{
if(aSprint != null && aSprint.value().equalsIgnoreCase(tgValue))
{
return true;
}
else
{
return false;
}
}
else
{
if(aSprint == null)
{
return true;
}
else
{
if(0 >= new StringComparator().compare(aSprint.value(), tgValue))
{
return true;
}
}
}
return false;
}
我这里多了个isOnly属性,是为了解决历史遗留的问题。很多以前的Case并没有我们加上新自定义的注解,那么可以通过这个属性来定义这些Case要不要执行。
当然核心的Filter的方法,还是要看大家各自的需求,自行设定。
优化,第二个解决办法
上面的实现方法做了很多工作,比如你要扩展JunitCore类,扩展Request 类,扩展RunnerBuilder类,还要扩展BlockJunit4ClassRunner类,那么研究过JUnit源码的童鞋可能知道,JUnit是提供入口让我们去注入Filter对象。具体是在ParentRunner类里的下面方法:
//
// Implementation of Filterable and Sortable
//
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();
}
}
那其实我们只要把我们自定义的Filter对象传进来,我们的需求也实现了。
public class FilterCollections extends Filter
{
List<Filter> filters = null;
public FilterCollections(String intent)
{
try
{
filters = FilterFactory.createFilters(intent);
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
@Override
public boolean shouldRun(Description description)
{
List<Boolean> result = new ArrayList<Boolean>();
for(Filter filter : filters)
{
if(filter != null && filter.shouldRun(description))
{
result.add(true);
}
else
{
result.add(false);
}
}
if(result.contains(false))
{
return false;
}
else
{
return true;
}
}