2012-08-22 8 views
15

में प्रत्येक '@After' से पहले मेरे पास एक टेस्ट सूट है जहां मैं @After में सिस्टम से लॉग आउट कर रहा हूं और ब्राउज़र को @AfterClass में बंद कर रहा हूं। मैं प्रत्येक परीक्षण विधि के लिए सेलेनियम का उपयोग कर असफल परीक्षण स्क्रीनशॉट लेने के लिए @Rule का उपयोग करने का प्रयास कर रहा हूं। मैंने मैन्युअल रूप से जांच की है कि @Rule केवल @Before से पहले चलता है लेकिन मैं @Test और @After से पहले इसे सेट करना चाहता हूं। मुझे सरल समाधान नहीं मिला। किसी भी तरह की सहायता को आभार समझेंगे।प्रत्येक '@Test' के बाद '@Rule' लागू करें और JUnit

public class MorgatgeCalculatorTest { 

@Before 
public void before(){ 
    System.out.println("I am before"); 
} 
@BeforeClass 
public static void beforeclass(){ 
    System.out.println("I am beforeclass"); 
} 
@Test 
    public void test(){ 
     System.out.println("I am Test"); 
    } 
@Test 
public void test2(){ 
    System.out.println("I am Test2"); 
} 
@After 
    public void after(){ 
     System.out.println("I am after"); 
    } 
@AfterClass 
     public static void afterclass(){ 
      System.out.println("I am afterclass"); 

} 
@Rule 
ExpensiveExternalResource ExpensiveExternalResource = new ExpensiveExternalResource(); 

static class ExpensiveExternalResource implements MethodRule { 
    public ExpensiveExternalResource(){ 
     System.out.println("I am rule"); 
    } 

    @Override 
    public Statement apply(Statement arg0, FrameworkMethod arg1, Object arg2) { 
     // TODO Auto-generated method stub 
     return null; 
    }  
}    

उत्पादन मैं हो रही है

I am beforeclass 
I am rule 
I am before 
I am Test 
I am after 
I am rule 
I am before 
I am Test2 
I am after 
I am afterclass 
+0

मैंने बताया कि केवल एक परीक्षण विफल होने पर ही मैं केवल स्क्रीन शॉट लेना चाहता हूं। प्रत्येक परीक्षण के लिए नहीं: डी –

+0

मजेदार। मुझे केवल आदेश में दिलचस्पी थी, इसलिए वास्तव में आपका प्रश्न मेरा जवाब था :) –

+0

@ गैबरलिप्टाक :) मुझे खुशी है! –

उत्तर

19

नियमों की स्थापना के तरीके के कारण, आपके पास ऐसा नियम नहीं हो सकता है जो @ पहले या बाद में @ बाद में आता है। आप टेस्ट विधि पर रखे गए गोले जैसे नियमों के बारे में सोच सकते हैं। आगे बढ़ने वाला पहला खोल @ @/@ के बाद है। उसके बाद @ नियम लागू होते हैं।

आप जो करना चाहते हैं उसे करने का एक त्वरित तरीका है @ पूरी तरह से से बचने के लिए। एक नियम बनाया जा सकता है ताकि कोई विधि विफल हो जाए और यदि कोड के बाद आपका निष्पादन हो जाए तो यह स्क्रीनशॉट लेगा। यह @After जितना सुंदर नहीं है, लेकिन यह काम करता है। (मैंने टेस्टरुले को भी लागू किया क्योंकि विधि नियम को कम किया गया है)।

public class MortgageCalculatorTest { 
    @Before 
    public void before(){ 
     System.out.println("I am before"); 
    } 

    @BeforeClass 
    public static void beforeclass(){ 
     System.out.println("I am beforeclass"); 
    } 

    @Test 
    public void test(){ 
     System.out.println("I am a Test"); 
    } 

    @Test 
    public void test2(){ 
     System.out.println("I am a Failed Test"); 
     fail(); 
    } 

    @AfterClass 
      public static void afterclass(){ 
       System.out.println("I am afterclass"); 

    } 

    @Rule 
    public ExpensiveExternalResource ExpensiveExternalResource = new ExpensiveExternalResource(); 

    public static class ExpensiveExternalResource implements TestRule { 


     // public ExpensiveExternalResource(){} 


     public class ExpansiveExternalResourceStatement extends Statement{ 

      private Statement baseStatement; 

      public ExpansiveExternalResourceStatement(Statement b){ 
       baseStatement = b; 
      } 

      @Override 
      public void evaluate() throws Throwable { 
       try{ 
        baseStatement.evaluate(); 
       }catch(Error e){ 
        System.out.println("I take a Screenshot"); 
        throw e; 
       }finally{ 
        after(); 
       } 
      } 

      //Put your after code in this method! 
      public void after(){ 
       System.out.println("I am after"); 
      } 
     } 

     public Statement apply(Statement base, Description description) { 
      return new ExpansiveExternalResourceStatement(base); 

     } 


    } 
} 

नियम के सभी कार्य एक बयान में किया जाता है। एक org.junit.runners.model.Statement एक वर्ग है जो कोड के बंडल का प्रतिनिधित्व करता है। तो यहां लागू करें विधि कोड के बंडल को प्राप्त करती है जिसे आप चारों ओर खोलते हैं। आवेदन करें जो आपके द्वारा दिए गए कोड के बंडल को निष्पादित करता है और विधि विफलताओं को पकड़ने के लिए प्रयास/पकड़ विवरण के साथ इसे घेरता है।

इस विधि के लिए उत्पादन होता है:

I am beforeclass 
I am before 
I am a Test 
I am after 
I am before 
I am a Failed Test 
I take a Screenshot 
I am after 
I am afterclass 

आशा इस मदद करता है!

+0

ट्रॉय, आपकी टिप्पणी के लिए धन्यवाद। आपके समाधान से संकेत मिला। –

+0

मैं आउटपुट के साथ '@ आफ्टर' विधि जोड़ने का सुझाव दूंगा, इसलिए यह दिखाई देगा, कि बेसस्टेटमेंट.evaluate() वास्तव में '@ पहले' का कारण बनता है, फिर परीक्षण विधि, फिर '@ After' चलाने के लिए। – dhblah

1

ExternalResource नियम का उपयोग कर के बारे में क्या है?
ऐसा लगता है कि यह आपको जो चाहिए उसे पर्याप्त लचीलापन दे सकता है।
और यदि यह बिल्कुल आवश्यक नहीं है, तो बाहरी संसाधन के source code पर नज़र डालें।
यह काफी समझ में आता है कि उदाहरण के लिए नियम कैसे कार्यान्वित किया जाए जो केवल परीक्षण आमंत्रण के बाद ही काम करेगा।

4
public class ScreenshotTestRule implements MethodRule { 
    public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) { 
     return new Statement() { 
      @Override 
      public void evaluate() throws Throwable { 
       try { 
        statement.evaluate(); 

       } catch (Throwable t) { 
        captureScreenshot(frameworkMethod.getName()); 
        throw t; // rethrow to allow the failure to be reported to JUnit      
       } finally { 
        tearDown(); 
       } 
      } 

      public void tearDown() { 
       //logout to the system; 
      } 


      public void captureScreenshot(String fileName) { 
       try { 
        new File("target/surefire-reports/screenshot").mkdirs(); // Insure directory is there 
        FileOutputStream out = new FileOutputStream("target/surefire-reports/screenshot/screenshot-" + fileName + ".png"); 
        out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES)); 
        out.close(); 
       } catch (Exception e) { 
        // No need to crash the tests if the screenshot fails 
       } 
      } 
     }; 
    } 
} 
संबंधित मुद्दे