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();
    }
 

 

posted on 2014-09-18 11:42  一剑染征途  阅读(247)  评论(0)    收藏  举报