You need to enable JavaScript to run this app. Java如何实现自定义Getter消除Selenium POM中的重复元素查找代码
优惠活动
大模型
产品
解决方案
定价
更多

Java如何实现自定义Getter消除Selenium POM中的重复元素查找代码

最优实现方案

针对需要消除元素获取方法重复代码、实现类似Lombok @Getter 能力的需求,有两类成熟的实现方案,按适配程度排序如下:

方案1:编译期自定义注解处理器(仿Lombok逻辑,最高匹配需求)

该方案和Lombok实现原理完全一致,编译阶段自动生成对应元素获取方法,无运行时性能损耗,使用体验和原生@Getter完全一致。

实现步骤

  1. 定义两个SOURCE级别的标记注解,分别对应单个元素和集合元素的获取方法生成规则:
import java.lang.annotation.*;

// 标记生成单个WebElement获取方法的By字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface FindElementGetter {
    // 自定义生成的方法名,不填则默认取字段名去掉Selector后缀,如emailInputSelector生成emailInput()
    String value() default "";
}

// 标记生成List<WebElement>获取方法的By字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface FindElementsGetter {
    String value() default "";
}
  1. 编写自定义注解处理器,继承javax.annotation.processing.AbstractProcessor,在process方法中完成以下逻辑:
  • 扫描所有标注了上述两个注解的By类型字段
  • 校验当前类是否存在WebDriver类型的成员变量
  • 按照命名规则生成对应的public方法,方法体固定为return driver.findElement(对应字段名)或return driver.findElements(对应字段名)
  • 将生成的方法写入对应类的字节码中
    可配合Google AutoService自动注册注解处理器,无需手动维护META-INF配置文件。
  1. 改造后的业务页面对象代码可简化为:
public class SigninPage {
    WebDriver driver;

    @FindElementGetter
    private By emailInputSelector = By.id("user_email");
    @FindElementGetter
    private By passwordInputSelector = By.id("user_password");
    @FindElementGetter
    private By signinBtnSelector = By.xpath("//input[@value='Log In']");
    @FindElementGetter
    private By errorDivSelector = By.xpath("//div[@role='alert']");
    @FindElementsGetter
    private By headerLinksSelector = By.className("nav-link");

    public SigninPage(WebDriver driver) {
        this.driver = driver;
    }
    // 所有元素获取方法编译时自动生成,无需手动编写
}

优缺点

  • 优点:完全符合@Getter使用习惯,无运行时开销,代码简洁度最高
  • 缺点:需要额外开发注解处理器,调试成本略高,和Lombok共用时需注意配置注解处理器执行顺序避免冲突

方案2:轻量运行期方案(低开发成本,可快速落地)

如果不想投入成本开发自定义注解处理器,可采用以下两种落地成本极低的替代方案:

子方案2.1 抽象父类封装通用逻辑

抽取通用页面对象父类,封装元素获取逻辑,减少重复方法体代码:

// 通用父类
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }

    protected WebElement getElement(By selector) {
        return driver.findElement(selector);
    }

    protected List<WebElement> getElements(By selector) {
        return driver.findElements(selector);
    }
}

// 改造后的登录页面类
public class SigninPage extends BasePage {
    private By emailInputSelector = By.id("user_email");
    private By passwordInputSelector = By.id("user_password");
    private By signinBtnSelector = By.xpath("//input[@value='Log In']");
    private By errorDivSelector = By.xpath("//div[@role='alert']");
    private By headerLinksSelector = By.className("nav-link");

    public SigninPage(WebDriver driver) {
        super(driver);
    }

    public WebElement emailInput() { return getElement(emailInputSelector); }
    public WebElement passwordInput() { return getElement(passwordInputSelector); }
    public WebElement signinBtn() { return getElement(signinBtnSelector); }
    public WebElement errorDiv() { return getElement(errorDivSelector); }
    public List<WebElement> headerElement() { return getElements(headerLinksSelector); }
}

子方案2.2 Selenium原生PageFactory方案

使用Selenium自带的@FindBy注解配合PageFactory初始化,直接省去所有方法定义:

import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class SigninPage {
    WebDriver driver;

    @FindBy(id = "user_email")
    private WebElement emailInput;
    @FindBy(id = "user_password")
    private WebElement passwordInput;
    @FindBy(xpath = "//input[@value='Log In']")
    private WebElement signinBtn;
    @FindBy(xpath = "//div[@role='alert']")
    private WebElement errorDiv;
    @FindBy(className = "nav-link")
    private List<WebElement> headerElement;

    public SigninPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    // 配合Lombok @Getter注解可自动生成所有元素的get方法,无需手动编写
}

优缺点

  • 优点:开发成本极低,无需额外组件开发,可快速落地
  • 缺点:要么仍需手动编写方法定义,要么依赖运行时代理有轻微性能损耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 15:15:04