如何通过JDBC ResultSet遍历实现TestNG @DataProvider数据驱动测试?
使用TestNG @DataProvider结合MySQL实现数据驱动登录测试
嘿,我刚好做过类似的数据驱动测试需求,结合你的场景,我整理了一套完整的实现方案,包含从数据库读取数据、封装成TestNG需要的DataProvider格式,以及对应的测试方法示例。
整体思路
- 用JDBC连接MySQL数据库,查询测试数据表里的3行记录
- 遍历
ResultSet,把每行的scenario、username、password存储到集合中 - 将集合转换为TestNG
@DataProvider要求返回的Object[][]格式 - 在测试方法上指定这个DataProvider,实现多组数据的登录测试
完整代码实现
首先,确保你的项目中引入了TestNG和MySQL JDBC驱动的依赖(比如Maven的pom.xml里添加对应的依赖)。
DataProvider实现类
import org.testng.annotations.DataProvider; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.List; public class LoginDataProvider { // 数据库连接配置(建议抽成配置文件,这里为了演示写死) private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC"; private static final String DB_USER = "your_db_username"; private static final String DB_PWD = "your_db_password"; private static final String QUERY = "SELECT scenario, username, password FROM your_test_table_name"; @DataProvider(name = "loginTestData") public Object[][] getLoginTestData() { List<Object[]> testDataList = new ArrayList<>(); Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // 加载驱动(MySQL 8.0+ 可以省略这一步,DriverManager会自动加载) Class.forName("com.mysql.cj.jdbc.Driver"); // 建立连接 conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD); // 创建Statement执行查询 stmt = conn.createStatement(); rs = stmt.executeQuery(QUERY); // 遍历ResultSet,把每行数据加入集合 while (rs.next()) { String browser = rs.getString("scenario"); String username = rs.getString("username"); String password = rs.getString("password"); testDataList.add(new Object[]{browser, username, password}); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("读取测试数据失败", e); } finally { // 关闭资源,避免连接泄漏 try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (Exception e) { e.printStackTrace(); } } // 把List转换成Object[][]返回 return testDataList.toArray(new Object[testDataList.size()][]); } }
测试类示例
import org.testng.annotations.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import java.util.concurrent.TimeUnit; public class LoginTest { @Test(dataProvider = "loginTestData", dataProviderClass = LoginDataProvider.class) public void testLogin(String browser, String username, String password) { WebDriver driver = null; try { // 根据scenario(浏览器)初始化驱动 switch (browser.toLowerCase()) { case "chrome": driver = new ChromeDriver(); break; case "firefox": driver = new FirefoxDriver(); break; // 可以扩展其他浏览器 default: throw new IllegalArgumentException("不支持的浏览器:" + browser); } driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("你的登录页面URL"); // 这里替换成实际的登录操作代码 // driver.findElement(By.id("username")).sendKeys(username); // driver.findElement(By.id("password")).sendKeys(password); // driver.findElement(By.id("loginBtn")).click(); // 可以添加断言,验证登录是否成功 // Assert.assertEquals(driver.getTitle(), "预期的页面标题"); System.out.printf("执行登录测试:浏览器=%s,用户名=%s,密码=%s%n", browser, username, password); } finally { // 关闭浏览器 if (driver != null) { driver.quit(); } } } }
关键部分解释
ResultSet遍历与转换:
ResultSet是游标式的,只能向前遍历一次,所以我们先把数据存入List<Object[]>,再转成Object[][],这是TestNG DataProvider要求的返回格式- 每行数据对应一个
Object[],元素顺序要和测试方法的参数顺序一致(浏览器、用户名、密码)
资源关闭:
- 在
finally块中依次关闭ResultSet、Statement、Connection,避免数据库连接泄漏 - 如果使用Java 7+,也可以用
try-with-resources语法自动关闭资源,代码会更简洁
- 在
DataProvider的使用:
- 测试方法通过
dataProvider属性指定DataProvider的名称,dataProviderClass指定DataProvider所在的类(如果和测试类在同一个类里可以省略) - 测试方法的参数顺序要和DataProvider返回的
Object[]元素顺序完全匹配
- 测试方法通过
注意事项
- 依赖引入:确保项目中包含TestNG和MySQL JDBC驱动的依赖,比如Maven:
<!-- TestNG依赖 --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>7.8.0</version> <scope>test</scope> </dependency> <!-- MySQL JDBC驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> - 浏览器驱动配置:确保系统环境变量中配置了对应浏览器的驱动路径(比如ChromeDriver),或者在代码中指定驱动路径
- 数据库配置:建议把数据库连接信息(URL、用户名、密码)放到配置文件(比如properties文件)中,避免硬编码,方便维护
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

