<!DOCTYPE suite SYSTEM "
http://beust.com/testng/testng-1.0.dtd" >
<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可以在這塊做的更好,使用了組的概念,每個(gè)方法都可以被分配到一個(gè)組里面,可以根據(jù)功能特性來(lái)分組。例如:
這是一個(gè)有4個(gè)方法,3個(gè)組(method1, method2 和 method4)的類(lèi)
@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文件定義了一個(gè)只是執(zhí)行methed1的組的單元測(cè)試
<!DOCTYPE suite SYSTEM "
http://beust.com/testng/testng-1.0.dtd" >
<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>
使用分組的概念,集成測(cè)試會(huì)更加強(qiáng)大。例如,我們可以只是執(zhí)行所有測(cè)試中的組名為DatabaseFuntion的測(cè)試。
參數(shù)化測(cè)試
參數(shù)化測(cè)試意思是給單元測(cè)試傳多個(gè)參數(shù)值。這個(gè)特性在JUnit 4 和TestNG。然后兩個(gè)框架實(shí)現(xiàn)的方式卻完全不同。
JUnit 4
@RunWith 和 @Parameter 注解用于為單元測(cè)試提供參數(shù)值,@Parameters必須返回 List,參數(shù)將會(huì)被作為參數(shù)傳給類(lèi)的構(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 的方式去聲明參數(shù),參數(shù)必須通過(guò)構(gòu)造函數(shù)的參數(shù)去初始化類(lèi)的成員來(lái)用于測(cè)試。返回的參數(shù)類(lèi)型必須是List [],數(shù)據(jù)已經(jīng)被限定為String或者是一個(gè)原始值。
TestNG
使用XML文件或者@DataProvider注解來(lái)給測(cè)試提供參數(shù)。
XML文件配置參數(shù)化測(cè)試
只是在方法上聲明@Parameters注解,參數(shù)的數(shù)據(jù)將由 TestNG 的 XML 配置文件提供。這樣做之后,我們可以使用不同的數(shù)據(jù)集甚至是不同的結(jié)果集來(lái)重用一個(gè)測(cè)試用例。另外,甚至是終用戶(hù),QA 或者 QE 可以提供使用 XML 文件來(lái)提供他們自己的數(shù)據(jù)來(lái)做測(cè)試。
Unit Test
public class TestNGTest6_1_0 {
@Test
@Parameters(value="number")
public void parameterIntTest(int number) {
System.out.println("Parameterized Number is : " + number);
}
}
XML 文件
<!DOCTYPE suite SYSTEM "
http://beust.com/testng/testng-1.0.dtd" >
<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è)試
使用XML文件初始化數(shù)據(jù)可以很方便,但是測(cè)試偶爾需要復(fù)雜的類(lèi)型,一個(gè)String或原始值并不能完全滿(mǎn)足。 TestNG 的@ DataProvider的注解,可以更好的把復(fù)雜的參數(shù)類(lèi)型映射到一個(gè)測(cè)試方法來(lái)處理這種情況。
@DataProvider 可以使用 Vector, String 或者 Integer 類(lèi)型的值作為參數(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ù)
P.S “TestNGTest6_3_0” 是一個(gè)簡(jiǎn)單的對(duì)象,使用了get和set方法。
@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è)試使用起來(lái)非常的友好和靈活 (不管是XML配置還是在類(lèi)里面注解的方式). 它可以使用許多復(fù)雜的數(shù)據(jù)類(lèi)型作為參數(shù)的值,并且沒(méi)有什么限制。如上面的例子所示, we even can pass in our own object (TestNGTest6_3_0) for parameterized test
依賴(lài)測(cè)試
參數(shù)化測(cè)試意味著測(cè)試的方法是有依賴(lài)的,也是要執(zhí)行的的方法在執(zhí)行之前需要執(zhí)行的部分。如果依賴(lài)的方法出現(xiàn)錯(cuò)誤,所有的子測(cè)試都會(huì)被忽略,不會(huì)被標(biāo)記為失敗。
JUnit 4
JUnit 框架主要聚焦于測(cè)試的隔離,暫時(shí)還不支持這個(gè)特性。
TestNG
它使用dependOnMethods來(lái)實(shí)現(xiàn)了依賴(lài)測(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");
}
如果method1()成功執(zhí)行,那么method2()也將被執(zhí)行,否則method2()將會(huì)被忽略。
討論總結(jié)
當(dāng)我們做完所有特性的對(duì)比以后,我建議使用 TestNG 作為 Java 項(xiàng)目的主要單元測(cè)試框架,因?yàn)?TestNG 在參數(shù)化測(cè)試、依賴(lài)測(cè)試以及套件測(cè)試(組)方面功能更加強(qiáng)大。TestNG 意味著高級(jí)的測(cè)試和復(fù)雜的集成測(cè)試。它更加的靈活,特別是對(duì)大的套件測(cè)試。另外,TestNG 也涵蓋了 JUnit4 的全部功能。那沒(méi)有任何理由使用 Junit了。