TestNG中用Parameters或DataProvider為測試方法傳入參數


轉載於網絡
 
一、設置參數
測試方法是可以帶有參數的。每個測試方法都可以帶有任意數量的參數,並且可以通過使用TestNG的@Parameters向方法傳遞正確的參數。
設置方式有兩種方法:使用 testng .xml 或者 Data Providers
(一)使用 testng.xml 設置參數
1.如果只使用相對簡單的參數,可以在 testng.xml文件中指定:
@Parameters({ "first-name" })
@Test
public void testSingleString(String firstName) {
System.out.println("Invoked testString " + firstName);
assert "Cedric".equals(firstName);
}
在這段代碼中,我們讓 firstName 參數能夠接到XML文件中叫做 first-name參數的值。這個XML參數被定義在 testng.xml:
<suite name="My suite">
<parameter name="first-name"  value="Cedric"/>
<test name="Simple example">
 
類似的,它也可以用在 @Before/After 和 @Factory 注解上:
@Parameters({ "datasource", "jdbcDriver" })
@BeforeMethod
public void beforeTest(String ds, String driver) {
m_dataSource = ...;                    // 查詢數據源的值
m_jdbcDriver = driver;
}
這次有兩個Java參數 ds 和 driver 會分別接收到來自屬性datasource 和 jdbc-driver所指定的值。
 
2.參數也可以通過 Optional 注釋來聲明:
@Parameters("db")
@Test
public void testNonExistentParameter(@Optional("mysql") String db) { ... }
如果在你的testng.xml文件中沒有找到"db",你的測試方法就會使用 @Optional 中的值:"mysql"。
 
3.@Parameters 可以被放置到如下位置:
1.在任何已經被 @Test, @Before/After 或 @Factory 注解過的地方。
2.在測試類中至多被放到一個構造函數簽。這樣,TestNG才能在需要的時候使用 testng.xml中特定的參數來實例化這個類。這個特性可以被用作初始化某些類中的值,以便稍后會被類中其他的方法所使用。
 
注意:
XML中的參數會按照Java參數在注解中出現的順序被映射過去,並且如果數量不匹配,TestNG會報錯。
參數是有作用范圍的。在testng.xml中,你即可以在<suite> 標簽下聲明,也可以在<test>下聲明。如果兩個參數都有相同的名字,那么,定義在<test>中的有優先權。這在你需要覆蓋某些測試中特定參數的值時,會非常方便。
 
(二)使用DataProviders提供參數
testng.xml 中指定參數可能會有如下的不足:
1.如果你壓根不用 testng.xml.
2.你需要傳遞復雜的參數,或者從Java中創建參數(復雜對象,對象從屬性文件或者數據庫中讀取的etc...)
這樣的話,你就可以使用Data Provider來給需要的測試提供參數。所謂數據提供者,就是一個能返回對象數組的數組的方法,並且這個方法被@DataProvider注解標注
DataProvider的定義如下:
 
@DataProvider(name = "range-provider")
public Object[][] rangeData() {
int lower = 5;
int upper = 10;
return new Object[][] {
{ lower-1, lower, upper, false },
{ lower, lower, upper, true },
{ lower+1, lower, upper, true },
{ upper, lower, upper, true},
{ upper+1, lower, upper, false },
};
}
 
調用DataProvider的方式如下:
@Test(dataProvider = "range-provider")
public void testIsBetween(int n, int lower,int upper, boolean expected)
{
println("Received " + n + " " + lower + "-"+ upper + " expected: " + expected);
Assert.assertEquals(expected, isBetween(n, lower, upper));
}
 
被@Test標注的方法通過dataProvider屬性指明其數據提供商。這個名字必須與@DataProvider(name="...")中的名字相一致。
 
DataProvider返回的是一個Object的二維數組,二維數組中的每個一維數組都會傳遞給調用函數,作為參數使用。運行的時候,會發現,@Test標識的test method被執行的次數和object[][]包含的一維數組的個數是一致的,而@Test標識的函數的參數個數,也和object內一維數組內的元素數是一致的。
 
運行后的輸出結果如下:
Received 4 5-10 expected: false
Received 5 5-10 expected: true
Received 6 5-10 expected: true
Received 10 5-10 expected: true
Received 11 5-10 expected: false
 
===============================================
Parameter Suite
Total tests run: 5, Failures: 0, Skips: 0
===============================================
 
(三)DataProviders擴展
默認的情況下,數據提供者會查找當前的測試類或者測試類的基類。如果你希望它能夠被其他的類所使用,那么就要將其指定為static,並且通過 dataProviderClass屬性指定要使用的類
public static classStaticProvider {
@DataProvider(name = "create")
public static Object[][] createData() {
  return new Object[][] {
    new Object[] { new Integer(42) }
  }
}
}
 
