Selenium 4中PageFactory.initElements报NoSuchMethodError问题排查
问题
为了在运行脚本前给浏览器添加扩展,我决定使用Selenium 4引入的EdgeOptions,目前已导入以下依赖:
- selenium-api-4.1.1
- selenium-chrome-driver-4.1.1
- selenium-chromium-driver-4.1.1
- selenium-edge-driver-4.1.1
- selenium-java-4.1.1
- selenium-remote-driver-4.1.1
- selenium-support-4.1.1
但调用PageFactory.initElements时出现异常,请问是否还需要添加其他依赖?
报错堆栈信息
Message: cucumber.runtime.CucumberException: Failed to instantiate class com.proj.stepdefinitions.common.ConfigTestData at cucumber.runtime.java.DefaultJavaObjectFactory.cacheNewInstance(DefaultJavaObjectFactory.java:40) at cucumber.runtime.java.DefaultJavaObjectFactory.getInstance(DefaultJavaObjectFactory.java:26) at cucumber.runtime.java.JavaHookDefinition.execute(JavaHookDefinition.java:59) at cucumber.runtime.Runtime.runHookIfTagsMatch(Runtime.java:222) at cucumber.runtime.Runtime.runHooks(Runtime.java:210) at cucumber.runtime.Runtime.runBeforeHooks(Runtime.java:200) at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44) at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:91) at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63) at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70) at cucumber.api.junit.Cucumber.runChild(Cucumber.java:93) at cucumber.api.junit.Cucumber.runChild(Cucumber.java:37) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at cucumber.api.junit.Cucumber.run(Cucumber.java:98) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at cucumber.runtime.java.DefaultJavaObjectFactory.cacheNewInstance(DefaultJavaObjectFactory.java:34) ... 31 more Caused by: java.lang.NoSuchMethodError: org.openqa.selenium.support.PageFactory.initElements(Lorg/openqa/selenium/WebDriver;Ljava/lang/Class;)Ljava/lang/Object; at com.proj.stepdefinitions.common.ConfigTestData.<init>(ConfigTestData.java:115) ... 36 more
相关代码(ConfigTestData.java)
import org.junit.Assert; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.PageFactory; import cucumber.api.Scenario; import cucumber.api.java.After; import cucumber.api.java.Before; import cucumber.api.java.en.Given; import com.step.AfterScenarioScript; //project class public class ConfigTestData { //some constants public static WebDriver driver = null; //exception here CommonMethods cm = PageFactory.initElements(driver, CommonMethods.class); AfterScenarioScript afterScenarioScript = PageFactory.initElements(driver, AfterScenarioScript.class); private CreateFile file = PageFactory.initElements(driver, CreateFile.class); @Before public void init(Scenario scenario) throws IOException { prop = Login.readPropertiesFile(); //some code } @After public void afterScenario(Scenario scenario) throws Throwable { //some code } //some utility methods }
解决方案
这个问题核心不是缺少依赖,而是以下两个关键问题:
PageFactory.initElements方法签名变更
Selenium 4中,原有的initElements(WebDriver, Class)方法已被标记为过时,部分版本中甚至直接移除。你需要使用适配Selenium 4的调用方式:
// 方式一:使用ElementLocatorFactory PageFactory.initElements(new DefaultElementLocatorFactory(driver), CommonMethods.class); // 方式二:先实例化页面类再初始化 CommonMethods cm = new CommonMethods(); PageFactory.initElements(driver, cm);
- 初始化时机错误
你在类成员变量位置直接调用PageFactory.initElements,此时driver还是null状态,既会触发方法不存在的错误,还会引发空指针问题。正确的做法是把页面类初始化逻辑移到@Before钩子中,确保driver已经完成实例化:
public class ConfigTestData { public static WebDriver driver = null; private CommonMethods cm; private AfterScenarioScript afterScenarioScript; private CreateFile file; @Before public void init(Scenario scenario) throws IOException { prop = Login.readPropertiesFile(); // 先初始化driver,同时添加扩展 EdgeOptions options = new EdgeOptions(); options.addExtensions(new File("你的扩展文件路径")); driver = new EdgeDriver(options); // 再初始化页面类 cm = PageFactory.initElements(driver, CommonMethods.class); afterScenarioScript = PageFactory.initElements(driver, AfterScenarioScript.class); file = PageFactory.initElements(driver, CreateFile.class); } // 其他代码... }
- 排查依赖冲突
如果调整后仍报错,检查项目中是否混入了Selenium 3.x版本的依赖,旧版本的类会和Selenium 4产生冲突,导致NoSuchMethodError。确保所有Selenium相关依赖版本统一为4.1.1。
内容的提问来源于stack exchange,提问作者Sumit Soni
相关产品推荐
相关产品推荐

