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

TestNG中多个@Test方法如何读取@BeforeTest内的Excel测试变量

问题解决说明

核心问题原因

  • 变量作用域错误:你在类中已经声明了workbook、sheet等成员变量,但在@BeforeTest方法中又重复定义了同名局部变量,导致成员变量始终未被赋值,@Test方法自然无法读取到有效值。同时你在循环中定义的userName、passWord也是局部变量,作用域仅限循环内部,外部方法完全访问不到。
  • 逻辑设计错误:@BeforeTest中的循环会重复实例化ChromeDriver,循环结束后仅会保留最后一行测试数据对应的driver实例和账号密码,前面所有行的测试数据都会被覆盖丢失。
  • 语法错误:代码中存在多处类型不匹配问题,比如getText()返回的是字符串类型,你直接赋值给WebElement变量会直接编译报错,密码输入方法中错误传入了用户名变量等。
  • 依赖逻辑误区:dependsOnMethods仅能保证被依赖方法执行成功后再运行当前测试,本身不具备跨方法传递局部变量的能力。

最优解决方案

推荐用TestNG原生的@DataProvider注解实现Excel参数化,这是TestNG处理多测试用例的标准方案,不需要手动在前置方法里循环读数据,修正后代码如下:

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Login {
    WebDriver driver;

    // 封装Excel测试数据读取逻辑
    @DataProvider(name = "loginTestData")
    public Object[][] getLoginData() throws IOException {
        FileInputStream file = new FileInputStream(new File("D:\\codtest.xlsx"));
        XSSFWorkbook workbook = new XSSFWorkbook(file);
        XSSFSheet sheet = workbook.getSheetAt(0);
        int rowCount = sheet.getLastRowNum();
        Object[][] data = new Object[rowCount][2];
        // 遍历所有行将数据存入二维数组返回
        for (int i = 1; i <= rowCount; i++) {
            data[i-1][0] = sheet.getRow(i).getCell(0).getStringCellValue();
            data[i-1][1] = sheet.getRow(i).getCell(1).getStringCellValue();
        }
        workbook.close();
        file.close();
        return data;
    }

    // 每个测试方法执行前初始化干净的浏览器环境
    @BeforeMethod
    public void browserSetup() {
        System.setProperty("webdriver.chrome.driver", "drivers\\chromedriver.exe");
        driver = new ChromeDriver();
        driver.get("https://opensource-demo.orangehrmlive.com/");
        driver.manage().window().maximize();
    }

    // 测试用户名校验逻辑,自动绑定DataProvider的所有测试数据
    @Test(dataProvider = "loginTestData")
    public void userNameVerify(String userName, String passWord){
        // 仅输入密码不输入用户名,触发用户名校验
        driver.findElement(By.id("txtPassword")).sendKeys(passWord);
        driver.findElement(By.id("btnLogin")).click();
        String errorMessage = driver.findElement(By.xpath("//*[@id=\"spanMessage\"]")).getText();
        if(errorMessage.contains("Username cannot be empty")) {
            System.out.println("用户名校验通过:必填提示正常显示");
        }
    }

    // 测试密码校验逻辑,自动绑定DataProvider的所有测试数据
    @Test(dataProvider = "loginTestData")
    public void passWordVerify(String userName, String passWord){
        // 仅输入用户名不输入密码,触发密码校验
        driver.findElement(By.id("txtUsername")).sendKeys(userName);
        driver.findElement(By.id("btnLogin")).click();
        String errorMessage = driver.findElement(By.xpath("//*[@id=\"spanMessage\"]")).getText();
        if(errorMessage.contains("Password cannot be empty")) {
            System.out.println("密码校验通过:必填提示正常显示");
        }
    }

    // 每个测试方法执行后关闭浏览器,避免用例互相影响
    @AfterMethod
    public void tearDown() {
        driver.quit();
    }
}

可选调整说明

如果需要复用同一个浏览器实例测试所有用例,可以把@BeforeMethod改成@BeforeTest,@AfterMethod改成@AfterTest,注意每次执行完测试用例后要清空输入框内容即可。

内容的提问来源于stack exchange,提问作者Lakshika Maduwanthi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:39:04