首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

TestNG 數據驅動測試:XML 作為數據源完整實戰

     編輯:Java 相關知識

核心概念

TestNG 的 @DataProvider 支援從多種數據源讀取測試數據:Excel、XML、YAML、CSV 等。本文以 XML + DOM4J 解析 為例,實現靈活的數據驅動測試。

測試數據文件 (TestData.xml)

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <testmethod1>
        <input>1</input>
        <button>2</button>
    </testmethod1>
    <testmethod1>
        <input>3</input>
        <button>4</button>
    </testmethod1>
    <testmethod2>
        <input>3</input>
        <button>4</button>
    </testmethod2>
    <testmethod3>
        <input>3</input>
        <button>4</button>
    </testmethod3>
    <testmethod4>
        <input>3</input>
        <button>4</button>
    </testmethod4>
</data>

XML 解析器 (DOM4J)

public class ParserXml {
    public List<Map<String, Map<String, String>>> parseXml(String fileName) {
        List<Map<String, Map<String, String>>> result = new ArrayList<>();
        File inputXml = new File(fileName);
        SAXReader reader = new SAXReader();
        
        try {
            Document doc = reader.read(inputXml);
            Element root = doc.getRootElement();
            
            for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
                Element methodNode = it.next(); // 如 testmethod1
                Map<String, String> params = new HashMap<>();
                
                for (Iterator<Element> paramIt = methodNode.elementIterator(); paramIt.hasNext(); ) {
                    Element paramNode = paramIt.next(); // 如 input, button
                    params.put(paramNode.getName(), paramNode.getText());
                }
                
                Map<String, Map<String, String>> entry = new HashMap<>();
                entry.put(methodNode.getName(), params);
                result.add(entry);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return result;
    }
}

DataProvider 實現

public class TestData {
    private List<Map<String, Map<String, String>>> xmlData;
    
    public TestData() {
        ParserXml parser = new ParserXml();
        xmlData = parser.parseXml(new File("src/com/test/TestData.xml").getAbsolutePath());
    }
    
    @DataProvider
    public Object[][] providerMethod(Method method) {
        String methodName = method.getName();
        List<Map<String, String>> matched = new ArrayList<>();
        
        // 篩選匹配當前測試方法的數據組
        for (Map<String, Map<String, String>> entry : xmlData) {
            if (entry.containsKey(methodName)) {
                matched.add(entry.get(methodName));
            }
        }
        
        // 轉換為 Object[][] 格式
        Object[][] data = new Object[matched.size()][];
        for (int i = 0; i < matched.size(); i++) {
            data[i] = new Object[] { matched.get(i) }; // 每行一個 Map
        }
        return data;
    }
}

測試類編寫

public class TestDataProvider extends TestData {
    
    @Test(dataProvider = "providerMethod")
    public void testmethod1(Map<?, ?> param) {
        System.out.println("method1 received: " + param.get("input"));
    }
    
    @Test(dataProvider = "providerMethod")
    public void testmethod2(Map<?, ?> param) {
        System.out.println("method2 received: " + param.get("input"));
    }
    
    @Test(dataProvider = "providerMethod")
    public void testmethod3(Map<?, ?> param) {
        System.out.println("method3 received: " + param.get("input"));
    }
    
    @Test // 無 DataProvider,正常執行一次
    public void testmethod4() {
        System.out.println("method4 received: 4");
    }
}

執行結果分析

method1 received: 1
method1 received: 3
method2 received: 3
method3 received: 3
method4 received: 4

PASSED: testmethod1({input=1, button=2})
PASSED: testmethod1({input=3, button=4})
PASSED: testmethod2({input=3, button=4})
PASSED: testmethod3({input=3, button=4})
PASSED: testmethod4

===============================================
Default test
Tests run: 5, Failures: 0, Skips: 0
===============================================

關鍵機制解析

  • 方法名匹配:XML 節點名 (testmethod1) 與測試方法名對應
  • 多組數據:同名節點可重複,對應多組測試數據
  • 參數注入:每組數據封裝為 Map,通過 @Test(dataProvider) 自動注入
  • 無數據方法:不標註 dataProvider 的方法正常執行一次

擴展建議

  1. 支持 Excel:替換 ParserXml 為 Apache POI 實現
  2. 支持 YAML:使用 SnakeYAML 解析,結構更清晰
  3. 參數類型轉換:在 DataProvider 中將 String 轉為實際類型 (int, Date 等)
  4. 並行測試:配合 @Test(threadPoolSize=5, invocationCount=10) 實現併發壓測

Maven 依賴

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.4.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.3</version>
</dependency>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved