TestNG中的另一個有趣的功能是引數化測試。 在大多數情況下,您會遇到業務邏輯需要大量測試的場景。 引數化測試允許開發人員使用不同的值一次又一次地執行相同的測試。
TestNG可以通過兩種不同的方式將引數直接傳遞給測試方法:
testng.xml
在本教學中,我們將向您展示如何通過XML @Parameters
或@DataProvider
將引數傳遞給@Test
方法。
為了方便演示,這裡建立一個名稱為:ParameterTest 的 Maven 工程,其結構如下所示 -
在此範例中,filename
屬性從testng.xml
傳遞,並通過@Parameters
注入到該方法中。
依懶檔案:pom.xml
檔案程式碼如下所示 -
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yiibai</groupId>
<artifactId>IgnoreTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>IgnoreTest</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.2</version>
</dependency>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
</build>
</project>
建立一個名稱為:TestParameterXML.java,其程式碼如下所示 -
package com.yiibai;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class TestParameterXML {
Connection con;
@Test
@Parameters({ "dbconfig", "poolsize" })
public void createConnection(String dbconfig, int poolsize) {
System.out.println("dbconfig : " + dbconfig);
System.out.println("poolsize : " + poolsize);
Properties prop = new Properties();
InputStream input = null;
try {
// get properties file from project classpath
String path = System.getProperty("user.dir")+"\\"+dbconfig;
System.out.println("path => "+path);
//input = getClass().getClassLoader().getResourceAsStream(path);
//prop.load(input);
prop.load(new FileInputStream(dbconfig));
String drivers = prop.getProperty("jdbc.driver");
String connectionURL = prop.getProperty("jdbc.url");
String username = prop.getProperty("jdbc.username");
String password = prop.getProperty("jdbc.password");
System.out.println("drivers : " + drivers);
System.out.println("connectionURL : " + connectionURL);
System.out.println("username : " + username);
System.out.println("password : " + password);
Class.forName(drivers);
con = DriverManager.getConnection(connectionURL, username, password);
} catch (Exception e) {
//e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
//e.printStackTrace();
}
}
}
}
}
建立一個名稱為:db.properties 的檔案, 其程式碼如下所示 -
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456
建立一個名稱為:testng.xml 的檔案, 其程式碼如下所示 -
<?xml version="1.0" encoding="UTF-8"?>
<suite name="test-parameter">
<test name="example1">
<parameter name="dbconfig" value="db.properties" />
<parameter name="poolsize" value="10" />
<classes>
<class name="com.yiibai.TestParameterXML" />
</classes>
</test>
</suite>
執行上面測試類程式碼,得到以下結果 -
[TestNG] Running:
F:\worksp\testng\ParameterTest\src\main\java\com\yiibai\testng.xml
dbconfig : db.properties
poolsize : 10
path => F:\worksp\testng\ParameterTest\db.properties
drivers : com.mysql.jdbc.Driver
connectionURL : jdbc:mysql://localhost:3306/test
username : root
password : 123456
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Tue May 02 23:11:05 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
===============================================
test-parameter
Total tests run: 1, Failures: 0, Skips: 0
===============================================
2.1. 檢視一個簡單的@DataProvider
範例,傳遞一個int
引數。
建立一個名稱為:TestParameterDataProvider.java 的檔案, 其程式碼如下所示 -
package com.yiibai;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestParameterDataProvider {
@Test(dataProvider = "provideNumbers")
public void test(int number, int expected) {
Assert.assertEquals(number + 10, expected);
}
@DataProvider(name = "provideNumbers")
public Object[][] provideData() {
return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
}
}
執行上面測試類程式碼,得到以下結果 -
[TestNG] Running:
C:\Users\Administrator\AppData\Local\Temp\testng-eclipse--1925148879\testng-customsuite.xml
PASSED: test(10, 20)
PASSED: test(100, 110)
PASSED: test(200, 210)
===============================================
Default test
Tests run: 3, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
[TestNG] Time taken by org.testng.reporters.XMLReporter@1b40d5f0: 13 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@6ea6d14e: 34 ms
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@4563e9ab: 7 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms
[TestNG] Time taken by org.testng.reporters.jq.Main@2aaf7cc2: 69 ms
[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@45c8e616: 4 ms
2.2. @DataProvider
支援傳遞一個物件引數。 下面的例子顯示了如何傳遞一個Map物件作為引數。
建立一個名稱為:TestParameterDataProvider2.java 的檔案, 其程式碼如下所示 -
package com.yiibai;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestParameterDataProvider2 {
@Test(dataProvider = "dbconfig")
public void testConnection(Map<String, String> map) {
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("[Key] : " + entry.getKey() + " [Value] : " + entry.getValue());
}
}
@DataProvider(name = "dbconfig")
public Object[][] provideDbConfig() {
Map<String, String> map = readDbConfig();
return new Object[][] { { map } };
}
public Map<String, String> readDbConfig() {
Properties prop = new Properties();
InputStream input = null;
Map<String, String> map = new HashMap<String, String>();
try {
input = getClass().getClassLoader().getResourceAsStream("db.properties");
prop.load(input);
map.put("jdbc.driver", prop.getProperty("jdbc.driver"));
map.put("jdbc.url", prop.getProperty("jdbc.url"));
map.put("jdbc.username", prop.getProperty("jdbc.username"));
map.put("jdbc.password", prop.getProperty("jdbc.password"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return map;
}
}
執行上面測試類程式碼,得到以下結果 -
[TestNG] Running:
F:\worksp\testng\ParameterTest\src\main\java\com\yiibai\testng.xml
dbconfig : db.properties
poolsize : 10
path => F:\worksp\testng\ParameterTest\db.properties
drivers : com.mysql.jdbc.Driver
connectionURL : jdbc:mysql://localhost:3306/test
username : root
password : 123456
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Tue May 02 23:15:52 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
===============================================
test-parameter
Total tests run: 1, Failures: 0, Skips: 0
===============================================
此範例顯示如何根據測試方法名稱傳遞不同的引數。
建立一個名稱為:TestParameterDataProvider3.java 的檔案, 其程式碼如下所示 -
package com.yiibai;
import java.lang.reflect.Method;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestParameterDataProvider3 {
@Test(dataProvider = "dataProvider")
public void test1(int number, int expected) {
Assert.assertEquals(number, expected);
}
@Test(dataProvider = "dataProvider")
public void test2(String email, String expected) {
Assert.assertEquals(email, expected);
}
@DataProvider(name = "dataProvider")
public Object[][] provideData(Method method) {
Object[][] result = null;
if (method.getName().equals("test1")) {
result = new Object[][] {
{ 1, 1 }, { 200, 200 }
};
} else if (method.getName().equals("test2")) {
result = new Object[][] {
{ "[email protected]", "[email protected]" },
{ "[email protected]", "[email protected]" }
};
}
return result;
}
}
執行上面測試類程式碼,得到以下結果 -
[TestNG] Running:
C:\Users\Administrator\AppData\Local\Temp\testng-eclipse-817554174\testng-customsuite.xml
PASSED: test1(1, 1)
PASSED: test1(200, 200)
PASSED: test2("[email protected]", "[email protected]")
PASSED: test2("[email protected]", "[email protected]")
===============================================
Default test
Tests run: 4, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
[TestNG] Time taken by org.testng.reporters.XMLReporter@1b40d5f0: 17 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@6ea6d14e: 51 ms
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@4563e9ab: 9 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms
[TestNG] Time taken by org.testng.reporters.jq.Main@2aaf7cc2: 93 ms
[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@45c8e616: 5 ms
在TestNG中,我們可以使用org.testng.ITestContext
來確定呼叫當前測試方法的執行時引數。 在最後一個例子中,我們將演示如何根據包含的分組名稱傳遞引數。
建立一個名稱為:TestParameterDataProvider4.java 的檔案, 其程式碼如下所示 -
package com.yiibai;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestParameterDataProvider4 {
@Test(dataProvider = "dataProvider", groups = {"groupA"})
public void test1(int number) {
Assert.assertEquals(number, 1);
}
@Test(dataProvider = "dataProvider", groups = "groupB")
public void test2(int number) {
Assert.assertEquals(number, 2);
}
@DataProvider(name = "dataProvider")
public Object[][] provideData(ITestContext context) {
Object[][] result = null;
//get test name
//System.out.println(context.getName());
for (String group : context.getIncludedGroups()) {
System.out.println("group : " + group);
if ("groupA".equals(group)) {
result = new Object[][] { { 1 } };
break;
}
}
if (result == null) {
result = new Object[][] { { 2 } };
}
return result;
}
}
建立一個名稱為:testng4.xml 的檔案, 其程式碼如下所示 -
<?xml version="1.0" encoding="UTF-8"?>
<suite name="test-parameter">
<test name="example1">
<groups>
<run>
<include name="groupA" />
</run>
</groups>
<classes>
<class name="com.yiibai.TestParameterDataProvider4" />
</classes>
</test>
</suite>
執行上面測試類程式碼,得到以下結果 -
[TestNG] Running:
F:\worksp\testng\ParameterTest\src\main\java\com\yiibai\testng4.xml
group : groupA
===============================================
test-parameter
Total tests run: 1, Failures: 0, Skips: 0
===============================================