public class MyTest {
@Test(dataProvider = "create", dataProviderClass =StaticProvider.class)
public void test(Integer n) {
  // ...
}
}
 
Data Provider方法可以返回如下兩種類型中的一種:
1.含有多個對象的數組(Object[][]),其中第一個下標指明了測試方法要調用的次數,第二個下標則完全與測試方法中的參數類型和個數相匹配。上面的例子已經說明。
2.另外一個是迭代器Iterator<Object[]>。二者的區別是迭代器允許你延遲創建自己的測試數據。TestNG會調用迭代器,之后測試方法會一個接一個的調用由迭代器返回的值。在你需要傳遞很多參數組給測試組的時候,這樣你無須提前創建一堆值。
 
下面是使用JDK5 的例子 (注意 JDK 1.4 的例子不適用泛型):
public Iterator createData() {
return new MyIterator(DATA);
)
@DataProvider(name = "test1")
public Iterator
 
如果你聲明的 @DataProvider 使用 java.lang.reflect.Method作為第一個參數,TestNG會把當前的測試方法當成參數傳給第一個參數。這一點在你的多個測試方法使用相同的@DataProvider的時候,並且你想要依據具體的測試方法返回不同的值時,特別有用。
例如,下面的代碼它內部的 @DataProvider 中的測試方法的名字:
@DataProvider(name = "dp")
public Object[][] createData(Method m) {
System.out.println(m.getName()); 
return new Object[][] { new Object[] { "Cedric" }};
}
 
@Test(dataProvider = "dp")
public void test1(String s) {
}
@Test(dataProvider = "dp")
public void test2(String s) {
}
所以會顯示:
test1
test2
 
Data provider可以通過屬性 parallel實現並行運行:
@DataProvider(parallel = true)
// ...
使用XML文件運行的data provider享有相同的線程池,默認的大小是10.你可以通過修改該在<suite> 標簽中的值來更改:
<suite name="Suite1" data-provider-thread-count="20" >
...
如果你需要讓指定的幾個data provider運行在不同的線程中,那么就必須通過不同的xml文件來運行。
 
、依賴方法
有些時候,需要按照特定順序調用測試方法。
1.確保在進行更多的方法測試之前,有一定數量的測試方法已經成功完成。
2.在初始化測試的時候,同時希望這個初始化方法也是一個測試方法( @Before/After不會出現在最后生成的報告中)。
 
為此,你可以使用 @Test 中的 dependsOnMethods 或 dependsOnGroups 屬性。
這兩種依賴:
1.Hard dependencies(硬依賴)。所有的被依賴方法必須成功運行。只要有一個出問題,測試就不會被調用,並且在報告中被標記為SKIP。
2.Soft dependencies(軟依賴)。 即便是有些依賴方法失敗了,也一樣運行。如果你只是需要保證你的測試方法按照順序執行,而不關心他們的依賴方法是否成功。那么這種機制就非常有用。可以通過添加"alwaysRun=true" 到 @Test 來實現軟依賴。
 
硬依賴的例子:
@Test
public void serverStartedOk() {}
@Test(dependsOnMethods = { "serverStartedOk" })
public void method1() {}
 
此例中,method1() 依賴於方法 serverStartedOk(),從而保證 serverStartedOk()總是先運行。
也可以讓若干方法依賴於組:
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
 
@Test(dependsOnGroups = { "init.* })
public void method1() {}
本例中,method1()依賴於匹配正則表達式"init.*"的組,由此保證了serverStartedOk()和 initEnvironment() 總是先於 method1()被調用。
 
注意:正如前面所說的那樣,在相同組中的調用可是在誇測試中不保證順序的。
 
如果你使用硬依賴,並且被依賴方法失敗(alwaysRun=false,即默認是硬依賴),依賴方法則不是被標記為FAIL而是SKIP。被跳過的方法會被在最后的報告中標記出來(HTML既不用紅色也不是綠色所表示),主要是被跳過的方法不是必然失敗,所以被標出來做以區別。
 
無論dependsOnGroups 還是 dependsOnMethods 都可以接受正則表達式作為參數。對於 dependsOnMethods,如果被依賴的方法有多個重載,那么所有的重載方法都會被調用。如果你只希望使用這些重載中的一個,那么就應該使用 dependsOnGroups
 
三、類級注解
通常 @Test也可以用來標注類,而不僅僅是方法:
@Test
public class Test1 {
public void test1() {
}
 
public void test2() {
}
}
處於類級的 @Test會使得類中所有的public方法成為測試方法,而不管他們是否已經被標注。當然,你仍然可以用 @Test 注解重復標注測試方法,特別是要為其添加一些特別的屬性時。
 
例如:
@Test
public class Test1 {
public void test1() {
}
 
@Test(groups = "g1")
public void test2() {
}
}
上例中 test1() 和 test2()都被處理,不過在此之上 test2() 現在還屬於組 "g1"。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM