java.lang.ExceptionInInitializerError 与 AppiumFieldDecorator - JAVA、黄瓜、Appium
java.lang.ExceptionInInitializerError with AppiumFieldDecorator - JAVA, Cucumber, Appium
大家好!
我正在尝试使用 Cucumber & Appium 为移动应用程序设置一个自动化项目(iOS 和 Android 两者)。
我计划在 JAVA 中编写项目,并使用 Gradle 来实现所需的依赖项。
所以我写了一个小项目,由于某种原因它一直失败并出现以下错误:
java.lang.ExceptionInInitializerError
调用PageFactory.initElements(new AppiumFieldDecorator(driver), this);
时出现异常
这就是我实现页面对象的方式 class:
public class OnboardingPageObjects {
public OnboardingPageObjects(AppiumDriver driver) {
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}
@AndroidFindBy(id = "com.bupp.wood_spoon_chef.staging:id/orangeBtnBackground")
public WebElement getStartedButton;
}
这是测试 class,它在 @Before
挂钩中失败:
public class FeedSteps {
public Capabilities cap;
public OnboardingPageObjects onboardingPageObjects;
@Before()
public void setup() throws MalformedURLException {
cap = new Capabilities();
cap.preparation("4723", Platform.ANDROID);
onboardingPageObjects = new OnboardingPageObjects(cap.getDriver());
}
...
}
这是我初始化AppiumDriver
的class(目前只有Android驱动,iOS驱动没有使用):
public class Capabilities {
private AppiumDriver driver = null;
public DesiredCapabilities capabilities = new DesiredCapabilities();
public void preparation(String port, Platform platform) throws MalformedURLException {
if (platform == Platform.IOS) {
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
//capabilities.setCapability(MobileCapabilityType.UDID, "emulator-5554");
capabilities.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "");
capabilities.setCapability("instrumentedApp", true);
driver = new IOSDriver(new URL("http://localhost:"+port+"/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
} else {
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.UDID, "emulator-5554");
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.bupp.wood_spoon_chef.staging");
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "com.bupp.wood_spoon_chef.presentation.features.splash.SplashActivity");
driver = new AndroidDriver(new URL("http://localhost:"+port+"/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
public AppiumDriver getDriver() {
return driver;
}
public void stopDriver() {
driver.quit();
}
}
如果我更改相同的代码:
-
new AppiumFieldDecorator(driver)
而不是这样做:PageFactory.initElements(driver, this);
- 将
@AndroidFindBy
更改为@FindBy
这是我得到的错误:
Step failed
java.lang.ExceptionInInitializerError
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:53)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:33)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:209)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.access[=16=]0(AppiumFieldDecorator.java:61)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForLocator(AppiumFieldDecorator.java:100)
at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:63)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:147)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:111)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:103)
at com.eatwoodspoon.homechefs.pages.onboarding.OnboardingPageObjects.<init>(OnboardingPageObjects.java:12)
at com.eatwoodspoon.homechefs.stepsdefs.feed.FeedSteps.setup(FeedSteps.java:22)
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @6073f712
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:96)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:94)
at net.sf.cglib.core.internal.LoadingCache.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)
at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:53)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:33)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:209)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.access[=16=]0(AppiumFieldDecorator.java:61)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForLocator(AppiumFieldDecorator.java:100)
at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:63)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:147)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:111)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:103)
at com.eatwoodspoon.homechefs.pages.onboarding.OnboardingPageObjects.<init>(OnboardingPageObjects.java:12)
at com.eatwoodspoon.homechefs.stepsdefs.feed.FeedSteps.setup(FeedSteps.java:22)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.cucumber.java.Invoker.doInvoke(Invoker.java:66)
at io.cucumber.java.Invoker.invoke(Invoker.java:24)
at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
at io.cucumber.java.JavaHookDefinition.execute(JavaHookDefinition.java:64)
at io.cucumber.core.runner.CoreHookDefinition.execute(CoreHookDefinition.java:46)
at io.cucumber.core.runner.HookDefinitionMatch.runStep(HookDefinitionMatch.java:21)
at io.cucumber.core.runner.ExecutionMode.execute(ExecutionMode.java:10)
at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:85)
at io.cucumber.core.runner.TestStep.run(TestStep.java:57)
at io.cucumber.core.runner.TestCase.run(TestCase.java:78)
at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
at io.cucumber.core.runtime.Runtime.lambda$executePickle(Runtime.java:128)
at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase(CucumberExecutionContext.java:129)
at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:129)
at io.cucumber.core.runtime.Runtime.lambda$executePickle(Runtime.java:128)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:249)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
at io.cucumber.core.runtime.Runtime.lambda$runFeatures(Runtime.java:110)
at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.SliceOps.accept(SliceOps.java:200)
at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at io.cucumber.core.runtime.Runtime.runFeatures(Runtime.java:111)
at io.cucumber.core.runtime.Runtime.lambda$run[=16=](Runtime.java:82)
at io.cucumber.core.runtime.Runtime.execute(Runtime.java:94)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:80)
at io.cucumber.core.cli.Main.run(Main.java:87)
at io.cucumber.core.cli.Main.main(Main.java:30)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @6073f712
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at net.sf.cglib.core.ReflectUtils.run(ReflectUtils.java:61)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:332)
... 64 more
这是 Gradle 构建依赖项:
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
implementation 'io.appium:java-client:8.0.0'
implementation 'org.seleniumhq.selenium:selenium-java:4.1.4'
testImplementation group: 'org.testng', name: 'testng', version: '7.6.0'
implementation 'io.cucumber:cucumber-java:7.3.3'
implementation group: 'io.cucumber', name: 'cucumber-testng', version: '7.3.4'
}
请帮忙,我不知道该怎么办!
好的,所以我找到了问题和解决方案!
问题出在运行器配置上。
出于某种原因,如果我们在 Cucumber 的 @Before
钩子中初始化页面对象,它会失败,但如果我们在 TestNG 的 @BeforeClass
钩子或 JUnit 的 @Before
钩子中做同样的事情,它就会完美地工作!
解决方法:
我更改了跑步者的配置。
我没有直接 运行 功能文件,而是在 TestRunner class 中使用了 @CucumberOptions
。
这是我的 TestRunner class,后面是这篇文章:https://www.lambdatest.com/support/docs/running-cucumber-scripts-with-testng-and-selenium/
package com.eatwoodspoon.homechefs.infra;
import com.eatwoodspoon.homechefs.infra.setups.DriverCapabilities;
import io.cucumber.testng.CucumberOptions;
import io.cucumber.testng.FeatureWrapper;
import io.cucumber.testng.PickleWrapper;
import io.cucumber.testng.TestNGCucumberRunner;
import org.testng.annotations.*;
import java.net.MalformedURLException;
@CucumberOptions(features = {"src/test/resources/features"},
glue = {"com/eatwoodspoon/homechefs/stepsDefinitios"},
plugin = {
"pretty",
"html:target/cucumber-reports/cucumber-pretty",
"json:target/cucumber-reports/CucumberTestReport.json",
"rerun:target/cucumber-reports/rerun.txt",
"json:target/cucumber-reports/CucumberTestReport.json"
}
)
public class TestRunner {
private TestNGCucumberRunner testNGCucumberRunner;
public DriverCapabilities cap;
public static HomeChefApp homeChefApp;
@BeforeClass(alwaysRun = true)
public void setUpCucumber() {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
}
@BeforeMethod(alwaysRun = true)
public void setUpClass() throws MalformedURLException {
cap = new DriverCapabilities();
cap.preparation("4723", Platform.ANDROID);
homeChefApp = new HomeChefApp(cap.getDriver());
}
@Test(groups = "cucumber", description = "Runs Cucumber Feature", dataProvider = "features")
public void feature(PickleWrapper pickle, FeatureWrapper cucumberFeature) {
testNGCucumberRunner.runScenario(pickle.getPickle());
}
@DataProvider
public Object[][] features() {
return testNGCucumberRunner.provideScenarios();
}
@AfterClass(alwaysRun = true)
public void tearDownClass() {
testNGCucumberRunner.finish();
cap.stopDriver();
}
}
大家好!
我正在尝试使用 Cucumber & Appium 为移动应用程序设置一个自动化项目(iOS 和 Android 两者)。
我计划在 JAVA 中编写项目,并使用 Gradle 来实现所需的依赖项。
所以我写了一个小项目,由于某种原因它一直失败并出现以下错误:
java.lang.ExceptionInInitializerError
调用PageFactory.initElements(new AppiumFieldDecorator(driver), this);
时出现异常
这就是我实现页面对象的方式 class:
public class OnboardingPageObjects {
public OnboardingPageObjects(AppiumDriver driver) {
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}
@AndroidFindBy(id = "com.bupp.wood_spoon_chef.staging:id/orangeBtnBackground")
public WebElement getStartedButton;
}
这是测试 class,它在 @Before
挂钩中失败:
public class FeedSteps {
public Capabilities cap;
public OnboardingPageObjects onboardingPageObjects;
@Before()
public void setup() throws MalformedURLException {
cap = new Capabilities();
cap.preparation("4723", Platform.ANDROID);
onboardingPageObjects = new OnboardingPageObjects(cap.getDriver());
}
...
}
这是我初始化AppiumDriver
的class(目前只有Android驱动,iOS驱动没有使用):
public class Capabilities {
private AppiumDriver driver = null;
public DesiredCapabilities capabilities = new DesiredCapabilities();
public void preparation(String port, Platform platform) throws MalformedURLException {
if (platform == Platform.IOS) {
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "iOS");
//capabilities.setCapability(MobileCapabilityType.UDID, "emulator-5554");
capabilities.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "");
capabilities.setCapability("instrumentedApp", true);
driver = new IOSDriver(new URL("http://localhost:"+port+"/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
} else {
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.UDID, "emulator-5554");
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.bupp.wood_spoon_chef.staging");
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "com.bupp.wood_spoon_chef.presentation.features.splash.SplashActivity");
driver = new AndroidDriver(new URL("http://localhost:"+port+"/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
public AppiumDriver getDriver() {
return driver;
}
public void stopDriver() {
driver.quit();
}
}
如果我更改相同的代码:
-
new AppiumFieldDecorator(driver)
而不是这样做:PageFactory.initElements(driver, this);
- 将
@AndroidFindBy
更改为@FindBy
这是我得到的错误:
Step failed
java.lang.ExceptionInInitializerError
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:53)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:33)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:209)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.access[=16=]0(AppiumFieldDecorator.java:61)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForLocator(AppiumFieldDecorator.java:100)
at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:63)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:147)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:111)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:103)
at com.eatwoodspoon.homechefs.pages.onboarding.OnboardingPageObjects.<init>(OnboardingPageObjects.java:12)
at com.eatwoodspoon.homechefs.stepsdefs.feed.FeedSteps.setup(FeedSteps.java:22)
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @6073f712
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:96)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:94)
at net.sf.cglib.core.internal.LoadingCache.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)
at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:53)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:33)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:209)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.access[=16=]0(AppiumFieldDecorator.java:61)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForLocator(AppiumFieldDecorator.java:100)
at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:63)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:147)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:111)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:103)
at com.eatwoodspoon.homechefs.pages.onboarding.OnboardingPageObjects.<init>(OnboardingPageObjects.java:12)
at com.eatwoodspoon.homechefs.stepsdefs.feed.FeedSteps.setup(FeedSteps.java:22)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.cucumber.java.Invoker.doInvoke(Invoker.java:66)
at io.cucumber.java.Invoker.invoke(Invoker.java:24)
at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
at io.cucumber.java.JavaHookDefinition.execute(JavaHookDefinition.java:64)
at io.cucumber.core.runner.CoreHookDefinition.execute(CoreHookDefinition.java:46)
at io.cucumber.core.runner.HookDefinitionMatch.runStep(HookDefinitionMatch.java:21)
at io.cucumber.core.runner.ExecutionMode.execute(ExecutionMode.java:10)
at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:85)
at io.cucumber.core.runner.TestStep.run(TestStep.java:57)
at io.cucumber.core.runner.TestCase.run(TestCase.java:78)
at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
at io.cucumber.core.runtime.Runtime.lambda$executePickle(Runtime.java:128)
at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase(CucumberExecutionContext.java:129)
at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:129)
at io.cucumber.core.runtime.Runtime.lambda$executePickle(Runtime.java:128)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:249)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
at io.cucumber.core.runtime.Runtime.lambda$runFeatures(Runtime.java:110)
at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.SliceOps.accept(SliceOps.java:200)
at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at io.cucumber.core.runtime.Runtime.runFeatures(Runtime.java:111)
at io.cucumber.core.runtime.Runtime.lambda$run[=16=](Runtime.java:82)
at io.cucumber.core.runtime.Runtime.execute(Runtime.java:94)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:80)
at io.cucumber.core.cli.Main.run(Main.java:87)
at io.cucumber.core.cli.Main.main(Main.java:30)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @6073f712
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at net.sf.cglib.core.ReflectUtils.run(ReflectUtils.java:61)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:332)
... 64 more
这是 Gradle 构建依赖项:
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
implementation 'io.appium:java-client:8.0.0'
implementation 'org.seleniumhq.selenium:selenium-java:4.1.4'
testImplementation group: 'org.testng', name: 'testng', version: '7.6.0'
implementation 'io.cucumber:cucumber-java:7.3.3'
implementation group: 'io.cucumber', name: 'cucumber-testng', version: '7.3.4'
}
请帮忙,我不知道该怎么办!
好的,所以我找到了问题和解决方案!
问题出在运行器配置上。
出于某种原因,如果我们在 Cucumber 的 @Before
钩子中初始化页面对象,它会失败,但如果我们在 TestNG 的 @BeforeClass
钩子或 JUnit 的 @Before
钩子中做同样的事情,它就会完美地工作!
解决方法:
我更改了跑步者的配置。
我没有直接 运行 功能文件,而是在 TestRunner class 中使用了 @CucumberOptions
。
这是我的 TestRunner class,后面是这篇文章:https://www.lambdatest.com/support/docs/running-cucumber-scripts-with-testng-and-selenium/
package com.eatwoodspoon.homechefs.infra;
import com.eatwoodspoon.homechefs.infra.setups.DriverCapabilities;
import io.cucumber.testng.CucumberOptions;
import io.cucumber.testng.FeatureWrapper;
import io.cucumber.testng.PickleWrapper;
import io.cucumber.testng.TestNGCucumberRunner;
import org.testng.annotations.*;
import java.net.MalformedURLException;
@CucumberOptions(features = {"src/test/resources/features"},
glue = {"com/eatwoodspoon/homechefs/stepsDefinitios"},
plugin = {
"pretty",
"html:target/cucumber-reports/cucumber-pretty",
"json:target/cucumber-reports/CucumberTestReport.json",
"rerun:target/cucumber-reports/rerun.txt",
"json:target/cucumber-reports/CucumberTestReport.json"
}
)
public class TestRunner {
private TestNGCucumberRunner testNGCucumberRunner;
public DriverCapabilities cap;
public static HomeChefApp homeChefApp;
@BeforeClass(alwaysRun = true)
public void setUpCucumber() {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
}
@BeforeMethod(alwaysRun = true)
public void setUpClass() throws MalformedURLException {
cap = new DriverCapabilities();
cap.preparation("4723", Platform.ANDROID);
homeChefApp = new HomeChefApp(cap.getDriver());
}
@Test(groups = "cucumber", description = "Runs Cucumber Feature", dataProvider = "features")
public void feature(PickleWrapper pickle, FeatureWrapper cucumberFeature) {
testNGCucumberRunner.runScenario(pickle.getPickle());
}
@DataProvider
public Object[][] features() {
return testNGCucumberRunner.provideScenarios();
}
@AfterClass(alwaysRun = true)
public void tearDownClass() {
testNGCucumberRunner.finish();
cap.stopDriver();
}
}