鍍金池/ 教程/ Java/ JUnit 4 Vs TestNG比較
TestNG參數(shù)測(cè)試(DataProvider)
TestNG配置注解實(shí)例
TestNG預(yù)期異常測(cè)試
TestNG + Selenium負(fù)載測(cè)試
TestNG參數(shù)化測(cè)試
TestNG參數(shù)測(cè)試(XML和DataProvider)
TestNG配置注釋
TestNG套件測(cè)試
TestNG依賴測(cè)試
TestNG忽略測(cè)試
TestNG忽略測(cè)試
TestNG分組測(cè)試
TestNG預(yù)期異常測(cè)試
TestNG + Selenium
TestNG參數(shù)測(cè)試實(shí)例
TestNG超時(shí)測(cè)試
TestNG Hello World入門示例
JUnit 4 Vs TestNG比較
TestNG + Spring集成示例
TestNG分組測(cè)試
TestNG教程
TestNG超時(shí)測(cè)試
JUnit 4 Vs TestNG比較
TestNG基本注解
TestNG依賴性測(cè)試
TestNG套件測(cè)試
TestNG + Spring集成測(cè)試

JUnit 4 Vs TestNG比較

JUnit 4和TestNG都是Java中非常受歡迎的單元測(cè)試框架。兩種框架在功能上看起來(lái)非常相似。 哪一個(gè)更好? 在Java項(xiàng)目中應(yīng)該使用哪個(gè)單元測(cè)試框架?

下面表中概括了JUnit 4和TestNG之間的功能比較。如下圖所示 -

1. 注釋支持

注釋/注解支持在JUnit 4和TestNG中是非常類似的。

特點(diǎn) JUnit 4 TestNG
測(cè)試注釋 @Test @Test
在套件中的所有測(cè)試運(yùn)行之前運(yùn)行 - @BeforeSuite
在套件中的所有測(cè)試運(yùn)行之后運(yùn)行 - @AfterSuite
測(cè)試之前運(yùn)行 - @BeforeTest
測(cè)試之后運(yùn)行 - @AfterTest
在調(diào)用屬于任何這些組的第一個(gè)測(cè)試方法之前運(yùn)行 - @BeforeGroups
在調(diào)用屬于任何這些組的第一個(gè)測(cè)試方法之后運(yùn)行 - @AfterGroups
在調(diào)用當(dāng)前類的第一個(gè)測(cè)試方法之前運(yùn)行 @BeforeClass @BeforeClass
在調(diào)用當(dāng)前類的第一個(gè)測(cè)試方法之后運(yùn)行 @AfterClass @AfterClass
在每個(gè)測(cè)試方法之前運(yùn)行 @Before @BeforeMethod
在每個(gè)測(cè)試方法之后運(yùn)行 @After @AfterMethod
忽略測(cè)試 @ignore @Test(enbale=false)
預(yù)期的異常 @Test(expected = ArithmeticException.class) @Test(expectedExceptions = ArithmeticException.class)
超時(shí)測(cè)試 @Test(timeout = 1000) @Test(timeout = 1000)

JUnit4和TestNG之間的主要注釋差異是:

  1. 在JUnit 4中,我們必須聲明“@BeforeClass”和“@AfterClass”方法作為靜態(tài)方法。 TestNG在方法聲明中更靈活,它沒(méi)有這個(gè)約束。

  2. 3個(gè)額外的setUp / tearDown級(jí)別:suitegroup(@Before / AfterSuite,@Before / After Test,@Before / After Group)。

JUnit 4

@BeforeClass
public static void oneTimeSetUp() {
    // one-time initialization code
    System.out.println("@BeforeClass - oneTimeSetUp");
}

TestNG

@BeforeClass
public void oneTimeSetUp() {
        // one-time initialization code
        System.out.println("@BeforeClass - oneTimeSetUp");
}

在JUnit 4中,注釋命名約定有點(diǎn)混亂,例如“Before”,“After”和“Expected”,我們并不真正了解“Before”和“After”之前的內(nèi)容,以及要測(cè)試中的“預(yù)期” 方法。TestiNG更容易理解,它使用類似“BeforeMethod”,“AfterMethod”和“ExpectedException”就很明了。

2. 異常測(cè)試

“異常測(cè)試”是指從單元測(cè)試中拋出的異常,此功能在JUnit 4和TestNG中都可實(shí)現(xiàn)。

JUnit 4

@Test(expected = ArithmeticException.class)
public void divisionWithException() {
  int i = 1/0;
}

TestNG

@Test(expectedExceptions = ArithmeticException.class)
public void divisionWithException() {
  int i = 1/0;
}

3. 忽略測(cè)試

“忽略”表示是否應(yīng)該忽略單元測(cè)試,該功能在JUnit 4和TestNG中均可實(shí)現(xiàn)。

JUnit 4

@Ignore("Not Ready to Run")
@Test
public void divisionWithException() {
  System.out.println("Method is not ready yet");
}

TestNG

@Test(enabled=false)
public void divisionWithException() {
  System.out.println("Method is not ready yet");
}

4. 時(shí)間測(cè)試

“時(shí)間測(cè)試”表示如果單元測(cè)試所花費(fèi)的時(shí)間超過(guò)指定的毫秒數(shù),則測(cè)試將會(huì)終止,并將其標(biāo)記為失敗,此功能在JUnit 4和TestNG中均可實(shí)現(xiàn)。

JUnit 4

@Test(timeout = 1000)
public void infinity() {
    while (true);
}

TestNG

@Test(timeOut = 1000)
public void infinity() {
    while (true);
}

5. 套件測(cè)試

“套件測(cè)試”是指捆綁幾個(gè)單元測(cè)試并一起運(yùn)行。 此功能在JUnit 4和TestNG中都可實(shí)現(xiàn)。 然而,兩者都使用非常不同的方法來(lái)實(shí)現(xiàn)它。

JUnit 4

@RunWith”和“@Suite”用于運(yùn)行套件測(cè)試。下面的類代碼表示在JunitTest5執(zhí)行之后,單元測(cè)試“JunitTest1”和“JunitTest2”一起運(yùn)行。 所有的聲明都是在類內(nèi)定義的。

@RunWith(Suite.class)
@Suite.SuiteClasses({
        JunitTest1.class,
        JunitTest2.class
})
public class JunitTest5 {
}

TestNG

XML文件用于運(yùn)行套件測(cè)試。以下XML文件表示單元測(cè)試“TestNGTest1”和“TestNGTest2”將一起運(yùn)行。

<suite name="My test suite">
  <test name="testing">
    <classes>
       <class name="com.fsecure.demo.testng.TestNGTest1" />
       <class name="com.fsecure.demo.testng.TestNGTest2" />
    </classes>
  </test>
</suite>

TestNG可以做捆綁類測(cè)試,也可以捆綁方法測(cè)試。 憑借TestNG獨(dú)特的“分組”概念,每種方法都可以與一個(gè)組合相結(jié)合,可以根據(jù)功能對(duì)測(cè)試進(jìn)行分類(分組)。 例如,

下面是一個(gè)有四個(gè)方法的類,三個(gè)組(method1method2method3)

@Test(groups="method1")
public void testingMethod1() {
  System.out.println("Method - testingMethod1()");
}

@Test(groups="method2")
public void testingMethod2() {
    System.out.println("Method - testingMethod2()");
}

@Test(groups="method1")
public void testingMethod1_1() {
    System.out.println("Method - testingMethod1_1()");
}

@Test(groups="method4")
public void testingMethod4() {
    System.out.println("Method - testingMethod4()");
}

使用以下XML文件,可以僅使用組“method1”執(zhí)行單元測(cè)試。

<suite name="My test suite">
  <test name="testing">
      <groups>
      <run>
        <include name="method1"/>
      </run>
    </groups>
    <classes>
       <class name="com.fsecure.demo.testng.TestNGTest5_2_0" />
    </classes>
  </test>
</suite>

通過(guò)“分組”測(cè)試概念,集成測(cè)試的可能性是無(wú)限制的。 例如,我們只能從所有單元測(cè)試類中測(cè)試“DatabaseFuntion”分組。

6. 參數(shù)化測(cè)試

“參數(shù)化測(cè)試”是指單位測(cè)試參數(shù)值的變化。 此功能在JUnit 4和TestNG中都實(shí)現(xiàn)。 然而,兩者都使用非常不同的方法來(lái)實(shí)現(xiàn)它。

JUnit 4

@RunWith”和“@Parameter”用于提供單元測(cè)試的參數(shù)值,@Parameters必須返回List [],參數(shù)將作為參數(shù)傳入類構(gòu)造函數(shù)。

@RunWith(value = Parameterized.class)
public class JunitTest6 {

     private int number;

     public JunitTest6(int number) {
        this.number = number;
     }

     @Parameters
     public static Collection<Object[]> data() {
       Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
       return Arrays.asList(data);
     }

     @Test
     public void pushTest() {
       System.out.println("Parameterized Number is : " + number);
     }
}

這里有很多限制,我們必須遵循“JUnit”的方式來(lái)聲明參數(shù),并且必須將參數(shù)傳遞給構(gòu)造函數(shù)才能初始化類成員作為測(cè)試的參數(shù)值。參數(shù)類的返回類型為“List []”,數(shù)據(jù)已被限制為String或用于測(cè)試的原始類型值。

TestNG

XML文件或“@DataProvider”用于提供不同參數(shù)進(jìn)行測(cè)試。

