TestNG Appium Параллельное выполнение не работает - PullRequest
0 голосов
/ 04 ноября 2019

Я пытаюсь запустить автоматические тесты параллельно через TestNGCucumberRunner, и моя проблема в том, что я создаю экземпляры своих PageObjects с помощью статического метода get из моего класса Manager, поскольку драйвер внутри него является статическим. Я уверен, что это проблема для параллельного выполнения. Как получить драйвер потокобезопасным способом?

Любая помощь приветствуется.

Редактировать: Мой текущий класс драйверов:

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;
    }
}

Здесь я инициализирую драйвер в другом классе:

Вот как я инициализирую драйвер и устанавливаю ThreadLocal в другом классе:

if (capabilities.getPlatform().is(Platform.IOS)) {
            driver = new IOSDriver<MobileElement>(new URL(urlStart + appiumServer.getPort() + "/wd/hub"),
                    capabilities);
        } else {
            driver = new AndroidDriver<MobileElement>(
                    new URL(urlStart + appiumServer.getPort() + "/wd/hub"),
                    capabilities);
        }
        LocalDriverManager.setDriver(driver);

Я устанавливаю переменную localDriver, когда устанавливаю драйвер в другом классе, и на

public BasePage(AppiumDriver driver, WebDriverWait wait) {
        this.driver = driver;
        this.wait = wait;
        PageFactory.initElements(new AppiumFieldDecorator(driver, Duration.ofSeconds(10)), this);
    }

Я получаю это исключение сейчас:

 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)

1 Ответ

1 голос
/ 05 ноября 2019

Вам нужно создать определенный класс для хранения ваших «драйверов» для каждого потока.

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.getTlDriver().get();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...