0

私は独自の junit ランナーを作成しようとしていますが、現在、適切なテストの説明を返すことに固執しています。

public class ParameterizedWrapper extends Suite {
    private List<Runner> fRunners;

    /**
     * @throws Throwable 
     * 
     */
    public ParameterizedWrapper(final Class<?> clazz) throws Throwable {
        super(clazz, Collections.<Runner>emptyList());
        fRunners = constructRunners(getParametersMethod());
    }

    protected List<Runner> constructRunners(final FrameworkMethod method) throws Exception, Throwable {
        @SuppressWarnings("unchecked")
        Iterable<Object[]> parameters = (Iterable<Object[]>) getParametersMethod().invokeExplosively(null);
        ArrayList<Runner> runners = new ArrayList<Runner>();
        int index = 0;
        for (Object[] parameter : parameters) {
            Class<?> testClass = getTestClass().getJavaClass();
            WrappedRunner wrappedRunner = testClass.getAnnotation(WrappedRunner.class);
            Runner runner = wrappedRunner.value().getConstructor(Class.class).newInstance(getTestClass().getJavaClass());
            runners.add(new WrappingRunner(runner, parameter, testClass, index++));
        }
        return runners;
    }

    private FrameworkMethod getParametersMethod() throws Exception {
        List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(Parameters.class);
        for (FrameworkMethod each : methods) {
            if (each.isStatic() && each.isPublic()) {
                return each;
            }
        }

        throw new Exception("No public static parameters method on class " + getTestClass().getName());
    }

    @Override
    protected List<Runner> getChildren() {
        return fRunners;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    public static @interface WrappedRunner {
        Class<? extends Runner> value();
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public static @interface ParameterSetter {
    }

}

class WrappingRunner extends Runner {
    private Runner wrappedRunner;

    private Object[] parameters;

    private Class<?> testClass;

    private int testPosition;

    public WrappingRunner(final Runner runner, final Object[] params, final Class<?> clazz, final int position) {
        wrappedRunner = runner;
        parameters = params;
        testClass = clazz;
        testPosition = position;
    }

    @Override
    public Description getDescription() {
        Description originalDescription = wrappedRunner.getDescription();
        Description newDescription = Description.createSuiteDescription(nameFor(""), new Annotation[0]);
        for (Description child : originalDescription.getChildren()) {
            newDescription.addChild(decorateChildDescription(child));
        }

        return newDescription;
    }

    private String nameFor(String name) {
        return String.format("%1$s[%2$s]", name, testPosition);
    }

    protected Description decorateChildDescription(final Description originalChildDescription) {
        Description d = Description.createTestDescription(originalChildDescription.getTestClass(),
                nameFor(originalChildDescription.getMethodName()),
                originalChildDescription.getAnnotations().toArray(new Annotation[0]));
        return d;
    }

    @Override
    public void run(final RunNotifier notifier) {
        try {
            ParameterStorage.storeParameters(testClass, parameters);
            wrappedRunner.run(notifier);
        } finally {
            ParameterStorage.clearParameters(testClass);
        }
    }
}

ランナーが機能するかどうかを確認するためのテストクラスがあります。ランナーは、テストの名前が変なことを除けば問題なく動作します。Eclipse では、すべてのテストが表示され、ルート化されていないテスト カテゴリが追加されます。

ここに画像の説明を入力

そして、surefire は私の命名をまったく使用しません。

ここに画像の説明を入力

私のランナーとランナーで生成された説明オブジェクトを比較しましParameterizedたが、違いはないようです。

4

2 に答える 2

1

少し醜いですが、子ランナーのリストを親コンストラクターに渡す方が安全です。

public ParameterizedWrapper(final Class<?> clazz) throws Throwable {
  super(clazz, constructRunners(getParametersMethod());
}

private static List<Runner> constructRunners(final FrameworkMethod method)
    throws Throwable {
  ...

オーバーライドする必要はありませんSuite.getChildren()

于 2013-02-13T22:42:00.310 に答える
0

もう少しチェックしたところ、ランナーによって生成された説明は問題ないことがわかりました。ただし、実際のテスト実行時に使用される記述と矛盾するため、それは問題ではありません。そのため、eclipse はエントリが実行されていないと表示し、surefire は私の名前を表示しません。

現在、独自の通知機能を使用してテストの開始点をキャッチし、その時点で構成を置き換えることを考えています。

誰かがより良い解決策を持っているなら、私はそれについて知りたいです:)。

于 2013-02-13T00:22:44.247 に答える