用于參數(shù)化測(cè)試的XML文件 -

只有“@Parameters”在需要參數(shù)測(cè)試的方法中聲明,參數(shù)化數(shù)據(jù)將在TestNG的XML配置文件中提供。 通過(guò)這樣做,我們可以使用不同數(shù)據(jù)集的單個(gè)測(cè)試用例,甚至獲得不同的結(jié)果。 另外,即使是最終用戶,QA還是QE都可以在XML文件中提供自己的數(shù)據(jù)進(jìn)行測(cè)試。

public class TestNGTest6_1_0 {

@Test
@Parameters(value="number")
public void parameterIntTest(int number) {
       System.out.println("Parameterized Number is : " + number);
    }
}

XML文件的內(nèi)容如下 -

<suite name="My test suite">
  <test name="testing">

    <parameter name="number" value="2"/>

    <classes>
       <class name="com.fsecure.demo.testng.TestNGTest6_0" />
    </classes>
  </test>
</suite>

@DataProvider用于參數(shù)化測(cè)試

將數(shù)據(jù)值拉入XML文件可能非常方便,但測(cè)試偶爾會(huì)需要復(fù)雜的類型,這些類型不能被表示為一個(gè)字符串或一個(gè)原始類型值。 TestNG使用@DataProvider注解來(lái)處理這種情況,這有助于將復(fù)雜參數(shù)類型映射到測(cè)試方法。

@DataProvider for Vector,String或Integer作為參數(shù),參考如下代碼 -

@Test(dataProvider = "Data-Provider-Function")
    public void parameterIntTest(Class clzz, String[] number) {
       System.out.println("Parameterized Number is : " + number[0]);
       System.out.println("Parameterized Number is : " + number[1]);
    }

    //This function will provide the patameter data
    @DataProvider(name = "Data-Provider-Function")
    public Object[][] parameterIntTestProvider() {
        return new Object[][]{
                   {Vector.class, new String[] {"java.util.AbstractList",
"java.util.AbstractCollection"}},
                   {String.class, new String[] {"1", "2"}},
                   {Integer.class, new String[] {"1", "2"}}
                  };
    }

@DataProvider作為對(duì)象的參數(shù)

“TestNGTest6_3_0”是一個(gè)簡(jiǎn)單的對(duì)象,只需使用get/set方法進(jìn)行演示。

@Test(dataProvider = "Data-Provider-Function")
public void parameterIntTest(TestNGTest6_3_0 clzz) {
   System.out.println("Parameterized Number is : " + clzz.getMsg());
   System.out.println("Parameterized Number is : " + clzz.getNumber());
}

//This function will provide the patameter data
@DataProvider(name = "Data-Provider-Function")
public Object[][] parameterIntTestProvider() {

    TestNGTest6_3_0 obj = new TestNGTest6_3_0();
    obj.setMsg("Hello");
    obj.setNumber(123);

    return new Object[][]{
               {obj}
    };
}

TestNG的參數(shù)化測(cè)試非常用戶友好和靈活(在XML文件或類內(nèi))。 它可以支持許多復(fù)雜的數(shù)據(jù)類型作為參數(shù)值,可能性是無(wú)限的。 如上例所示,我們甚至可以傳入我們自己的對(duì)象(TestNGTest6_3_0)進(jìn)行參數(shù)化測(cè)試

7.依賴性測(cè)試

“參數(shù)化測(cè)試”表示方法是依賴性測(cè)試,它將在所需方法之前執(zhí)行。 如果依賴方法失敗,則所有后續(xù)測(cè)試將會(huì)被跳過(guò),不會(huì)被標(biāo)記為失敗。

JUnit 4

JUnit框架著重于測(cè)試隔離; 目前它不支持此功能。

TestNG

它使用“dependOnMethods”來(lái)實(shí)現(xiàn)依賴測(cè)試如下 -

@Test
public void method1() {
   System.out.println("This is method 1");
}

@Test(dependsOnMethods={"method1"})
public void method2() {
    System.out.println("This is method 2");
}

method2()”只有在“method1()”運(yùn)行成功的情況下才會(huì)執(zhí)行,否則“method2()”將跳過(guò)測(cè)試。

結(jié)論

在考慮所有功能比較之后,建議使用TestNG作為Java項(xiàng)目的核心單元測(cè)試框架,因?yàn)門estNG在參數(shù)化測(cè)試,依賴測(cè)試和套件測(cè)試(分組概念)方面更加突出。 TestNG用于高級(jí)測(cè)試和復(fù)雜集成測(cè)試。 它的靈活性對(duì)于大型測(cè)試套件尤其有用。 此外,TestNG還涵蓋了整個(gè)核心的JUnit4功能。這樣說(shuō)來(lái),好像也沒(méi)有理由使用JUnit了。