本系列所有代碼?https://github.com/zhangting85/simpleWebtest
?
本文將介紹一個Java+TestNG+Maven+Selenium的web自動化測試腳本環境下testNG的Dataprovider的使用和數據驅動的自動化測試的實現,并提供全部代碼。
?
?
首先,DataProvider是什么?
這是testNG提供的一個做數據驅動的自動化測試時用到的標簽。詳見testNG官網文檔。
?
很多人會在使用testNG的時候把測試數據文件獨立出來,有的人會自己去寫讀文件的方法,在測試方法里去調用。這樣寫不一定不好,但有時我們如果了解testNG提供的方法,就多了一種選擇。而且通常DataProvider是比較好的一種選擇。
?
DataProvider有兩種寫法:
?
一種是返回一個Iterator的泛型對象,代碼如下:

1 package simplewebtest.test.testcases.sample.jd; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.Iterator; 6 import java.util.List; 7 8 import org.testng.annotations.DataProvider; 9 import org.testng.annotations.Test; 10 11 import simplewebtest.core.TestCase; 12 import simplewebtest.core.page.sample.jd.JDHomepage; 13 14 public class TestJDDataDriven extends TestCase { 15 16 17 18 19 /** 20 * JD首頁上搜索一個商品 主要介紹定位某個商品名稱的N種寫法 21 * 這里用了DataProvider 22 * (不會用DataProvier不要說自己懂testNG) 23 */ 24 @Test(dataProvider="product_to_search" ) 25 public void searchProduct(String keyword) throws InterruptedException { 26 27 log.info("keyword="+ keyword); 28 // 方法鏈。方法鏈并不會導致調試困難,因為我是先寫線性腳本后重構成這種腳本this is a method chain 29 String actual_procut_name= new JDHomepage().init().searchHeader.search(keyword).getProductNameByIndexMethodTwo(1 ); 30 log.info("actual_procut_name="+ actual_procut_name); 31 assert (actual_procut_name.contains(keyword)); 32 log.info("--------------------------------" ); 33 } 34 35 /** 36 * 一個返回iterator的的DataProvider 37 */ 38 @DataProvider(name="product_to_search" ) 39 public Iterator<Object[]> createData1() { 40 // 一個Array 41 String[] astringarray={"巧克力","餅","糕","蛋" }; 42 // 轉成一個String的List 43 List<String> lines= Arrays.asList(astringarray); 44 45 // 一個Object的空的List 46 List<Object[]> data = new ArrayList<Object[]> (); 47 48 // 往空List里放東西,然后返回 49 for (String line :lines ) 50 { 51 data.add( new Object[]{line}); 52 } 53 return data.iterator(); 54 55 } 56 57 }
?
另一種是返回一個Object的二維數組,代碼如下:

1 package simplewebtest.test.testcases.sample.jd; 2 3 import org.testng.annotations.DataProvider; 4 import org.testng.annotations.Test; 5 6 import simplewebtest.core.TestCase; 7 import simplewebtest.core.page.sample.jd.JDHomepage; 8 9 public class TestJDDataDriven2 extends TestCase { 10 11 12 13 14 /** 15 * JD首頁上搜索一個商品 主要介紹定位某個商品名稱的N種寫法 16 * 這里用了DataProvider 17 * (不會用DataProvier不要說自己懂testNG) 18 */ 19 @Test(dataProvider="product_to_search" ) 20 public void searchProduct(String keyword) throws InterruptedException { 21 22 log.info("keyword="+ keyword); 23 String actual_procut_name= new JDHomepage().init().searchHeader.search(keyword).getProductNameByIndexMethodTwo(1 ); 24 log.info("actual_procut_name="+ actual_procut_name); 25 assert (actual_procut_name.contains(keyword)); 26 log.info("--------------------------------" ); 27 } 28 29 /** 30 * 一個返回Object2維數組的DataProvider 31 */ 32 @DataProvider(name="product_to_search" ) 33 public Object[][] createData1() { 34 return new Object[][] { 35 { "巧克力" }, 36 { "餅" }, 37 { "核桃" }, 38 }; 39 } 40 41 }
?
這兩種寫法都可以,隨個人喜好選擇吧。第二種方法更古老一點,在沒有泛型的年代就只能用它了。
?
另外,DataProvider還支持并行執行。
比如,
@DataProvider(name="product_to_search",parallel =
true
)
parallel屬性為true時,testNG會并行執行這個DataProvider提供的測試數據。
如此,我們的測試執行速度也會大幅提升(如果你的電腦有多個CPU,速度提升更明顯)。下期介紹testNG中的并行測試執行時會給出例子。
?
有人問,我要把測試數據放到獨立文件里去的話,怎么做?
這個問題其實很簡單,我們仍舊使用DataProvider,在DataProvider里調用負責文件讀取的方法,然后把文件內容存入我們DataProvider的返回值中。例子就不給了,請自己動手寫吧。
但是呢,測試數據和測試用例分開放雖然有他的好處,新的問題卻會產生:程序的讀者(需要閱讀或維護你代碼的人)怎么知道哪個用例對應哪個數據?我親眼見過有的人把上百個測試用例的數據放在一個txt文件里。其結構之混亂,對程序讀者來說,無疑是一場災難。請不要這么做!請在寫代碼時,考慮讀者的感受,讀者每次讀到一個蹩腳的設計時是多么地難受啊。
?
有人問,我要把DataProvider獨立到一個專門的類里去,行不行?
你可以自己試試哦,我記得是可以的。同樣,請在做這種設計前考慮一下讀者的感受,我不希望在一個巨大的包含幾百個方法的類里尋找我用到的測試方法的DataProvider,請不要這么設計。
?
有人問,我一個DataProvider可不可以為多個測試方法提供數據?
完全可以哦,DataProvider上是可以跟一個傳入參數Method的,用來表示調用這個DataProvider的方法名稱。你可以在后續的代碼里判斷這個Method的值,根據不同的方法名為方法提供不同的數據。官網有例子哦,請看官網啊親。或者自己試試寫吧。這個系列里關于testNG的東西我就簡單帶過了,主要講selenium嘛。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
