2010-04-14 99 views
124

我發現JUnit的正確使用(或至少文檔)非常混亂。 這個問題既可以作爲未來的參考,也可以作爲一個真正的問題。JUnit混淆:使用'擴展TestCase'或'@Test'?

如果我理解正確的話,有創建和運行JUnit測試方法主要有兩種:

方法A(JUnit的3式):創建一個擴展的TestCase類,並開始測試方法用詞test。將該類作爲JUnit Test(在Eclipse中)運行時,將自動運行以test這個詞開頭的所有方法。

import junit.framework.TestCase; 

public class DummyTestA extends TestCase { 

    public void testSum() { 
     int a = 5; 
     int b = 10; 
     int result = a + b; 
     assertEquals(15, result); 
    } 
} 

方法B(JUnit 4中樣式):創建一個 '正常' 的類和在前面加上一個@Test註釋的方法。請注意,您不必使用單詞test開始該方法。

import org.junit.*; 
import static org.junit.Assert.*; 

public class DummyTestB { 

    @Test 
    public void Sum() { 
     int a = 5; 
     int b = 10; 
     int result = a + b; 
     assertEquals(15, result); 
    } 
} 

將兩者混合似乎並不是一個好主意, this stackoverflow question

現在,我的問題(S):

  1. 什麼是首選的方法,或當您將使用一個,而不是其他?
  2. 方法B允許通過擴展@Test註釋來測試異常,如@Test(expected = ArithmeticException.class)但是,如何使用方法A測試異常?
  3. 當使用方法A,就可以組中的測試套件這樣一些測試類:

    TestSuite suite = new TestSuite("All tests");
    suite.addTestSuite(DummyTestA.class);
    suite.addTestSuite(DummyTestAbis.class);

    但這不能與方法B中使用(因爲每個測試類都應該子類TestCase)。 對方法B進行分組測試的正確方法是什麼?

編輯:我已經添加了JUnit版本,這兩種方法

回答

96

的區別是相當容易:

  • 延伸TestCase是(當然它仍然支持JUnit 4)
  • 使用@Test註釋是由JUnit 4引入的方式

通常,您應該選擇註釋路徑,除非需要與JUnit 3(和/或早於Java 5的Java版本)的兼容性。新辦法有幾個好處:

要在一個JUnit 3 TestCase測試預期的例外

  • 支持替代測試運行,你就必須使文字清晰。

    public void testMyException() { 
        try { 
        objectUnderTest.myMethod(EVIL_ARGUMENT); 
        fail("myMethod did not throw an Exception!"); 
        } catch (MyException e) { 
        // ok! 
        // check for properties of exception here, if desired 
        } 
    } 
    
  • +0

    有幫助和全面的答案,但我不完全理解「檢查異常消息」。檢查硬編碼的字符串將成爲維護的噩夢。您必須具有「檢查特定異常類型的屬性」的含義。 – thSoft 2010-04-14 09:17:29

    +3

    @thSoft:它並不經常被使用,但偶爾我想確保例外方法提到違規字段。然後,一個簡單的'assertTrue(e.getMessage()。contains(「foo」))'可能會有用。 – 2010-04-14 09:22:06

    +1

    即使在JUnit4中,當你必須檢查消息或異常的其他屬性(如原因)時,這也是一個重要的習慣用法。預期的方法只檢查類型。 – Yishai 2010-04-14 13:35:22

    21

    我有JUnit 4中(譯註方法)的偏愛,因爲我覺得它更靈活。

    如果你想建立測試套件JUnit 4中,你必須創建一個類分組這樣所有的測試:

    import org.junit.runner.RunWith; 
    import org.junit.runners.Suite; 
    import org.junit.runners.Suite.SuiteClasses; 
    
    
    @RunWith(Suite.class) 
    @SuiteClasses({ 
        Test1.class, 
        Test2.class, 
        Test3.class, 
        Test4.class 
    })public class TestSuite 
    { 
    /* empty class */ 
    } 
    
    1
    1. 「首選」的方法是使用已經出臺的註解,因爲JUnit 4中他們做了很多事情變得更加容易(見你的第二個問題)

    2. 可以使用對於簡單的try/catch塊:

    
    public void testForException() { 
        try { 
         Integer.parseInt("just a string"); 
         fail("Exception should have been thrown"); 
        } catch (final Exception e) { 
         // expected 
        } 
    } 
    
    3

    你應該使用JUnit 4,這是更好。

    許多框架已經開始廢棄JUnit 3.8支持。

    這是從Spring 3.0參考文檔:

    【警告】傳統的JUnit 3.8類 層次棄用

    在一般情況下,你應該儘量使用最新的穩定版本一個框架,當你開始新的東西。

    14

    您的問題有一個未答覆的部分,那就是「對方法B進行分組測試的正確方法是什麼?」

    官方答案是你用@RunWith(Suite)註解一個類。類),然後使用@ Suite.SuiteClasses註釋來列出這些類。這是JUnit開發人員如何做的(手動列出套件中的每個類)。在許多方面,這種方法是一種改進,因爲在套件和套件行爲之前添加是微不足道和直觀的(只需將@BeforeClass和@AfterClass方法添加到使用@RunWith註釋的類中 - 比舊的TestFixture好得多)。

    但是,它有一個倒退,因爲註釋不允許您動態創建類的列表,並且解決該問題會變得有點難看。您必須繼承Suite類的子類,並在子類中動態創建類的數組並將其傳遞給Suite構造函數,但這是一個不完整的解決方案,因爲Suite的其他子類(例如Categories)不能使用它,不支持動態測試類集合。

    +1

    +1。在着手編寫動態解決方案以將測試添加到TestSuite之後,我必須在每個測試中擴展TestCase。這反過來打破了以前的工作單元測試,它使用JUnit4註釋來定義預期的異常。我在尋找一種動態填充測試套件的方式,讓我有了這個線索,特別是您的答案,我相信這是繼續使用JUnit 3的少數理想的理由之一。 – 8bitjunkie 2011-06-24 16:58:41