执行Selenium测试报java.lang.ExceptionInInitializerError如何解决
错误根本原因
错误栈的根因已经明确说明:你把org.openqa.selenium.By$ByXPath类型的对象强制转换为List类型,触发了类转换异常。
你写的这段代码是完全错误的:
private final static List<WebElement> listOfJobs = (List<WebElement>) By.xpath("//*[@id='resultTable']//tbody/tr//a");
By.xpath()的返回值是定位器对象,作用是告诉Selenium你要按照什么规则找元素,它本身根本不包含任何页面元素数据,不可能转成List<WebElement>。而且这个变量是静态常量,类加载阶段就会执行初始化逻辑,所以你还没调用类里的其他方法,初始化就失败了,抛出ExceptionInInitializerError。
符合你需求的正确实现
你想基于By抽象类实现的写法才是Selenium页面对象模式的最佳实践,不建议直接把findElements的结果存为静态变量:提前查出来的元素会和页面状态绑定,页面刷新、跳转后就会变成陈旧元素,后续调用会抛出StaleElementReferenceException。
正确的修改步骤如下:
- 把定位器存为静态By常量,不要提前执行查找元素的操作
// 仅存储元素定位规则,不提前查询元素 private final static By JOB_LIST_LOCATOR = By.xpath("//*[@id='resultTable']//tbody/tr//a");
- 修改getListOfJobs方法,每次调用时实时查询当前页面的元素
public static List<WebElement> getListOfJobs() { // 此处driver替换为你项目中可用的WebDriver实例,比如从基类获取、或者从ThreadLocal存储中拿 return driver.findElements(JOB_LIST_LOCATOR); }
- 修复你listOfJobs方法的空指针隐患:你之前把
jobs初始化为null,直接调用add方法会触发空指针异常
public static List<String> listOfJobs() { List<String> jobs = new ArrayList<>(); for(WebElement jobEle : OrangeHRMAddJobCategories.getListOfJobs()) { jobs.add(jobEle.getText()); } return jobs; }
你之前直接存driver.findElements结果的写法虽然能临时跑通,但可维护性极差:静态变量初始化时必须保证driver已经完成初始化、且页面刚好加载到对应路由才能查到元素,执行顺序稍有变化就会失败,页面刷新后元素也会直接失效。
内容的提问来源于stack exchange,提问作者enthusiasticCoder
相关产品推荐
相关产品推荐

