简体   繁体   English

Selenium和TestNg并行运行并未将驱动程序附加到我们启动的每个浏览器,即使我使用ThreadLocal概念

[英]Selenium and TestNg parallel run is not attaching driver to every browser that we launched even though i used ThreadLocal concept

I used below code to get parallel run work but unfortunately it is NOT working, can anyone help me on this. 我使用下面的代码来获取并行运行的工作,但不幸的是,它无法正常工作,任何人都可以帮我解决这个问题。

    public EmergyaWebDriver initialize() {
        log.info("[log-Properties] " + this.getClass().getName() + "- Start initialize test");

        tmpDriver = new ThreadLocal<RemoteWebDriver>();

        // EmergyaWebDriver tmpDriver = null;

        // Driver initialization
        if (browser.equalsIgnoreCase("Firefox")) {

            FirefoxProfile firefoxProfile = new FirefoxProfile();

            firefoxProfile.setPreference("browser.download.manager.focusWhenStarting", true);
            firefoxProfile.setEnableNativeEvents(true);
            firefoxProfile.setPreference("browser.download.folderList", 2);
            firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
            firefoxProfile.setPreference("browser.download.dir", this.getDownloadPath());

            File dir = new File(this.getDownloadPath());
            if (dir.isDirectory()) {
                File[] files = dir.listFiles();

                for (File file : files) {
                    if (file.isFile()) {
                        file.delete();
                    }
                }
            }

            String mimeTypes = getMimeTypes();

            // adding mimetypes
            firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", mimeTypes);
            // forcing the downloads
            firefoxProfile.setPreference("browser.helperApps.neverAsk.openFile", mimeTypes);
            firefoxProfile.setPreference("browser.helperApps.alwaysAsk.force", false);

            firefoxProfile.setPreference("pdfjs.disabled", true);

            // EmergyaFirefoxDriver tmpDriver = new firefoxProfile(firefoxProfile);

            DriverManager manager = new DriverManager();
            manager.setWebDriver(driver = new EmergyaFirefoxDriver(firefoxProfile));
}
}


public class DriverManager {
    private static ThreadLocal<EmergyaWebDriver> EmergyaWebDriver = new ThreadLocal<EmergyaWebDriver>();

    public static EmergyaWebDriver getDriver() {
        return EmergyaWebDriver.get();
    }

    public void setWebDriver(EmergyaWebDriver driver) {
        EmergyaWebDriver.set(driver);
    }
}

What I do is I have four separate classes to handle my browsers: 我要做的是,我有四个单独的类来处理我的浏览器:

ChromeDriverFactory: ChromeDriverFactory:

public class ChromeDriverFactory {

    public ThreadLocal<WebDriver> driver;
    private Set<WebDriver> drivers = Collections.newSetFromMap(new ConcurrentHashMap<>());

    public ChromeDriverFactory(Boolean isHeadless) throws IOException
     {
        System.setProperty("webdriver.chrome.driver", TestUtils.getRelativePath() + "/externalLibraries/browsers/chromedriver");
        System.setProperty("java.awt.headless", Boolean.toString(isHeadless));
        DesiredCapabilities caps = DesiredCapabilities.chrome();
        caps.setJavascriptEnabled(true);
        caps.setCapability("takesScreenshot", true);
        ChromeOptions options = new ChromeOptions();
        if (isHeadless)
        {
            options.addArguments("headless");
            options.addArguments("disable-gpu");
            //options.addArguments("no-sandbox");
        }
        options.addArguments("disable-extensions");
        caps.setCapability(ChromeOptions.CAPABILITY, options);

        driver = new InheritableThreadLocal<WebDriver>(){
            @Override
            protected ChromeDriver initialValue() {
                ChromeDriver chromeDriver = new ChromeDriver(caps);
                drivers.add(chromeDriver);
                return chromeDriver;
            }
        };
    }

}

LocalDriverFactory: LocalDriverFactory:

public class LocalDriverFactory {

    public static WebDriver createInstance(String browserName, Boolean isHeadless) throws IOException {

        WebDriver driver = null;
        if (browserName.toLowerCase().contains("firefox")) {

        }
        if (browserName.toLowerCase().contains("internet")) {
            /*driver = new InternetExplorerDriver();
            return driver;*/
        }
        if (browserName.toLowerCase().contains("chrome")) {
            ChromeDriverFactory cFac = new ChromeDriverFactory(isHeadless);
            driver = cFac.driver.get();
        }
        if (browserName.toLowerCase().trim().equals("safari"))
        {
           /* driver = SafariDriverFactory.driver.get();
            LocalDriverManager.setFFWebDriver(driver);*/
        }
        if (browserName.toLowerCase().trim().contains("phantom"))
        {
            java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
        }
        return driver;
    }
}

