2012-01-27 14 views
6

में सभी परीक्षण मामलों के लिए एक जुनीट @ नियम लागू करने के लिए मैं परीक्षण सूट चलाने के लिए जुनीट 4.10 का उपयोग कर रहा हूं, और मैंने How to Re-run failed JUnit tests immediately? पोस्ट में मैथ्यू फ़ारवेल के अद्भुत नोट्स के बाद "पुनः प्रयास विफल परीक्षण" नियम लागू किया है। मैं निम्नलिखित कोड के साथ एक वर्ग "RetryTestRule" बनाया:एक सूट

public class RetryTestRule implements TestRule { 

    private final int retryCount; 

    public RetryTestRule(int retryCount) { 
    this.retryCount = retryCount; 
    } 

    @Override 
    public Statement apply(Statement base, Description description) { 
    return statement(base, description); 
    } 

    private Statement statement(final Statement base, final Description description) { 
    return new Statement() { 
     @Override 
     public void evaluate() throws Throwable { 
     Throwable caughtThrowable = null; 

     // retry logic 
     for (int i = 0; i < retryCount; i++) { 
      try { 
      base.evaluate(); 
      return; 
      } catch (Throwable t) { 
      caughtThrowable = t; 
      System.err.println(description.getDisplayName() + ": run " + (i + 1) + "  failed"); 
      } 
     } 
     System.err.println(description.getDisplayName() + ": Giving up after " + retryCount 
      + " failures"); 
     throw caughtThrowable; 
     } 
    }; 
    } 
} 

जब एक परीक्षण का मामला पूरी तरह से काम करता है यह अंदर एक नियम के रूप में इस का उपयोग करते हुए, लेकिन यह एक के हर परीक्षण मामले में @Rule संकेतन का उपयोग करने के लिए इष्टतम नहीं लगता है

@RunWith(Suite.class) 
@SuiteClasses({ 
    UserRegistrationTest.class, 
    WebLoginTest.class 
}) 
public class UserSuite {  
    @ClassRule 
    public static RetryTestRule retry = new RetryTestRule(2); 
} 

समस्या यह अपेक्षा के अनुरूप काम नहीं करता है: सुइट परिभाषा में एक भी अंकन के बजाय सूट, इसलिए थोड़ा की जाँच के बाद मैं अपने सुइट कक्षा में नए @ClassRule अंकन की कोशिश की असफल परीक्षण पुन: प्रयास नहीं किया जा रहा है । क्या किसी ने कोशिश की है और समाधान जानता है? मदद बहुत सराहना की है!

+0

एक डुप्लिकेट हो सकता है: http://stackoverflow.com/questions/7639353/how-to-define-junit-method-rule-in-a-suite – pholser

+0

आपको यह बिल्कुल चिंता नहीं है कि आपकी इकाई परीक्षण यादृच्छिक रूप से विफल? – Tobb

उत्तर

6

@ClassRule एस प्रति वर्ग एक बार निष्पादित होते हैं, प्रति विधि एक बार नहीं। प्रति विधि एक बार निष्पादित करने के लिए, आपको @Rule का उपयोग करने की आवश्यकता है जैसे आप कर रहे हैं, या How to define JUnit method rule in a suite? के उत्तर का पालन करें।

अपने मौजूदा नियम का पुन: उपयोग करने के लिए आपको चलाने के लिए नियमों की सूची के लिए नियम जोड़ सकते हैं, इस प्रकार RunRules वर्ग का उपयोग कर:

public class MyRunner extends BlockJUnit4ClassRunner { 
    public MyRunner(Class<?> klass) throws InitializationError { 
     super(klass); 
    } 

    @Override 
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) { 
     Description description= describeChild(method); 
     if (method.getAnnotation(Ignore.class) != null) { 
      notifier.fireTestIgnored(description); 
     } else { 
      RunRules runRules = new RunRules(methodBlock(method), Arrays.asList(new TestRule[]{new RetryTestRule(3)}), description); 
      runLeaf(runRules, description, notifier); 
     } 
    } 
} 

यह ऊपर जवाब से उदाहरण का उपयोग कर रहा है। उदाहरण के लिए आपके परीक्षण पर एनोटेशन होने पर आप शायद दो उत्तरों को और अधिक अच्छी तरह से दानेदार नियंत्रण के लिए जोड़ सकते हैं, एक रेट्रीटेस्टरूल बना सकते हैं।

+0

आपके त्वरित उत्तर, मैथ्यू के लिए बहुत बहुत धन्यवाद। जैसा कि आपने सुझाव दिया है और आसानी से एक कस्टम धावक और सूट बनाया है, मैंने दोनों उत्तरों को संयुक्त किया। फिर मैंने अपने सुइट क्लास और वॉयला में @RunWith (MySuite.class) जोड़ा! पूरे सूट के लिए विफलता पर स्वचालित परीक्षण पुनः प्राप्त करें :) – jbaxenom

+0

क्या मुझे कुछ याद आ रहा है या यह दृष्टिकोण (* दोनों उत्तरों का संयोजन *) परीक्षणों को @ @ClassRule के निष्पादन से पहले चलाने के लिए कारण बनाता है ... बाहरी संसाधन .. .. विधि से पहले – Daniel

संबंधित मुद्दे