2012-11-09 14 views
5

Eclipse ve Ant'den çalıştırmak istediğim birkaç JBehave testim var. Eclipse ben grafiksel çıktı yapılmaktadır tüm farklı hikayeleri, senaryolar ve adımların bir ağacı görmek istiyorum, bu yüzden bunu yapar testler için özel bir koşucu ekledi: Eclipse ve Ant'deki farklı Junit TestRunner nasıl kullanılır?

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

Ama tam tersine

çalıştırırken Ant ile ve Sürekli Entegrasyon sunucusunda yapılan testlerle, çıktıdaki tek bir öğe olarak sadece tüm hikayeyi görmek istiyorum. Bu genellikle hiçbir şerhe elde edilir:

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

Yani Ant (junit Ant görev) Eclipse farklı bir koşucu kullanmak olduğunu nasıl bilebilirim? şeyler daha karmaşık hale getirmek için:

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

Herhangi Fikirler: Şu anda testler (değil Ant) Eclipse bir test paketi kullanmak?

ihtiyaçlarınızı sığabilecek Alkış, Tilmann'ın

cevap

6

bazı birkaç hafta önce kesmek vermedi. Bir ünite test çalışması durumunda Eclipse tarafından yürütülen java komutunun, adında her zaman bir paket içerdiğini fark ettim. Bu geri doğrudur verirse Yani, muhtemelen Eclipse altında test yapmaktayız:

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

Biliyorum, onun değil yüzde 100 çözüm, ancak genellikle çalışır ve onun hiçbir şey daha iyi.

ben oluşturulan ve sizin için bir koşucu + Ek açıklama çifti test:

Ek Açıklama: Varsayılan olarak

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

gerçekten JUnit4 için varsayılan defaultrunner olarak JUnit4 kullanır.

ek açıklama bilgileri kullanır 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); 
    } 
} 

Ve bir kullanım örneği:

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

yüzden üstünde, Eclipse JUnit4 koşucu ile çalışacak bu test Eclipse dışında parametrelenmiş.

+0

Çevre girdisini beğenmezseniz, iş parçacığının izini de alabilir ve içinde belirli sınıfları tutturabilirsiniz. –

+2

Thats harika, çok teşekkür ederim! Ve neredeyse mükemmel çalışıyor. Değiştirdiğim tek şey, bir sınıfta bulunmayan süper sınıf hiyerarşisi boyunca ek açıklama aramaktı. – Gandalf

+0

O halde lütfen yazımın bir düzenlemesini yapın, sonra diğerleri de bu değişikliğe sahip olabilir. –

İlgili konular