然后再实现各个注解自定义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; } } |