Cucumber TestNG Appium并行执行不工作

Cucumber TestNG Appium并行执行不工作,cucumber,testng,appium,Cucumber,Testng,Appium,我正试图通过TestNGCucumberRunner并行运行自动化测试,我的问题是,我使用来自Manager类的静态get方法实例化了PageObjects,因为其中的驱动程序是静态的。我很确定这就是并行执行的问题所在。如何以线程安全的方式检索驱动程序 感谢您的帮助 编辑: 我目前的驾驶级别: public class LocalDriverManager { private static ThreadLocal<AppiumDriver> localDriver = new

我正试图通过TestNGCucumberRunner并行运行自动化测试,我的问题是,我使用来自Manager类的静态get方法实例化了PageObjects,因为其中的驱动程序是静态的。我很确定这就是并行执行的问题所在。如何以线程安全的方式检索驱动程序

感谢您的帮助

编辑: 我目前的驾驶级别:

public class LocalDriverManager {
    private static ThreadLocal<AppiumDriver> localDriver = new ThreadLocal<>();

    public static AppiumDriver getDriver() {
        return localDriver.get();
    }

    static void setDriver(AppiumDriver driver) {
        localDriver.set(driver);
    }

    public static ThreadLocal<AppiumDriver> getLocalDriver() {
        return localDriver;
    }
}
我现在收到这个例外:

 java.lang.IllegalArgumentException: Can not set io.appium.java_client.MobileElement field ba.woop.automation.pages.LandingPage.itsBanking to org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$d27c0df4
        at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
        at java.base/java.lang.reflect.Field.set(Field.java:780)
        at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:117)
        at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:105)
        at ba.woop.automation.BasePage.<init>(BasePage.java:35)
        at ba.woop.automation.pages.LandingPage.<init>(LandingPage.java:30)
        at ba.klika.automation.steps.LoginCheckSteps.<init>(LoginCheckSteps.java:13)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
        at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
        at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
        at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
        at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
        at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
        at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
        at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
        at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
        at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
        at io.cucumber.picocontainer.PicoFactory.getInstance(PicoFactory.java:42)
        at cucumber.runtime.java.ObjectFactoryLoader$ObjectFactoryAdapter.getInstance(ObjectFactoryLoader.java:157)
        at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:57)
        at cucumber.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:50)
        at cucumber.runner.TestStep.executeStep(TestStep.java:65)
        at cucumber.runner.TestStep.run(TestStep.java:50)
        at cucumber.runner.PickleStepTestStep.run(PickleStepTestStep.java:43)
        at cucumber.runner.TestCase.run(TestCase.java:46)
        at cucumber.runner.Runner.runPickle(Runner.java:50)
        at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:79)
        at ba.woop.automation.runners.LoginCheckRunner.runScenario(LoginCheckRunner.java:36)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
        at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
        at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:71)
        at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:14)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
        at ?.the user clicks on LOGIN button on LANDING PAGE(file:src/test/resources/features/loginCheck.feature:3)
