You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JDBC ResultSet遍历实现TestNG @DataProvider数据驱动测试?

使用TestNG @DataProvider结合MySQL实现数据驱动登录测试

嘿,我刚好做过类似的数据驱动测试需求,结合你的场景,我整理了一套完整的实现方案,包含从数据库读取数据、封装成TestNG需要的DataProvider格式,以及对应的测试方法示例。

整体思路

  1. 用JDBC连接MySQL数据库,查询测试数据表里的3行记录
  2. 遍历ResultSet,把每行的scenario、username、password存储到集合中
  3. 将集合转换为TestNG @DataProvider要求返回的Object[][]格式
  4. 在测试方法上指定这个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();
            }
        }
    }
}

关键部分解释

  1. ResultSet遍历与转换:

    • ResultSet是游标式的,只能向前遍历一次,所以我们先把数据存入List<Object[]>,再转成Object[][],这是TestNG DataProvider要求的返回格式
    • 每行数据对应一个Object[],元素顺序要和测试方法的参数顺序一致(浏览器、用户名、密码)
  2. 资源关闭:

    • 在finally块中依次关闭ResultSet、Statement、Connection,避免数据库连接泄漏
    • 如果使用Java 7+,也可以用try-with-resources语法自动关闭资源,代码会更简洁
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:52:04