天天看點

TestNG中DataProvider的用法二:帶懶加載的資料驅動

使用TestNG實作資料驅動的方法

@DataProvider

标記的方法除了可以傳回數組外,還可以傳回一個Iterator,這樣的好處是不用把所有的測試資料都加載到記憶體中,而是需要的時候就讀一條。

下面的例子就使用了Iterator,然後在Iterator對象中儲存了一個檔案對象,在需要參數的時候就從檔案中讀一行資料出來。

這個例子主要由如下四個檔案組成:

  1. Person類

    被測試類
  2. TxtIterator類

    實作Iterator接口,用于從檔案中讀取資料,傳回給被測試類
  3. testng.xml

    TestNG配置檔案
  4. 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
===============================================
           

簡單說一下上面的運作過程:

  1. 運作testng.xml,發現要運作的方法在Person類中,這就要構造一個Person類的對象,發現Person類的構造方法包含一個file參數,于是從testng.xml檔案中把file參數的值取出來,傳給了構造方法,建立了Person對象
  2. 開始執行測試,發現該測試方法需要一個DataProvider,于是在本類中找到了provider()方法,執行該方法,構造出Iterator對象,傳遞給測試方法。Iterator對象使用了Person對象中的dataFile成員變量的值構造出一個BufferedReader對象,每當測試方法需要一條資料時就由BufferedReader讀一條資料出來,再拆分成數組,傳回給測試方法調用。這樣就實作了資料驅動和參數懶加載。