java.lang.IllegalArgumentException:无法将io.appium.java_client.mobileeElement字段ba.woop.automation.pages.LandingPage.itsBanking设置为org.openqa.selenium.remote.RemoteWebElement$$EnhancerByGlib$$d27c0df4
位于java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetileGalargumentException(UnsafeFieldAccessorImpl.java:167)
位于java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ThrowSetileGalargumentException(UnsafeFieldAccessorImpl.java:171)
位于java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
位于java.base/java.lang.reflect.Field.set(Field.java:780)
位于org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:117)
位于org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:105)
在ba.woop.automation.BasePage.(BasePage.java:35)
在ba.woop.automation.pages.LandingPage.(LandingPage.java:30)
在ba.klika.automation.steps.LoginCheckSteps.(LoginCheckSteps.java:13)
位于java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
位于java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
位于java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
位于org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
位于org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
在org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicdDependencyGuard.observe上(AbstractInjector.java:270)
位于org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
位于org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
位于org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
位于org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
位于org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
位于org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
位于org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
位于io.cumber.picocontainer.picofacory.getInstance(picofacory.java:42)
位于cucumber.runtime.java.ObjectFactoryLoader$ObjectFactoryAdapter.getInstance(ObjectFactoryLoader.java:157)
在cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:57)
在cumber.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:50)
位于cucumber.runner.TestStep.executeStep(TestStep.java:65)
运行(TestStep.java:50)
在cumber.runner.PickleStepTestStep.run(PickleStepTestStep.java:43)中
运行(TestCase.java:46)
位于cumber.runner.runner.runPickle(runner.java:50)
在io.cumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:79)
在ba.woop.automation.runners.LoginCheckRunner.runScenario(LoginCheckRunner.java:36)中
位于java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
位于java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
位于java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
位于java.base/java.lang.reflect.Method.invoke(Method.java:566)
位于org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
位于org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
位于org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
位于org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:71)
位于org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:14)
位于java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
位于java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
位于java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
位于java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
位于java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
位于java.base/java.lang.Thread.run(Thread.java:834)
在?处。用户单击登录页上的登录按钮(文件:src/test/resources/features/loginCheck.feature:3)

您需要创建特定的类来存储每个线程的“驱动程序”

public class ThreadLocalDriver {

    private static ThreadLocal<AppiumDriver> tlDriver = new ThreadLocal<>();

    public static ThreadLocal<AppiumDriver> getTlDriver() {
        return tlDriver;
    }

    public static void setTLDriver(AppiumDriver driver) {
            tlDriver.set(driver);
    }
}
公共类ThreadLocalDriver{
private static ThreadLocal tlDriver=new ThreadLocal();
公共静态线程本地getTlDriver(){
返回驱动程序;
}
公共静态驱动程序(AppiumDriver驱动程序){
tlDriver.set(驱动程序);
}
}

一旦需要获取驱动程序,只需调用静态方法
ThreadLocalDriver.getTlDriver().get()

创建一个单独的驱动程序管理器类,并将驱动程序对象声明为ThreadLocal。您必须使用setter/getter方法来存储y
 java.lang.IllegalArgumentException: Can not set io.appium.java_client.MobileElement field ba.woop.automation.pages.LandingPage.itsBanking to org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$d27c0df4
        at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
        at java.base/java.lang.reflect.Field.set(Field.java:780)
        at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:117)
        at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:105)
        at ba.woop.automation.BasePage.<init>(BasePage.java:35)
        at ba.woop.automation.pages.LandingPage.<init>(LandingPage.java:30)
        at ba.klika.automation.steps.LoginCheckSteps.<init>(LoginCheckSteps.java:13)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
        at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
        at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
        at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
        at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
        at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
        at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
        at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
        at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
        at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
        at io.cucumber.picocontainer.PicoFactory.getInstance(PicoFactory.java:42)
        at cucumber.runtime.java.ObjectFactoryLoader$ObjectFactoryAdapter.getInstance(ObjectFactoryLoader.java:157)
        at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:57)
        at cucumber.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:50)
        at cucumber.runner.TestStep.executeStep(TestStep.java:65)
        at cucumber.runner.TestStep.run(TestStep.java:50)
        at cucumber.runner.PickleStepTestStep.run(PickleStepTestStep.java:43)
        at cucumber.runner.TestCase.run(TestCase.java:46)
        at cucumber.runner.Runner.runPickle(Runner.java:50)
        at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:79)
        at ba.woop.automation.runners.LoginCheckRunner.runScenario(LoginCheckRunner.java:36)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
        at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
        at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:71)
        at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:14)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
        at ?.the user clicks on LOGIN button on LANDING PAGE(file:src/test/resources/features/loginCheck.feature:3)
public class ThreadLocalDriver {

    private static ThreadLocal<AppiumDriver> tlDriver = new ThreadLocal<>();

    public static ThreadLocal<AppiumDriver> getTlDriver() {
        return tlDriver;
    }

    public static void setTLDriver(AppiumDriver driver) {
            tlDriver.set(driver);
    }
}