乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      全面認(rèn)識(shí)JUnit 4的新特征

       nbtymm 2006-10-25
      提要 本文將向你介紹如何實(shí)現(xiàn)從JUnit 3.8向JUnit 4的遷移。同時(shí),還討論JUnit 4中的一些新特征,特別包括對(duì)注解的使用;最后,簡(jiǎn)要介紹這個(gè)新版本的IDE集成現(xiàn)狀。

        一、 引言

        在本文開始,我將假定,你已經(jīng)了解由Kent Beck和Erich Gamma發(fā)明的這個(gè)Java單元測(cè)試框架并因此而略過(guò)必要的簡(jiǎn)介。所以,我將集中分析從JUnit 3.8到最新版本-JUnit 4的遷移過(guò)程以及其在IDE和Ant中的集成。

        JUnit 4是一種與其之前的版本完全不同的API,它根據(jù)Java 5.0中的新特征(注解,靜態(tài)導(dǎo)入等)構(gòu)建而成。如你所見,JUnit 4更簡(jiǎn)單、更豐富和更易于使用,而且它引入了更為靈活的初始化和清理工作,還有限時(shí)的和參數(shù)化測(cè)試用例。

        代碼實(shí)例最能說(shuō)明問題。因此,在本文中,我將使用一個(gè)例子來(lái)展示不同的測(cè)試用例:一個(gè)計(jì)算器。該示例計(jì)算器很簡(jiǎn)單,效率并不高,甚至還有一些錯(cuò)誤;它僅僅操作整數(shù),并且把結(jié)果存儲(chǔ)在一個(gè)靜態(tài)變量中。Substract方法并不返回一個(gè)有效的結(jié)果,而且也沒有實(shí)現(xiàn)乘法運(yùn)算,而且看上去在squareRoot方法中還存在一個(gè)錯(cuò)誤:無(wú)限循環(huán)。這些錯(cuò)誤將幫助說(shuō)明使用JUnit 4進(jìn)行測(cè)試的有效性。你可以打開和關(guān)閉這個(gè)計(jì)算器,而且你可以清除這些結(jié)果。下面是其實(shí)現(xiàn)代碼:

      package calc;
      public class Calculator {
       private static int result; //存儲(chǔ)結(jié)果的靜態(tài)變量
       public void add(int n) {
        result = result + n;
       }
       public void substract(int n) {
        result = result - 1; //錯(cuò)誤:應(yīng)該是"result = result - n"
       }
       public void multiply(int n) {} //還沒實(shí)現(xiàn)
       public void divide(int n) {
        result = result / n;
       }
       public void square(int n) {
        result = n * n;
       }
       public void squareRoot(int n) {
        for (; ;) ; //錯(cuò)誤:無(wú)限循環(huán)
       }
       public void clear() { //清除結(jié)果
        result = 0;
       }
       public void switchOn() { //打開屏幕,顯示"hello",并報(bào)警
        result = 0; //實(shí)現(xiàn)其它的計(jì)算器功能
       }
       public void switchOff() { } //顯示"bye bye",報(bào)警,并關(guān)閉屏幕
       public int getResult() {
        return result;
       }
      }

        二、 遷移一個(gè)測(cè)試類

        現(xiàn)在,我將把一個(gè)已經(jīng)使用JUnit 3.8編寫成的簡(jiǎn)單的測(cè)試類遷移到JUnit 4。這個(gè)類有一些缺陷:它沒有測(cè)試所有的業(yè)務(wù)方法,而且看上去在testDivide方法中還存在一個(gè)錯(cuò)誤(8/2不等于5)。因?yàn)檫€沒有實(shí)現(xiàn)乘法運(yùn)算功能,所以對(duì)其測(cè)試將被忽略。

        下面,我們把兩個(gè)版本的框架之間的差別以粗體顯示出現(xiàn)于表格1中。

        表格1.分別以JUnit 3.8和JUnit 4實(shí)現(xiàn)的CaculatorTest。

        JUnit 3.8

      package junit3;
      import calc.Calculator;
      import junit.framework.TestCase;
      public class CalculatorTest extends TestCase {
       private static Calculator calculator = new Calculator();
       @Override protected void setUp() { calculator.clear(); }
       public void testAdd() {
        calculator.add(1);
        calculator.add(1);
        assertEquals(calculator.getResult(), 2);
       }
       public void testSubtract() {
        calculator.add(10);
        calculator.subtract(2);
        assertEquals(calculator.getResult(), 8);
       }
       public void testDivide() {
        calculator.add(8);
        calculator.divide(2);
        assert calculator.getResult() == 5;
       }
       public void testDivideByZero() {
        try {
         calculator.divide(0);
         fail();
        }
        catch (ArithmeticException e) { }
       }
       public void notReadyYetTestMultiply() {
        calculator.add(10);
        calculator.multiply(10);
        assertEquals(calculator.getResult(), 100);
       }
      }

        JUnit 4

      package JUnit 4;
      import calc.Calculator;
      import org.junit.Before;
      import org.junit.Ignore;
      import org.junit.Test;
      import static org.junit.Assert.*;
      public class CalculatorTest {
       private static Calculator calculator = new Calculator();
       @Before public void clearCalculator() {
        calculator.clear();
       }
       @Test public void add() {
        calculator.add(1);
        calculator.add(1);
        assertEquals(calculator.getResult(), 2);
       }
       @Test public void subtract() {
        calculator.add(10);
        calculator.subtract(2);
        assertEquals(calculator.getResult(), 8);
       }
       @Test public void divide() {
        calculator.add(8);
        calculator.divide(2);
        assert calculator.getResult() == 5;
       }
       @Test(expected = ArithmeticException.class)
       public void divideByZero() {
        calculator.divide(0);
       }
       @Ignore("not ready yet")
       @Test
       public void multiply() {
        calculator.add(10);
        calculator.multiply(10);
        assertEquals(calculator.getResult(), 100);
       }
      }
       
       
      三、 包

        首先,你可以看到,JUnit 4使用org.junit.*包而JUnit 3.8使用的是junit.framework.*。當(dāng)然,為了向后兼容性起見,JUnit 4jar文件發(fā)行中加入了這兩種包。

        四、 繼承

        在中,測(cè)試類不必再擴(kuò)展junit.framework.TestCase;事實(shí)上,它們不必須擴(kuò)展任何內(nèi)容。但是,JUnit 4中使用的是注解。為了以一個(gè)測(cè)試用例方式執(zhí)行,一個(gè)JUnit 4類中至少需要一個(gè)@Test注解。例如,如果你僅使用@Before和@After注解而沒有至少提供一個(gè)@Test方法來(lái)編寫一個(gè)類,那么,當(dāng)你試圖執(zhí)行它時(shí)將得到一個(gè)錯(cuò)誤:

      java.lang.Exception: No runnable methods.

        五、 斷言(Assert)方法

        因?yàn)樵贘Unit 4中一個(gè)測(cè)試類并不繼承自TestCase(在JUnit 3.8中,這個(gè)類中定義了assertEquals()方法),所以你必須使用前綴語(yǔ)法(舉例來(lái)說(shuō),Assert.assertEquals())或者(由于JDK5.0)靜態(tài)地導(dǎo)入Assert類。這樣以來(lái),你就可以完全象以前一樣使用assertEquals方法(舉例來(lái)說(shuō),assertEquals())。

        另外,在JUnit 4中,還引入了兩個(gè)新的斷言方法,它們專門用于數(shù)組對(duì)象的比較。如果兩個(gè)數(shù)組包含的元素都相等,那么這兩個(gè)數(shù)組就是相等的。

      public static void assertEquals(String message, Object[] expecteds, Object[] actuals);
      public static void assertEquals(Object[] expecteds, Object[] actuals);

        由于JDK 5.0的自動(dòng)裝箱機(jī)制的出現(xiàn),原先的12個(gè)assertEquals方法全部去掉了。例如,原先JUnit 3.8中的assertEquals(long,long)方法在JUnit 4中要使用assertEquals(Object,Object)。對(duì)于assertEquals(byte,byte)、assertEquals(int,int)等也是這樣。這種改進(jìn)將有助于避免反模式。

        在JUnit 4中,新集成了一個(gè)assert關(guān)鍵字(見我們的例子中的divide()方法)。你可以象使用assertEquals方法一樣來(lái)使用它,因?yàn)樗鼈兌紥伋鱿嗤漠惓?java.lang.AssertionError)。JUnit 3.8的assertEquals將拋出一個(gè)junit.framework.AssertionFailedError。注意,當(dāng)使用assert時(shí),你必須指定Java的"-ea"參數(shù);否則,斷言將被忽略。

        六、 預(yù)設(shè)環(huán)境(Fixture)

        Fixture是在測(cè)試期間初始化和釋放任何普通對(duì)象的方法。在JUnit 3.8中,你要使用setUp()來(lái)實(shí)現(xiàn)運(yùn)行每一個(gè)測(cè)試前的初始化工作,然后使用tearDown()來(lái)進(jìn)行每個(gè)測(cè)試后的清理。這兩個(gè)方法在TestCase類中都得到重載,因此都被唯一定義。注意,我在這個(gè)Setup方法使用的是Java5.0內(nèi)置的@Override注解-這個(gè)注解指示該方法聲明要重載在超類中的方法聲明。在JUnit 4中,則代之使用的是@Before和@After注解;而且,可以以任何命名(在我們的例子中是clearCalculator())來(lái)調(diào)用這些方法。在本文后面,我將更多地解釋這些注解。

        七、 測(cè)試

        JUnit 3.8通過(guò)分析它的簽名來(lái)識(shí)別一個(gè)測(cè)試方法:方法名必須以"test"為前綴,它必須返回void,而且它必須沒有任何參數(shù)(舉例來(lái)說(shuō),publicvoidtestDivide())。一個(gè)不遵循這個(gè)命名約定的測(cè)試方法將被框架簡(jiǎn)單地忽略,而且不拋出任何異常(指示發(fā)生了一個(gè)錯(cuò)誤)。
      JUnit 4不使用與JUnit 3.8相同的約定。一個(gè)測(cè)試方法不必以‘test‘為前綴,但是要使用@Test注解。但是,正如在前一個(gè)框架中一樣,一個(gè)測(cè)試方法也必須返回void并且是無(wú)參數(shù)的。在JUnit 4中,可以在運(yùn)行時(shí)刻控制這個(gè)要求,并且不符合要求的話會(huì)拋出一個(gè)異常:

      java.lang.Exception: Method xxx should have no parameters
      java.lang.Exception: Method xxx should be void

        @Test注解支持可選參數(shù)。它聲明一個(gè)測(cè)試方法應(yīng)該拋出一個(gè)異常。如果它不拋出或者如果它拋出一個(gè)與事先聲明的不同的異常,那么該測(cè)試失敗。在我們的例子中,一個(gè)整數(shù)被零除應(yīng)該引發(fā)一個(gè)ArithmeticException異常。

        八、 忽略一個(gè)測(cè)試

        記住,不能執(zhí)行多個(gè)方法。然而,如果你不想讓測(cè)試失敗的話,你可以僅僅忽略它。那么,在JUnit 3.8中,我們是如何實(shí)現(xiàn)臨時(shí)禁止一個(gè)測(cè)試的呢?方法是:通過(guò)注釋掉它或者改變命名約定,這樣測(cè)試運(yùn)行機(jī)就無(wú)法找到它。在我的例子中,我使用了方法名notReadyYetTestMultiply()。它沒有以"test"開頭,所以它不會(huì)被識(shí)別出來(lái)?,F(xiàn)在的問題是,在成百上千的測(cè)試中間,你可能記不住重命名這個(gè)方法。

        在JUnit 4中,為了忽略一個(gè)測(cè)試,你可以注釋掉一個(gè)方法或者刪除@Test注解(你不能再改變命名約定,否則將拋出一個(gè)異常)。然而,該問題將保留:該運(yùn)行機(jī)將不報(bào)告這樣一個(gè)測(cè)試。現(xiàn)在,你可以把@Ignore注解添加到@Test的前面或者后面。測(cè)試運(yùn)行機(jī)將報(bào)告被忽略的測(cè)試的個(gè)數(shù),以及運(yùn)行的測(cè)試的數(shù)目和運(yùn)行失敗的測(cè)試數(shù)目。注意,@Ignore使用一個(gè)可選參數(shù)(一個(gè)String),如果你想記錄為什么一個(gè)測(cè)試被忽略的話。

        九、 運(yùn)行測(cè)試

        在JUnit 3.8中,你可以選擇使用若干運(yùn)行機(jī):文本型,AWT或者Swing。JUnit 4僅僅使用文本測(cè)試運(yùn)行機(jī)。注意,JUnit 4不會(huì)顯示任何綠色條來(lái)通知你測(cè)試成功了。如果你想看到任何類型的綠色的話,那么你可能需要使用JUnit擴(kuò)展或一種集成了JUnit的IDE(例如IDEA或者Eclipse)。

        首先,我想使用老式但好用的junit.textui.TestRunner來(lái)運(yùn)行該JUnit 3.8測(cè)試類(考慮到使用assert關(guān)鍵字,我使用了-ea參數(shù))。
      java -ea junit.textui.TestRunner junit3.CalculatorTest

      ..F.E.
      There was 1 error:
      1) testDivide(junit3.CalculatorTest)java.lang.AssertionError
      at junit3.CalculatorTest.testDivide(CalculatorTest.java:33)
      There was 1 failure:
      1) testSubtract(junit3.CalculatorTest)junit.framework.AssertionFailedError: expected:<9> but was:<8>
      at junit3.CalculatorTest.testSubtract(CalculatorTest.java:27)
      FAILURES!!!
      Tests run: 4, Failures: 1, Errors: 1

        TestDivide產(chǎn)生一個(gè)錯(cuò)誤,因?yàn)閿嘌源_定了8/2不等于5。TestSubstract產(chǎn)生一個(gè)失敗,因?yàn)?0-2應(yīng)該等于8,但是在這個(gè)實(shí)現(xiàn)中存在一個(gè)錯(cuò)誤:它返回9。

        現(xiàn)在,我使用新的org.junit.runner.JUnitCore運(yùn)行機(jī)來(lái)運(yùn)行這兩個(gè)類。注意,它能執(zhí)行JUnit 4和JUnit 3.8測(cè)試,甚至是這二者的結(jié)合。

      java -ea org.junit.runner.JUnitCore junit3.CalculatorTest

      JUnit version 4.1

      ..E.E.
      There were 2 failures:
      1) testSubtract(junit3.CalculatorTest)
      junit.framework.AssertionFailedError: expected:<9> but was:<8>
      at junit.framework.Assert.fail(Assert.java:47)
      2) testDivide(junit3.CalculatorTest)
      java.lang.AssertionError
      at junit3.CalculatorTest.testDivide(CalculatorTest.java:33)
      FAILURES!!!
      Tests run: 4, Failures: 2
      ***

      java -ea org.junit.runner.JUnitCore JUnit 4.CalculatorTest

      JUnit version 4.1
      ...E.EI
      There were 2 failures:
      1) subtract(JUnit 4.CalculatorTest)
      java.lang.AssertionError: expected:<9> but was:<8>
      at org.junit.Assert.fail(Assert.java:69)
      2) divide(JUnit 4.CalculatorTest)
      java.lang.AssertionError
      at JUnit 4.CalculatorTest.divide(CalculatorTest.java:40)
      FAILURES!!!
      Tests run: 4, Failures: 2

        第一個(gè)非常明顯的區(qū)別是,JUnit版本號(hào)被顯示于控制臺(tái)中(4.1)。第二個(gè)區(qū)別是,JUnit 3.8區(qū)分失敗和錯(cuò)誤;JUnit 4則僅使用失敗進(jìn)行簡(jiǎn)化。一個(gè)新奇的地方是,字母"I",它顯示一個(gè)測(cè)試被忽略。
       
      十、 高級(jí)測(cè)試

        現(xiàn)在,我將展示JUnit 4的一些高級(jí)特征。列表1(見下載源碼)是一個(gè)新的測(cè)試類-AdvancedTest,它派生自AbstractParent。

        (一) 高級(jí)預(yù)設(shè)環(huán)境

        兩個(gè)類都使用新的注解@BeforeClass和@AfterClass,還有@Before和@After。表格2展示了在這些注解之間的主要區(qū)別。

        表格2.@BeforeClass/@AfterClass比較于@Before/@After。

      @BeforeClass和@AfterClass @Before和@After
      在每個(gè)類中只有一個(gè)方法能被注解。 多個(gè)方法能被注解,但其執(zhí)行的順序未特別指定,且不運(yùn)行重載方法。
      方法名是不相關(guān)的 方法名是不相關(guān)的
      每個(gè)類運(yùn)行一次 在每個(gè)測(cè)試方法運(yùn)行前或運(yùn)行后運(yùn)行
      在當(dāng)前類的@BeforeClass方法運(yùn)行前先運(yùn)行超類的@BeforeClass方法。在超類中聲明的@AfterClass方法將在所有當(dāng)前類的該方法運(yùn)行后才運(yùn)行。 超類中的@Before在所有子類的該方法運(yùn)行前運(yùn)行。在超類中的@After在在所有子類的該方法運(yùn)行后才運(yùn)行。
      必須是公共和非靜態(tài)的。 必須是公共和非靜態(tài)的。
      即使一個(gè)@BeforeClass方法拋出一個(gè)異常,所有的@AfterClass方法也保證被運(yùn)行。 即使一個(gè)@Before或者@Test方法拋出一個(gè)異常,所有的@After方法也保證被運(yùn)行。

        如果你僅有一次需要分配和釋放昂貴的資源,那么@BeforeClass和@AfterClass可能很有用。在我們的例子中,AbstractParent使用這些在startTestSystem()和stopTestSystem()方法上的注解啟動(dòng)和停止整個(gè)測(cè)試系統(tǒng)。并且它使用@Before和@After初始化和清除系統(tǒng)。子類AdvancedTest也混合使用這些注解。

        在你的測(cè)試代碼中使用System.out.println不是一種良好的實(shí)踐習(xí)慣;但是,在這個(gè)用例中,它有助于理解這些注解被調(diào)用的順序。當(dāng)我運(yùn)行AdvancedTest時(shí),我得到如下結(jié)果:

      Start test system //父類的@BeforeClass
      Switch on calculator //子類的@BeforeClass

      Initialize test system //第一個(gè)測(cè)試
      Clear calculator

      Initialize test system //第二個(gè)測(cè)試
      Clear calculator
      Clean test system

      Initialize test system //第三個(gè)測(cè)試
      Clear calculator
      Clean test system

      Initialize test system //第四個(gè)測(cè)試
      Clear calculator
      Clean test system

      Switch off calculator //子類的@AfterClass
      Stop test system //父類的@AfterClass

        如你所見,@BeforeClass和@AfterClass僅被調(diào)用一次,而@Before和@Afterare在每次測(cè)試中都要調(diào)用。

        (二) 限時(shí)測(cè)試

        在前面的例子中,我為squareRoot()方法編寫了一個(gè)測(cè)試用例。記住,在這個(gè)方法中存在一個(gè)錯(cuò)誤-能夠?qū)е滤鼰o(wú)限循環(huán)。如果沒有結(jié)果的話,我想讓這個(gè)測(cè)試在1秒鐘后退出。這一功能正是timeout參數(shù)所要實(shí)現(xiàn)的。@Test注解的第二個(gè)可選參數(shù)(第一個(gè)參數(shù)是必需的)可以使一個(gè)測(cè)試失敗,如果該測(cè)試花費(fèi)比一個(gè)預(yù)先確定的時(shí)限(毫秒)還長(zhǎng)的時(shí)間的話。當(dāng)我運(yùn)行該測(cè)試時(shí),我得到如下的運(yùn)行結(jié)果:

      There was 1 failure:

      1) squareRoot(JUnit 4.AdvancedTest)
      java.lang.Exception: test timed out after 1000 milliseconds
      at org.junit.internal.runners.TestMethodRunner.runWithTimeout(TestMethodRunner.java:68)
      at org.junit.internal.runners.TestMethodRunner.運(yùn)行(TestMethodRunner.java:43)

      FAILURES!!!
      Tests run: 4, Failures: 1

        (三) 參數(shù)化測(cè)試

        在列表1中,我測(cè)試了squareRoot(它是square方法而不是squareRoot方法)-通過(guò)創(chuàng)建若干測(cè)試方法(square2,square4,square5),這些方法都完成相同的事情(通過(guò)被一些變量參數(shù)化實(shí)現(xiàn))。其實(shí),現(xiàn)在這里的復(fù)制/粘貼技術(shù)可以通過(guò)使用一個(gè)參數(shù)化測(cè)試用例加以優(yōu)化(列表2)。

        在列表2(見本文相應(yīng)下載源碼)中的測(cè)試用例使用了兩個(gè)新的注解。當(dāng)一個(gè)類被使用@RunWith注釋時(shí),JUnit將調(diào)用被參考的類來(lái)運(yùn)行該測(cè)試而不是使用缺省的運(yùn)行機(jī)。為了使用一個(gè)參數(shù)化測(cè)試用例,你需要使用運(yùn)行機(jī)org.junit.runners.Parameterized。為了確定使用哪個(gè)參數(shù),該測(cè)試用例需要一個(gè)公共靜態(tài)方法(在此是data(),但是名字似乎無(wú)關(guān)),該方法返回一個(gè)Collection,并且被使用@參數(shù)加以注解。你還需要一個(gè)使用這些參數(shù)的公共構(gòu)造函數(shù)。

        當(dāng)運(yùn)行這個(gè)類,該輸出是:

      java org.junit.runner.JUnitCore JUnit 4.SquareTest
      JUnit version 4.1

      .......E

      There was 1 failure:
      1) square[6](JUnit 4.SquareTest)
      java.lang.AssertionError: expected:<48> but was:<49>
      at org.junit.Assert.fail(Assert.java:69)

      FAILURES!!!
      Tests run: 7, Failures: 1

        在此,共執(zhí)行了7個(gè)測(cè)試,好象編寫了7個(gè)單獨(dú)的square方法。注意,在我們的測(cè)試中出現(xiàn)了一個(gè)失敗,因?yàn)?的平方是49,而不是48。

        (四) 測(cè)試集

        為了在JUnit 3.8的一個(gè)測(cè)試集中運(yùn)行若干測(cè)試類,你必須在你的類中添加一個(gè)suite()方法。而在JUnit 4中,你可以使用注解來(lái)代之。為了運(yùn)行CalculatorTest和SquareTest,你需要使用@RunWith和@Suite注解編寫一個(gè)空類。

      package JUnit 4;

      import org.junit.runner.RunWith;
      import org.junit.runners.Suite;

      @RunWith(Suite.class)
      @Suite.SuiteClasses({
      CalculatorTest.class,
      SquareTest.class
      })
      public class AllCalculatorTests {}

        在此,@RunWith注解告訴JUnit它使用org.junit.runner.Suite。這個(gè)運(yùn)行機(jī)允許你手工地構(gòu)建一個(gè)包含測(cè)試(可能來(lái)自許多類)的測(cè)試集。這些類的名稱都被定義在@Suite.SuiteClass中。當(dāng)你運(yùn)行這個(gè)類時(shí),它將運(yùn)行CalculatorTest和SquareTest。其輸出是:

      java -ea org.junit.runner.JUnitCore JUnit 4.AllCalculatorTests
      JUnit version 4.1
      ...E.EI.......E
      There were 3 failures:
      1) subtract(JUnit 4.CalculatorTest)
      java.lang.AssertionError: expected:<9> but was:<8>
      at org.junit.Assert.fail(Assert.java:69)
      2) divide(JUnit 4.CalculatorTest)
      java.lang.AssertionError
      at JUnit 4.CalculatorTest.divide(CalculatorTest.java:40)
      3) square[6](JUnit 4.SquareTest)
      java.lang.AssertionError: expected:<48> but was:<49>
      at org.junit.Assert.fail(Assert.java:69)
      FAILURES!!!
      Tests run: 11, Failures: 3

        (五) 測(cè)試運(yùn)行機(jī)

        在JUnit 4中,廣泛地使用測(cè)試運(yùn)行機(jī)。如果沒有指定@RunWith,那么你的類仍然會(huì)使用一個(gè)默認(rèn)運(yùn)行機(jī)(org.junit.internal.runners.TestClassRunner)執(zhí)行。注意,最初的Calculator類中并沒有顯式地聲明一個(gè)測(cè)試運(yùn)行機(jī);因此,它使用的是默認(rèn)運(yùn)行機(jī)。一個(gè)包含一個(gè)帶有@Test的方法的類都隱含地?fù)碛幸粋€(gè)@RunWith。事實(shí)上,你可以把下列代碼添加到Calculator類上,而且其輸出結(jié)果會(huì)完全一樣。

      import org.junit.internal.runners.TestClassRunner;
      import org.junit.runner.RunWith;
      @RunWith(TestClassRunner.class)
      public class CalculatorTest {
      ...
      }

        在@Parameterized和@Suite的情況下,我需要一個(gè)特定的運(yùn)行機(jī)來(lái)執(zhí)行我的測(cè)試用例。這就是為什么我顯式地注解了它們。
       
      十一、 工具集成功能

        當(dāng)我寫本文時(shí),JUnit 4在IDE方面的集成還不是很理想。事實(shí)上,如果你試圖運(yùn)行我們剛才看到的那個(gè)測(cè)試類的話,它們無(wú)法工作在任何IDE環(huán)境中,因?yàn)樗鼈儾荒鼙蛔R(shí)別為測(cè)試類。為了向前兼容性起見,JUnit 4發(fā)行中帶有一個(gè)適配器(junit.framework.JUnit 4TestAdapter),你必須把它使用于一個(gè)suite()方法中。下面是你必須添加到每個(gè)類中的代碼;這樣以來(lái),它們才能為各種IDE,Ant以及JUnit 3.8中的文本運(yùn)行機(jī)所識(shí)別:

      public static junit.framework.Test suite() {
       return new JUnit 4TestAdapter(CalculatorTest.class);
      }

        (一) Intellij IDEA

        IDEA 5并沒有集成JUnit 4。沒有辦法,我們只好等待IDEA 6中實(shí)現(xiàn)這一集成了。在這個(gè)例子中,我使用了較早的發(fā)行版本(Demetra build 5321);但是,參數(shù)化測(cè)試用例仍不能工作。圖1展示了這個(gè)CalculatorTest的執(zhí)行情況(被忽略的測(cè)試以一個(gè)不同的圖標(biāo)標(biāo)志)。


      圖1.IDEADemetra僅能運(yùn)行CalculatorTest。

      圖2.Eclipse 3.2RC7能夠運(yùn)行測(cè)試集類AllCalculatorTests。

        (二) Eclipse

        我現(xiàn)在使用的是Eclipse的3.2 RC7版本。雖然它還不是一個(gè)穩(wěn)定發(fā)行版本,但是其與JUnit 4的集成優(yōu)于IDEA。上圖2展示了在運(yùn)行AllCalculatorTests類時(shí)你能看到的結(jié)果。

        如你所見,該參數(shù)化測(cè)試用例(SquareTest)被描述為7個(gè)單獨(dú)的測(cè)試。

        (三) Ant集成

        junit任務(wù)當(dāng)前僅僅支持JUnit 3.8風(fēng)格測(cè)試;這也就是說(shuō),你還必須用一個(gè)JUnit 4 TestAdapter來(lái)包裝你的JUnit 4測(cè)試;這樣,它們才能在Ant中運(yùn)行。這個(gè)<junit>任務(wù)與其在JUnit 3.8中用法一樣:

      <!-- Test -->
      <target name="test" depends="compile">
      <junit fork="yes" haltonfailure="yes">
      <test name=" JUnit 4.AllCalculatorTests"/>
      <formatter type="plain" usefile="false"/>
      <classpath refid="classpath"/>
      </junit>
      </target>

        十二、 結(jié)論

        有很長(zhǎng)一段時(shí)間,JUnit簡(jiǎn)直成了事實(shí)上的單元測(cè)試框架標(biāo)準(zhǔn)。但是,近來(lái),這個(gè)框架似乎無(wú)大"動(dòng)靜":沒有重要的發(fā)行版本,沒有引人注目的新特征出現(xiàn)。這可能是為什么其它測(cè)試框架,例如Test-NG開始逐漸占居測(cè)試框架市場(chǎng)統(tǒng)治地位的原因。

        隨著這個(gè)新版本的發(fā)行,JUnit又出現(xiàn)了新的轉(zhuǎn)機(jī)。如今,它提供了許多新的API,而且現(xiàn)在還使用注解,所以使開發(fā)測(cè)試用例更為容易。事實(shí)上,該JUnit開發(fā)者已經(jīng)開始考慮新的未來(lái)的注解問題。例如,你可以在一個(gè)依賴于前提(舉例來(lái)說(shuō),你需要在線地執(zhí)行這個(gè)測(cè)試)的測(cè)試用例上添加一個(gè)@Prerequisite注解;或者添加一個(gè)能夠指定重復(fù)次數(shù)及時(shí)限(舉例來(lái)說(shuō),重復(fù)測(cè)試5次以確保真正出現(xiàn)了一個(gè)時(shí)限問題)的@Repeat注解;或者甚至在@Ignore注解上添加一個(gè)平臺(tái)參數(shù)(舉例來(lái)說(shuō),@Ignore(platform=macos),這將只有你在一個(gè)MacOS平臺(tái)上運(yùn)行時(shí)才忽略一個(gè)測(cè)試)。從本文中你能看到,JUnit的未來(lái)依然燦爛輝煌。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多