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

Selenium自动化测试中跨类方法参数调用失败求助

Selenium自动化测试:继承类无法访问Excel读取参数问题解决

问题描述

在Selenium自动化测试中编写了两个Java类:TestData类的excel()方法负责从Excel文件中读取UID和PWD参数;AdminLoginAction类继承TestData,其Admin_Login()方法需调用上述参数完成登录操作,但脚本报错无法访问这些参数。需解决该问题并评估实现思路是否正确。

现有代码

AdminLoginAction类

import java.io.IOException; 
import java.util.Date;

import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.chrome.ChromeDriver; 
import org.testng.annotations.*;

import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;

import com.aventstack.extentreports.reporter.ExtentSparkReporter;

public class AdminLoginAction extends TestData{

WebDriver d;
Date currentdate = new Date();
String Screenshotdate = currentdate.toString().replace(" ", "-").replace(":", "-");
ExtentSparkReporter spark = new ExtentSparkReporter("ExtentReport.html");
ExtentReports extent = new ExtentReports();
@Test()
public void Admin_Login() throws InterruptedException, IOException {
    TestData excel = new TestData();
    
    extent.attachReporter(spark);
    ExtentTest test = extent.createTest("Launch browswer and access the WeClean Login page");
    test.log(Status.PASS, "Launch browser success...!!!");
    test.pass("Verified launching browser");
    System.setProperty("webdriver.chrome.driver", "D:\\backup\\selenium\\chromedriver.exe");
    d = new ChromeDriver();
    d.manage().window().maximize();
    d.get(URL);
    Utils.CaptureScreenshot(d, Screenshotdate + "_Login.png");
    d.findElement(By.id("loginUser")).sendKeys(UID);
    d.findElement(By.id("password")).sendKeys(PWD);
    d.findElement(By.id("loginButton")).click();
    Thread.sleep(5000);
    Utils.CaptureScreenshot(d, Screenshotdate + "_HomePage.png");
    test.log(Status.PASS, "Admin Logged in Successful");
    test.pass("Verified Admin logged in");
}

TestData类

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.testng.annotations.Test;

public class TestData{
    public void excel() throws IOException {
     String filePath = System.getProperty("user.dir")+"\\Inputfiles";
     File file =    new File(filePath + "\\TestData.xlsx");
     FileInputStream inputStream = new FileInputStream(file);
     XSSFWorkbook wb=new XSSFWorkbook(inputStream);
     XSSFSheet sheet=wb.getSheet("Admin_inputs");
     XSSFRow row2=sheet.getRow(1);
     XSSFCell cell=row2.getCell(0);
     double UID= cell.getNumericCellValue();
     XSSFCell cell2 = row2.getCell(1);
     String PWD = cell2.getStringCellValue();
    }

问题原因

  • 变量作用域错误:TestData类中的UID、PWD是excel()方法的局部变量,仅在方法内部有效,子类无法直接访问。
  • 未调用数据加载方法:AdminLoginAction中未调用父类的excel()方法,导致数据从未被加载;同时没必要新建TestData实例,继承关系已让子类拥有父类的属性和方法。
  • 类型不匹配:UID是double类型,而sendKeys()需要传入String类型,直接传入会引发类型错误。
  • URL未定义:代码中使用的URL变量未在任何类中定义,也会导致报错。

解决方案

步骤1:修改TestData类,将参数设为成员变量

把UID、PWD、URL定义为类的公共成员变量,excel()方法负责初始化这些变量:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class TestData{
    // 定义为类成员变量,子类可访问
    public String UID;
    public String PWD;
    public String URL = "你的登录页面URL"; // 补充URL定义

    public void excel() throws IOException {
        String filePath = System.getProperty("user.dir") + "\\Inputfiles";
        File file = new File(filePath + "\\TestData.xlsx");
        FileInputStream inputStream = new FileInputStream(file);
        XSSFWorkbook wb = new XSSFWorkbook(inputStream);
        XSSFSheet sheet = wb.getSheet("Admin_inputs");
        XSSFRow row2 = sheet.getRow(1);
        
        // 处理UID:将double转为String,避免.0后缀
        XSSFCell cell = row2.getCell(0);
        double uidNum = cell.getNumericCellValue();
        UID = String.valueOf((long) uidNum); // 如果是整数UID,转成long再转String
        
        XSSFCell cell2 = row2.getCell(1);
        PWD = cell2.getStringCellValue();
        
        wb.close(); // 关闭工作簿,释放资源
        inputStream.close();
    }
}

步骤2:修改AdminLoginAction类,正确调用父类方法

利用继承特性,调用父类的excel()方法加载数据,同时修正类型和URL问题:

import java.io.IOException; 
import java.util.Date;

import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.chrome.ChromeDriver; 
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.reporter.ExtentSparkReporter;

public class AdminLoginAction extends TestData{

    WebDriver d;
    Date currentdate;
    String Screenshotdate;
    ExtentSparkReporter spark;
    ExtentReports extent;

    @BeforeMethod
    public void setup() throws IOException {
        // 提前加载测试数据,保证测试方法执行前数据已准备好
        excel();
        currentdate = new Date();
        Screenshotdate = currentdate.toString().replace(" ", "-").replace(":", "-");
        spark = new ExtentSparkReporter("ExtentReport.html");
        extent = new ExtentReports();
        extent.attachReporter(spark);
        // 初始化浏览器
        System.setProperty("webdriver.chrome.driver", "D:\\backup\\selenium\\chromedriver.exe");
        d = new ChromeDriver();
        d.manage().window().maximize();
    }

    @Test()
    public void Admin_Login() throws InterruptedException, IOException {
        ExtentTest test = extent.createTest("Launch browser and access the WeClean Login page");
        test.log(Status.PASS, "Launch browser success...!!!");
        test.pass("Verified launching browser");
        
        d.get(URL);
        Utils.CaptureScreenshot(d, Screenshotdate + "_Login.png");
        
        // 使用父类加载好的参数
        d.findElement(By.id("loginUser")).sendKeys(UID);
        d.findElement(By.id("password")).sendKeys(PWD);
        d.findElement(By.id("loginButton")).click();
        
        Thread.sleep(5000);
        Utils.CaptureScreenshot(d, Screenshotdate + "_HomePage.png");
        
        test.log(Status.PASS, "Admin Logged in Successful");
        test.pass("Verified Admin logged in");
        
        // 关闭浏览器和报告
        d.quit();
        extent.flush();
    }
}

实现思路评估

你的核心思路(父类封装测试数据读取逻辑,子类继承后复用数据)是合理的,符合面向对象的封装和复用思想。但最初的实现存在变量作用域、方法调用时机、类型处理等细节问题,调整这些细节后,就能正常实现预期功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:15:38