And LocalDriverManager: 和LocalDriverManager:

public class LocalDriverManager { 公共类LocalDriverManager {

private static ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>();

public static WebDriver getDriver() {
    return driver.get();
    /*driver = chromeWebDriver.get();
    if (driver == null)
    {
        driver = ffWebDriver.get();
    }
    */
}

public static void setDriver(WebDriver indriver)
{
    driver.set(indriver);
}

} }

Then you have to create a listener like so: 然后,您必须像这样创建一个侦听器:

public class WebDriverListener implements IInvokedMethodListener {

    public static int testNumber = 0;

    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult){
        try 
        {
            LocalTestManager.initializeSettings();
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
        if (method.toString().toLowerCase().contains("beforescenario")) {
            WebDriver driver = null;
            try {
                driver = LocalDriverFactory.createInstance(TestSettings.getBrowser(), TestSettings.getIsHeadless());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            LocalDriverManager.setDriver(driver);
            testNumber ++;
            System.out.println("Now executing test number: " + testNumber);
            LocalTestManager.setTestName(method.getTestMethod().getMethodName());
        }
    }

    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        WebDriver driver = LocalDriverManager.getDriver();
            if(method.toString().toLowerCase().contains("afterscenario")){
                try {
                    if (driver != null) {
                        driver.quit();
                    }
                } catch (Exception e) {
                    driver.quit();
                    throw e;
                }
                finally {
                    driver.quit();
                }
            }
    }
}

Your tests should call the listener in an xml file like so: 您的测试应在xml文件中调用侦听器,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" thread-count="4" parallel="methods">
 <listeners>
        <listener class-name="[PATH TO THE WebDriverListener CLASS SEPARATED BY .]WebDriverListener"/>
 </listeners>
  <test name="Regression">
    <classes>
        <class name="[PATH TO THE TEST CLASS SEPARATED BY .]SomeTestClass"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Then you run that xml file through testng. 然后,您通过testng运行该xml文件。 This works for me. 这对我有用。 It opens 4 browsers and executes 4 separate test methods at one time in those 4 browser instances. 它会打开4个浏览器,并在这4个浏览器实例中一次执行4个单独的测试方法。

Note: You have to make sure that you have absolutely NO global static variables. 注意:您必须确保绝对没有全局静态变量。 Everything has to be thread safe (like your browser instances). 一切都必须是线程安全的(例如您的浏览器实例)。

@Trinadh Kumar in regard to your "WebDriverException thrown by findElement(By.xpath: //img[@pc-id = 'logo-big']) org.openqa.selenium.NoSuchSessionException: no such session " error that is occurring. @Trinadh Kumar关于您的“ findElement(By.xpath:// img [@ pc-id ='logo-big'])引发的WebDriverException” org.openqa.selenium.NoSuchSessionException:没有此类会话发生。 Sometimes this happens when you have an outdated version of Chromedriver. 有时,当您使用过时的Chromedriver版本时会发生这种情况。 Try downloading and using the most updated version from https://sites.google.com/a/chromium.org/chromedriver/ . 尝试从https://sites.google.com/a/chromium.org/chromedriver/下载并使用最新版本。 Latest version is 2.30. 最新版本是2.30。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使我们有一个线程池,我的ThreadLocal如何重置每个请求 - How does my ThreadLocal gets reset every request even though we have a thread pool TestNG与Selenium驱动程序工厂并行执行 - TestNG Parallel execution with selenium driver factory 如何使用TestNG并行运行Selenium? - How to run Selenium in parallel using TestNG? Selenium、TestNg 并行运行未按预期工作 - Selenium, TestNg parallel run not working as expected 如何通过使用 TestNG 和 Selenium 的方法并行运行测试 - How to run tests in parallel by methods with TestNG and Selenium 如何使用@BeforeSuite批注使用Selenium + TestNG运行多个浏览器会话(并行执行) - How to run multiple browser sessions (parallel execution) with Selenium + TestNG using @BeforeSuite annotation TestNG:即使我正在运行一组测试,也会为每个组条目调用@BeforeGroups - TestNG: @BeforeGroups gets called for every group entry even though I am running one group of tests 每次我们调用浏览器时,在 selenium 中使用 driver.manage().window().maximize() 是不是很好 - Is that good to use driver.manage().window().maximize() in selenium for every time we invoke browser 如何在多台服务器上的IE中并行运行TestNG / Selenium测试套件? - How can I run a TestNG/Selenium test suite in IE on multiple servers in parallel? 具有并行线程的TestNG Selenium - TestNG Selenium with parallel threads
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM