如何避免空额外浏览器中打开使用TestNG运行并行测试时 [英] How to avoid empty extra browser opens when running parallel tests with TestNG

查看:174
本文介绍了如何避免空额外浏览器中打开使用TestNG运行并行测试时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我正在使用TestNG和硒的webdriver并行测试的情况下,也有开空,甚至在执行完成后不关闭一些浏览器实例。我已阅读不同的论坛上问类似的问题,几个主题,但他们都不似乎是同样的问题。

While I'm running parallel test cases using TestNG and selenium-webdriver, there are some browser instances that open empty and doesn't close even after the execution finish. I have read several topics on different forums asking about similar problems but none of them seems to be the same issue.

也似乎更加空虚的浏览器是开放的,当我添加更多的测试套件。我不知道以下信息会有什么相关的这个问题,但我会尽量提供什么,我有一个完整的画面:

Also seems like more empty browsers are open when I add more test to the suite. I'm not sure what of the following information will be relevant for this problem but I will try to provide a complete picture of what I have:


  • 我使用的(如前所述)TestNG的 - 的webdriver

  • 我与页面对象的工作模式。

  • 我是从一个JavaFX接口,允许用户选择一些选项,运行自动化的我。

  • 我使用ChromeDriver模拟移动设备上。

  • 我使用的驱动程序,允许我使用独占静态驱动程序为每个测试的本地线程。

  • 没有空的浏览器打开的时候,我不并行运行。

这是我的testng.xml:

This is my TestNg.xml:

<suite name="Suite" parallel="classes" thread-count="4">
<test name="Test">
<groups>
     <run>
        <!-- Use include to specify what you want to run or exclude to not run the mentioned group(s) -->
        <include name="fullRegression"/>
        <exclude name="brokenOrDevelopment"/>
     </run>
  </groups>
<packages>
    <!-- Packages who contains the test cases classes -->
    <package name="Test"/>       
</packages>


 

这是创建驱动程序实例类

This is the class which create the driver instance

public class TestCaseConfiguration {
 protected HomePageObjects homePage = null;
 protected DesiredCapabilities  capabilities;
 protected ExtentReports REPORTMANAGER;
 protected ExtentTest REPORT;

 public static ThreadLocal<ChromeDriver> driver;

 @BeforeMethod(alwaysRun = true)
 public void setup() throws InterruptedException {

     System.setProperty("webdriver.chrome.driver", "src/Tools/chromedriver.exe");//chrome driver version 2.20 | We need to have a relative path since no all the user will have the driver on C: 

     capabilities = DesiredCapabilities.chrome();
     Map<String, String> mobileEmulation = new HashMap<String, String>();
     mobileEmulation.put("deviceName", Constants.DEVICE);
     Map<String, Object> chromeOptions = new HashMap<String, Object>();
     chromeOptions.put("mobileEmulation", mobileEmulation);

     capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);

     /**
      * dirver is a ThreadLocal<ChromeDriver>. This allows the driver to be static and available for the complete project, and exclusive for each thread. 
      */
     driver=new ThreadLocal<ChromeDriver>()
                {
                    @Override
                    protected ChromeDriver initialValue()
                    {
                        return new ChromeDriver(capabilities); 
                    }
                };
     driver.get().manage().deleteAllCookies();
     driver.get().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
     driver.get().navigate().to(Constants.DOMAIN);

     homePage = PageFactory.initElements(driver.get(), HomePageObjects.class);
 }

 @AfterMethod(alwaysRun = true)
 public void close() throws InterruptedException {           
    driver.get().close();
    driver.get().quit();  
 }

}

本类每个测试用例类扩展。如预期运行测试,唯一的问题似乎是多余的浏览器实例。

This class is extended by each test case class. The tests run as expected, the only problem seems to be the extra browser instances.

难道没有人知道如何避免这个问题,或者如果我做错了什么?
感谢您的帮助。

Doesn't anyone know how can I avoid that issue or if I'm doing something wrong? Thanks for the help.

这是浏览器的外观,当打开空

推荐答案

您正在创建一个新的的ThreadLocal&LT; ChromeDriver&GT; 实例,并重新分配驱动每次设置运行。想象一下下面的场景,其中设置是并行多线程名为:

You are creating a new ThreadLocal<ChromeDriver> instance and reassigning driver each time setup runs. Imagine the following scenario where setup is called in parallel by multiple threads:


  1. Thread0创建的ThreadLocal&LT; ChromeDriver&GT; 实例,其分配给驱动,并呼吁 driver.get()。一个浏览器现已开放。

  2. 线程1创建的ThreadLocal&LT; ChromeDriver&GT; 实例,其分配给驱动(更换一个接分配给它Thread0),并要求 driver.get()。两个浏览器现在是开放的,每个的ThreadLocal 实例之一。

  3. Thread0调用 driver.get()再度但驱动不再引用相同的 ThreadLocal的实例,这样一个新的浏览器中打开。三种浏览器现在是开放的,一个是孤立的ThreadLocal 实例和两个在引用的ThreadLocal

  1. Thread0 creates a ThreadLocal<ChromeDriver> instance, assigns it to driver, and calls driver.get(). One browser is now open.
  2. Thread1 creates a ThreadLocal<ChromeDriver> instance, assigns it to driver (replacing the one assigned to it by Thread0), and calls driver.get(). Two browsers are now open, one per ThreadLocal instance.
  3. Thread0 calls driver.get() again but driver no longer references the same ThreadLocal instance so a new browser is opened. Three browsers are now open, one in an "orphaned" ThreadLocal instance and two in the referenced ThreadLocal.

现在想象的场景,但有两个以上的线程!您将有大量的孤儿的ThreadLocal 实例左右浮动,其中一些具有一些相关的 ChromeDriver 实例螺纹(S),但要引用任何线程没有对象的的ThreadLocal 以让出来。

Now imagine that scenario but with more than two threads! You'll have lots of "orphaned" ThreadLocal instances floating around, some of which having a ChromeDriver instance associated with some thread(s) but no objects on any threads with references to the ThreadLocal in order to "get" them.

要解决,我建议标记问题驱动最后并分配 ThreadLocal的实例来一次。

To fix the problem I recommend marking driver as final and assigning a ThreadLocal instance to it once.

例如

public class TestCaseConfiguration {
    protected HomePageObjects homePage = null;
    protected ExtentReports REPORTMANAGER;
    protected ExtentTest REPORT;

    public static final ThreadLocal<ChromeDriver> driver;
    private static final Set<ChromeDriver> drivers = Collections.newSetFromMap(new ConcurrentHashMap<>());
    static {
        System.setProperty("webdriver.chrome.driver", "src/Tools/chromedriver.exe");//chrome driver version 2.20 | We need to have a relative path since no all the user will have the driver on C:

        DesiredCapabilities capabilities = DesiredCapabilities.chrome();
        Map<String, String> mobileEmulation = new HashMap<String, String>();
        mobileEmulation.put("deviceName", Constants.DEVICE);
        Map<String, Object> chromeOptions = new HashMap<String, Object>();
        chromeOptions.put("mobileEmulation", mobileEmulation);

        capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);

        /**
         * dirver is a ThreadLocal<ChromeDriver>. This allows the driver to be static and available for the complete project, and exclusive for each thread.
         */
        driver = new ThreadLocal<ChromeDriver>() {
            @Override
            protected ChromeDriver initialValue() {
                ChromeDriver chromeDriver = new ChromeDriver(capabilities);
                drivers.add(chromeDriver);
                return chromeDriver;
            }
        };
    }

    @BeforeMethod(alwaysRun = true)
    public void setup() throws InterruptedException {
        driver.get().manage().deleteAllCookies();
        driver.get().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
        driver.get().navigate().to(Constants.DOMAIN);

        homePage = PageFactory.initElements(driver.get(), HomePageObjects.class);
    }

    @AfterSuite(alwaysRun = true)
    public void close() throws InterruptedException {
        for (ChromeDriver chromeDriver : drivers) {
            try {
                chromeDriver.quit();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

这篇关于如何避免空额外浏览器中打开使用TestNG运行并行测试时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