junit4.12源码分析-runner周边类
上一篇博文介绍了从开始运行测试到选择哪个builder运行runner的过程,写的很少,因为许多细小的地方没写。这系列博文也将只介绍核心重点,细小的地方自己看代码就能够理解力。
再介绍runner之前,先介绍与之相关联的类
FrameworkMethod与FrameworkField类、TestClass类
FrameworkMethod是Java反射中Method的封装,FrameworkField是java反射中Field的封装。这两个类比较好理解,提供了一些方法,比如:isStatic、isPublic、validatePublicVoid等,其中isShadowedBy方法用于隐藏父类方法或属性,对于属性,如果父类属性与子类一样则隐藏,对于方法,如果父类与子类方法名一致,参数一致,则隐藏。
public boolean isShadowedBy(FrameworkField otherMember) { return otherMember.getName().equals(getName()); } public boolean isShadowedBy(FrameworkMethod other) { if (!other.getName().equals(getName())) { return false; } if (other.getParameterTypes().length != getParameterTypes().length) { return false; } for (int i = 0; i < other.getParameterTypes().length; i++) { if (!other.getParameterTypes()[i].equals(getParameterTypes()[i])) { return false; } } return true; }
TestClass是java中class的封装,构造函数中遍历所有父类和本类具有注释的field和method,放到LinkedHashMap。父类@Before和@BeforeClass的注解方法总在子类之前,从而保证父类@Before和@BeforeClass的注解方法会在子类的这些注解方法之前执行。@After和@AfterClass的注解方法按照默认list.add,保持了子类@After和@AfterClass注解方法会在父类的这些注解方法之前执行。
protected static <T extends FrameworkMember<T>> void addToAnnotationLists(T member, Map<Class<? extends Annotation>, List<T>> map) { for (Annotation each : member.getAnnotations()) { Class<? extends Annotation> type = each.annotationType(); List<T> members = getAnnotatedMembers(map, type, true); if (member.isShadowedBy(members)) { return; } if (runsTopToBottom(type)) { members.add(0, member); } else { members.add(member); } } } private static boolean runsTopToBottom(Class<? extends Annotation> annotation) { return annotation.equals(Before.class) || annotation.equals(BeforeClass.class); }
Description类和Discribable接口
Description类是对测试类或者测试方法的描述,测试类描述拥有children,测试方法没有。Describable接口提供了getDescription方法,集成该接口的类都可以被描述。ParentRunner继承该接口,创建Description,遍历当前Runner下的Children,并将这些child的Description添加到Description中最后返回
public Description getDescription() { Description description = Description.createSuiteDescription(getName(), getRunnerAnnotations()); for (T child : getFilteredChildren()) { description.addChild(describeChild(child)); } return description; } BlockJUnit4ClassRunner中 protected Description describeChild(FrameworkMethod method) { Description description = methodDescriptions.get(method); if (description == null) { description = Description.createTestDescription(getTestClass().getJavaClass(), testName(method), method.getAnnotations()); methodDescriptions.putIfAbsent(method, description); }return description; }
Suite中
protected Description describeChild(Runner child) {
return child.getDescription();
}
浙公网安备 33010602011771号