5

Eclipse と Ant から実行したい JBehave テストがいくつかあります。Eclipse では、グラフィカルな出力で実行されるすべての異なるストーリー、シナリオ、およびステップのツリーを表示したいので、これを行うテストにカスタム ランナーを追加しました。

@RunWith(de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.class)
public class MyStoryTest extends org.jbehave.core.junit.JUnitStories
{
    // ...
}

しかし、反対に、Ant を使用して継続的インテグレーション サーバーでテストを実行する場合、すべてのストーリー全体のみを出力の単一のアイテムとして表示したいと考えています。これは通常、注釈なしで実現されます。

public class MyStoryTest extends JUnitStories
{
    // ...
}

では、Ant (junit Ant タスク) に Eclipse とは異なるランナーを使用するように指示するにはどうすればよいでしょうか? 物事をより複雑にするために: 現時点では、テストを実行するために (Ant ではなく) Eclipse でテスト スイートを使用しています。

@RunWith(org.junit.extensions.cpsuite.ClasspathSuite.class)
@org.junit.extensions.cpsuite.ClassnameFilters("foo.mypackage.tests.*")
public class MyStoriesTestSuite
{
    // Nothing more to say ;)
}

何か案は?

乾杯、ティルマン

4

1 に答える 1

6

私は数週間前にいくつかのハックを行いました。それはあなたのニーズを満たすことができます. 単体テストの実行時にEclipseによって実行されるjavaコマンドには、その名前に常にパッケージが含まれていることに気付きました。したがって、これが true を返した場合、おそらく Eclipse でテストを実行しています。

System.getProperty( "sun.java.command" ).contains( "org.eclipse.jdt" )

100% の解決策ではないことはわかっていますが、通常は機能し、何もないよりはましです。

Runner+Annotation のペアを作成してテストしました。

注釈:

package org.junit.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.junit.runner.Runner;
import org.junit.runners.JUnit4;

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target( ElementType.TYPE )
public @interface RunWithInEnvironment {
    Class<? extends Runner> eclipse();
    Class<? extends Runner> defaultRunner() default JUnit4.class;
}

デフォルトでは、JUnit4 を defaultrunner として使用します。これは、JUnit4 の実際のデフォルトです。

注釈の情報を使用するRunner :

package org.junit.runners;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.junit.annotation.RunWithInEnvironment;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;

public class EnvironmentDependentRunner extends Runner {
    protected Class<?> testClass;
    protected Runner delegate;

    public EnvironmentDependentRunner(Class<?> testClass) {
        super();
        this.testClass = testClass;
        RunWithInEnvironment annotation = findAnnotationInClassHierarchy(testClass);
        assertNotNull( EnvironmentDependentRunner.class.getSimpleName() + " can be used only with test classes, that are annotated with " + RunWithInEnvironment.class.getSimpleName() + " annotation somewhere in their class hierarchy!", annotation );
        Class<? extends Runner> delegateClass = null;
        if ( System.getProperty( "sun.java.command" ).contains( "org.eclipse.jdt" ) && annotation.eclipse() != null ) {
            delegateClass = annotation.eclipse();
        }
        else {
            delegateClass = annotation.defaultRunner();
        }
        try {
            Constructor<? extends Runner> constructor = delegateClass.getConstructor( Class.class );
            delegate = constructor.newInstance(testClass);
        } catch (NoSuchMethodException e) {
            fail( delegateClass.getName() + " must contain a public constructor with a " + Class.class.getName() + " argument.");
        } catch (SecurityException e) {
            throw new RuntimeException("SecurityException during instantiation of " + delegateClass.getName() );
        } catch (InstantiationException e) {
            throw new RuntimeException("Error while creating " + delegateClass.getName() );
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Error while creating " + delegateClass.getName() );
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Error while creating " + delegateClass.getName() );
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Error while creating " + delegateClass.getName() );
        }
    }

    private RunWithInEnvironment findAnnotationInClassHierarchy(Class<?> testClass) {
        RunWithInEnvironment annotation = testClass.getAnnotation(RunWithInEnvironment.class);
        if (annotation != null) {
            return annotation;
        }

        Class<?> superClass = testClass.getSuperclass();
        if (superClass != null) {
            return findAnnotationInClassHierarchy(superClass);
        }

        return null;
    }

    @Override
    public Description getDescription() {
        return delegate.getDescription();
    }

    @Override
    public void run(RunNotifier arg0) {
        delegate.run(arg0);
    }
}

そして使用例

@RunWithInEnvironment( eclipse=JUnit4.class, defaultRunner=Parameterized.class)
@RunWith( EnvironmentDependentRunner.class)
public class FooTest {
...
}

したがって、このテストは、Eclipse の JUnit4 ランナーで実行され、Eclipse の外部でパラメーター化されます。

于 2012-11-12T22:33:08.383 に答える