2012-11-09 31 views
5

मेरे पास कुछ जेबीहेव परीक्षण हैं जो मैं ग्रहण और चींटी से भागना चाहता हूं। ग्रहण में मैं सभी विभिन्न कहानियों, परिदृश्यों और चरण हैं, जो चित्रमय परिणाम में प्रदर्शन कर रहे हैं का एक वृक्ष देखना चाहते हैं, तो मैं परीक्षण है कि यह करता है के लिए एक कस्टम धावक कहा:ग्रहण और चींटी में विभिन्न जूनिट टेस्टरनर का उपयोग कैसे करें?

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

लेकिन इसके विपरीत जब चल रहा है चींटी और निरंतर एकीकरण सर्वर में परीक्षण मैं आउटपुट में केवल एक ही आइटम के रूप में केवल हर पूरी कहानी देखना चाहता हूं। यह आमतौर पर किसी भी टिप्पणी के बिना हासिल की है:

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

तो मैं कैसे बता सकता चींटी (JUnit चींटी कार्य) ग्रहण तुलना में एक अलग धावक उपयोग करने के लिए? बातें और अधिक जटिल बनाने के लिए: फिलहाल मैं ग्रहण (चींटी में नहीं) में टेस्ट स्वीट का उपयोग परीक्षण चलाने के लिए:

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

किसी भी विचार?

चीयर्स, Tilmann

उत्तर

6

मैं कुछ कुछ सप्ताह पहले हैक किया था, कि अपनी आवश्यकताओं फिट कर सकते हैं। मुझे एहसास हुआ कि जावा कमांड, जिसे यूनिट टेस्ट रन के मामले में एक्लिप्स द्वारा निष्पादित किया जाता है, हमेशा इसके नाम पर एक पैकेज होता है। तो अगर यह वापस सही देता है, शायद आप अपने परीक्षण ग्रहण के तहत चल रहे हैं:

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

मुझे पता है, इसकी नहीं 100 प्रतिशत समाधान है, लेकिन आम तौर पर काम करता है, और उसके लिए कुछ भी नहीं की तुलना में बेहतर।

मैं बनाया है और आप के लिए एक धावक + एनोटेशन जोड़ी का परीक्षण किया:

एनोटेशन:

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

डिफ़ॉल्ट रूप से यह defaultrunner, जो वास्तव में JUnit4 के लिए डिफ़ॉल्ट है के रूप में JUnit4 उपयोग करता है।

धावक, जो एनोटेशन की जानकारी का उपयोग करता:

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 { 
... 
} 

तो यह परीक्षण, ग्रहण में JUnit4 धावक के साथ चलेंगे साथ ग्रहण के बाहर पैरामीटर।

+0

यदि आपको पर्यावरण प्रविष्टि पसंद नहीं है, तो आप धागे का निशान भी प्राप्त कर सकते हैं, और इसमें कुछ ग्रहण विशिष्ट कक्षाएं देख सकते हैं। –

+2

बहुत बढ़िया है, बहुत बहुत धन्यवाद! और यह लगभग perfekt काम करता है। एकमात्र चीज जो मैंने बदल दी थी वह कक्षा में नहीं मिलने पर सुपर क्लास पदानुक्रम के साथ एनोटेशन देखना था। – Gandalf

+0

फिर कृपया मेरी पोस्ट का संपादन करें, और फिर दूसरों को भी यह परिवर्तन हो सकता है। –