使用TestNG實作資料驅動的方法 @DataProvider
标記的方法除了可以傳回數組外,還可以傳回一個Iterator,這樣的好處是不用把所有的測試資料都加載到記憶體中,而是需要的時候就讀一條。
下面的例子就使用了Iterator,然後在Iterator對象中儲存了一個檔案對象,在需要參數的時候就從檔案中讀一行資料出來。
這個例子主要由如下四個檔案組成:
-
被測試類Person類
-
實作Iterator接口,用于從檔案中讀取資料,傳回給被測試類TxtIterator類
-
TestNG配置檔案testng.xml
-
參數池檔案data.txt
Person主類(被測試類)
package ngtest;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
/**
* @author Administrator
*
*/
public class Person {
String dataFile;
@Parameters({ "file" }) //parameter可以添加在類的構造方法上
public Person(String dataFile) {
super();
this.dataFile = dataFile;
}
@Test(dataProvider = "provider") //被測試方法
public void getName(String name, String age) {
System.out.println(name + "_" + age);
}
@DataProvider(name = "provider")
public Iterator<String[]> provider() throws IOException {
return new TxtIterator(new File(dataFile));
}
}
TxtIterator類
package ngtest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
public class TxtIterator implements Iterator<String[]> {
File txtFile; //資料檔案
BufferedReader bs;
String currentLine;
public TxtIterator(File txtFile) throws IOException {
super();
this.txtFile = txtFile;
try {
bs = new BufferedReader(new FileReader(txtFile));
} catch (FileNotFoundException e) {
System.out.println("檔案找不到");
e.printStackTrace();
}
currentLine = bs.readLine();
}
@Override
public boolean hasNext() {
if (currentLine != null) {
return true;
} else {
return false;
}
}
@Override
public String[] next() {
String returnLine = currentLine;
try {
currentLine = bs.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return returnLine.split(",");
}
}
TestNG配置檔案testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<parameter name="file" value="data.txt"/><!--資料檔案的路徑-->
<test name="Test1">
<classes>
<class name="ngtest.Person" />
</classes>
</test>
</suite>
資料檔案data.txt
Liming,12
HanMeimei,13
Lily,11
Lucy,12
執行後輸出
[TestNG] Running:
D:\workspace\tester\testng.xml
Liming_12
HanMeimei_13
Lily_11
Lucy_12
===============================================
Suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
簡單說一下上面的運作過程:
- 運作testng.xml,發現要運作的方法在Person類中,這就要構造一個Person類的對象,發現Person類的構造方法包含一個file參數,于是從testng.xml檔案中把file參數的值取出來,傳給了構造方法,建立了Person對象
- 開始執行測試,發現該測試方法需要一個DataProvider,于是在本類中找到了provider()方法,執行該方法,構造出Iterator對象,傳遞給測試方法。Iterator對象使用了Person對象中的dataFile成員變量的值構造出一個BufferedReader對象,每當測試方法需要一條資料時就由BufferedReader讀一條資料出來,再拆分成數組,傳回給測試方法調用。這樣就實作了資料驅動和參數懶加載。