您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關java中TestNG數據驅動是什么的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
TestNG數據驅動
testng的功能很強大,利用@DataProvider可以做數據驅動,數據源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本。
@DataProvider注解簡介:
@DataProvider標記專門為測試方法提供參數的方法。這類方法必須返回Object[ ][ ]類型的二維數組或者Iterator<Object>[],每一行的Object[],都是測試方法的一個測試數據集,測試方法會為每個測試數據集執行一次。如果沒有指定參數的名稱,則默認為方法的名稱,方法的名稱沒有限制。
@DataProvider的小例子:
import java.lang.reflect.Method; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class test { @DataProvider(name = "user") public Object[][] createUser(Method m) { System.out.println(m.getName()); return new Object[][] { { "root", "root" }, { "test", "root" }, { "test", "test" } }; } @Test(dataProvider = "user") public void verifyUser(String username, String password) { System.out.println("Verify User : " + username + ":" + password); assert username.equals(password); } }
如上所示@DataProvider注解了createUser方法,返回的二位數組里有三行數據,每行兩列。
所以@Test(dataProvider = "user")注解的verifyUser方法有兩個參數,用來接收每一行的兩個數據,如果createUser返回的數據數組的列數和verifyUser的參數個數不同就會報錯的。
因為返回的有三行,所以verifyUser會被執行三次。結果如下:
PASSED: verifyUser("root", "root") FAILED: verifyUser("test", "root") PASSED: verifyUser("test", "test")
CSV文件數據讀取和@DataProvider
我自己做了一個以csv為例的測試架子,部分代碼可通用。
CSV文件讀取類(可通用,目錄自己可以修改,也可改變成讀取EXCEL、TXT等文件):
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; public class CSVData implements Iterator<Object[]> { private BufferedReader br = null; //行數 private int rowNum = 0; //獲取次數 private int curRowNo = 0; //列數 private int columnNum = 0; //key名 private String[] columnName; //csv中所有行數據 private List<String> csvList; //實際想要的行數據 private List<String> csvListNeed; /* * 在TestNG中由@DataProvider(dataProvider = "name")修飾的方法 * 取csv時,調用此類構造方法(此方法會得到列名并將當前行移到下以后)執行后,轉發哦 * TestNG自己的方法中去,然后由它們調用此類實現的hasNext()、next()方法 * 得到一行數據,然后返回給由@Test(dataProvider = "name")修飾的方法,如此 * 反復到數據讀完為止 * * * @param filepath CSV文件名 * @param casename 用例名 */ public CSVData(String fileName, String caseId) { try { File directory = new File("."); String ss = "resources."; File csv = new File(directory.getCanonicalFile() + "\\src\\test\\" + ss.replaceAll("\\.", Matcher.quoteReplacement("\\")) + fileName + ".csv"); br = new BufferedReader(new FileReader(csv)); csvList = new ArrayList<String>(); while (br.ready()) { csvList.add(br.readLine()); this.rowNum++; } String stringValue[] = csvList.get(0).split(","); this.columnNum = stringValue.length; columnName = new String[stringValue.length]; for (int i = 0; i < stringValue.length; i++) { columnName[i] = stringValue[i].toString(); } this.curRowNo++; csvListNeed = new ArrayList<String>(); for (int i = 1; i < rowNum; i++) { String values[] = csvList.get(i).split(","); if (caseId.equals(values[0])) { csvListNeed.add(csvList.get(i)); } } this.rowNum = 2;//就取一行 } catch (Exception e) { e.printStackTrace(); } } @Override public boolean hasNext() { if (this.rowNum == 0 || this.curRowNo >= this.rowNum) { try { br.close(); } catch (Exception e) { e.printStackTrace(); } return false; } else { return true; } } @Override public Object[] next() { /* * 將數據放入map */ Map<String, String> s = new TreeMap<String, String>(); String csvCell[] = csvListNeed.get(0).split(","); for (int i = 0; i < this.columnNum; i++) { String temp = ""; try { temp = csvCell[i].toString(); } catch (ArrayIndexOutOfBoundsException ex) { temp = ""; } s.put(this.columnName[i], temp); } Object r[] = new Object[1]; r[0] = s; this.curRowNo++; return r; } @Override public void remove() { throw new UnsupportedOperationException("remove unsupported"); } }
這個類實現了Iterator<Object[]>迭代器,TestNG調用此類實現的hasNext()、next()方法得到一行數據,在next()方法中可以看到,我把數據是放在Map<String, String>中的,再把map放在Object[]里,所以測試方法的參數就必須是一個Map<String, String>。我這里改成了只讀取一行,因為一個csv文件的一個caseId只應該有一行。
數據驅動類:
import java.lang.reflect.Method; import java.util.Iterator; import org.testng.annotations.DataProvider; public class DataProviderTest { /** * @DataProvider的返回值類型只能是Object[][]與Iterator<Object>[] * * @param method * @return */ @DataProvider public Iterator<Object[]> dataSource(Method method) { return (Iterator<Object[]>) new CSVData(method.getDeclaringClass().getSimpleName(), method.getName()); } }
Method方法是通過反射獲取的,總之哪個方法調用我Method就是那個方法。
method.getDeclaringClass().getSimpleName()可以獲取方法所屬的類的類名。
我這里規定了csv的文件名就是測試類的類名,用例名就是方法名。
return (Iterator<Object[]>) new CSVData(…)就是將CSV讀取類讀取的結果返回,返回的類型是Iterator<Object[]>的,符合@DataProvider的返回值類型要求。當@Test(dataProvider = "dataSource")注解的測試方法執行時就會調用Iterator的hasNext()判斷是否有數據和next()獲取數據。
測試類:
import java.util.Map; import org.testng.annotations.Test; public class DataTest extends DataProviderTest { @Test(dataProvider = "dataSource") public void id2(Map<String, String> data) { System.out.println(data); } @Test(dataProvider = "dataSource") public void id1(Map<String, String> data) { System.out.println(data); } }
輸出結果如下:
PASSED: id1({caseId=id1, flag=Y, property=flowModel, type=com.mybank.bkloanapply.core.model.BaseModel, value=BaseModel.csv@1}) PASSED: id2({caseId=id2, flag=M, property=context, type=java.util.Map, value=a:Object.csv@1})
總結
通過以上例子可以看到,無論@DataProvider注解的方法返回的是Object[ ][ ]還是Iterator<Object>[],最后測試方法獲得的參數都是Object[ ]里放的東西,第一個例子里放了兩列String,第二個例子里放了Map<String, String>,所以第一個測試類的測試方法的參數是兩個String,第二個測試類的測試方法的參數是Map<String, String>,必須保持一致才行。
感謝各位的閱讀!關于java中TestNG數據驅動是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。