首页 > 解决方案 > 无法让测试方法与硒网格并行运行

问题描述

所以我有一个 selenium 网格集线器,一个为每个浏览器注册了 5 个实例的节点(Safari 12.1.2、Firefox 69.0、Chrome 76.0)。每当我尝试使用并行方法和 thread-count=2 或更多方法运行测试时,我都会不断收到有关会话创建问题的错误消息。很奇怪,但 Chrome 中的测试通过(有时 Safari 中的测试也会通过)。我相信测试脚本是好的。我相信这个问题与方法共享相同的浏览器会话有关,尽管我实现了线程安全方法,但是,一定有我错过的东西。我认为问题出在 TestBase.class 的某个地方,但不确定。ide 用完了。请指教。

Selenium Grid 3 Selenium-java 库:v 3.141.59 java.version:'11.0.4' Safari 12.1.2、Firefox 69.0、Chrome 76.0

这是我的配置节点:

browserTimeout: 0

debug: false

help: false

port: 4445

role: node

timeout: 1800

cleanUpCycle: 5000

host: 169.254.129.238

maxSession: 5

capabilities: Capabilities {browserName: firefox, browserVersion: 69.0, maxInstances: 5, platform: MAC, platformName: mac, se:CONFIG_UUID: 42a26507-e6b8-4463-a6e3-fd7..., seleniumProtocol: WebDriver}

capabilities: Capabilities {browserName: chrome, browserVersion: 76.0, maxInstances: 5, platform: MAC, platformName: mac, se:CONFIG_UUID: c6a7fd21-84cb-4295-be81-cd6..., seleniumProtocol: WebDriver}

capabilities: Capabilities {browserName: safari, browserVersion: 12.1.2, maxInstances: 5, platform: MAC, platformName: mac, se:CONFIG_UUID: 606e350d-f4b7-405a-a772-6c7..., seleniumProtocol: WebDriver}

downPollingLimit: 2

hub: http://localhost:4444

id: http://169.254.129.238:4445

nodePolling: 5000

nodeStatusCheckTimeout: 5000

proxy: org.openqa.grid.selenium.proxy.DefaultRemoteProxy

register: true

registerCycle: 5000

remoteHost: http://169.254.129.238:4445

unregisterIfStillDownAfter: 60000

My testng.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="3" name="Suite" parallel="tests">

    <listeners>
        <listener class-name="Base.TestListener"/>
        <!--<listener class-name="Base.RetryListener"/>-->
    </listeners>

    <parameter name="appURL" value="https://www.google.com"/>

    <test name="Chrome_tests"  parallel="methods" thread-count="2">
        <parameter name="browser" value="chrome"/>
        <parameter name="browser_version" value="76.0"/>
        <parameter name="platform" value="mac"/>
        <classes>
            <class name="Tests.FirstTest">
                <methods>
                    <include name="GOOGLE1" />
                    <include name="GOOGLE2" />
                    <include name="GOOGLE3" />
                </methods>
            </class>
        </classes>
    </test>


    <test name="Firefox_tests" parallel="methods" thread-count="2">
        <parameter name="browser" value="firefox"/>
        <parameter name="browser_version" value="69.0"/>
        <parameter name="platform" value="mac"/>
        <classes>
            <class name="Tests.FirstTest">
                <methods>
                    <include name="GOOGLE1"/>
                    <include name="GOOGLE2"/>
                    <!--<include name="GOOGLE3" />-->
                </methods>
            </class>
        </classes>
    </test> <!-- Second Test -->

    <test name="Safari_tests" parallel="methods" thread-count="1">
        <parameter name="browser" value="safari"/>
        <parameter name="browser_version" value="12.1.2"/>
        <parameter name="platform" value="mac"/>
        <classes>
            <class name="Tests.FirstTest">
                <methods>
                    <include name="GOOGLE1"/>
                    <include name="GOOGLE2"/>
                    <!--<include name="GOOGLE3" />-->
                </methods>
            </class>
        </classes>
    </test> <!-- Second Test -->
</suite>

我的 TestBase.class


    public class TestBase {
        //Declare ThreadLocal Driver (ThreadLocalMap) for ThreadSafe Tests
        public ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
        public CapabilityFactory capabilityFactory = new CapabilityFactory();

        @BeforeMethod
        @Parameters({"browser", "appURL", "browser_version", "platform"})
        public void setup (String browser, String appURL, String browser_version, String platform) throws MalformedURLException {
            //Set Browser to ThreadLocalMap
            driver.set(new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilityFactory.getCapabilities(browser, browser_version, platform)));
            getDriver().manage().window().maximize();
            getDriver().navigate().to(appURL);
        }

        public WebDriver getDriver() {
            //Get driver from ThreadLocalMap
            return driver.get();
        }

        @AfterMethod
        public void tearDown() {
            getDriver().quit();
            driver.remove();
        }
    }


能力工厂类


    public class CapabilityFactory {
        public Capabilities capabilities;

        public Capabilities getCapabilities (String browser, String browser_version, String platform) {
            if (browser.equals("chrome"))
                capabilities = getChromeOptions(browser_version, platform, browser);
            if (browser.equals("firefox"))
                capabilities = getFirefoxOptions(browser_version, platform, browser);
            if (browser.equals("safari"))
                capabilities = getSafariOptions(browser_version, platform, browser);
            return capabilities;
        }

            //Get Chrome Options
            public ChromeOptions getChromeOptions(String browser_version, String platform, String browser) {
                ChromeOptions options = new ChromeOptions();
            /*DesiredCapabilities cap = DesiredCapabilities.chrome();
            cap.setCapability("browser_version", browser_version);
            cap.setCapability("os", platform);
            options.merge(cap);*/

                options.setCapability("browserVersion", browser_version);
                options.setCapability("platformName", platform);
                options.setCapability("browserName", browser);

            /*cap.setCapability("os_version", "10");
            cap.setCapability("resolution", "1024x768");
            cap.setCapability("name", "Bstack-[Java] Sample Test");*/
                /*options.addArguments("--start-maximized");
                options.addArguments("--ignore-certificate-errors");
                options.addArguments("--disable-popup-blocking");*/
                //options.addArguments("--incognito");
                return options;
            }

            //Get Firefox Options
            public FirefoxOptions getFirefoxOptions(String browser_version, String platform, String browser) {

                FirefoxOptions options = new FirefoxOptions();


                /*System.setProperty("webdriver.gecko.driver", "/Users/Sasha/Documents/Selenium_projects/testng_maven/SeleniumGrid/src/main/resources/geckodriver");*/
                options.setCapability("browserVersion", browser_version);
                options.setCapability("platformName", platform);
                options.setCapability("browserName", browser);
            /*DesiredCapabilities cap = DesiredCapabilities.firefox();
            cap.setCapability("browser_version", browser_version);
            cap.setCapability("os", platform);
            options.merge(cap);*/
            /*FirefoxProfile profile = new FirefoxProfile();
            //Accept Untrusted Certificates
            profile.setAcceptUntrustedCertificates(true);
            profile.setAssumeUntrustedCertificateIssuer(false);
            //Use No Proxy Settings
            profile.setPreference("network.proxy.type", 0);
            //Set Firefox profile to capabilities
            options.setCapability(FirefoxDriver.PROFILE, profile);*/
                return options;
            }

            public SafariOptions getSafariOptions(String browser_version, String platform, String browser) {
                SafariOptions options = new SafariOptions();
                options.setCapability("browserVersion", browser_version);
                options.setCapability("platformName", platform);
                options.setCapability("browserName", browser);
            /*FirefoxProfile profile = new FirefoxProfile();
            //Accept Untrusted Certificates
            profile.setAcceptUntrustedCertificates(true);
            profile.setAssumeUntrustedCertificateIssuer(false);
            //Use No Proxy Settings
            profile.setPreference("network.proxy.type", 0);
            //Set Firefox profile to capabilities
            options.setCapability(FirefoxDriver.PROFILE, profile);*/
                return options;
            }
        }

FirstTest.class


    public class FirstTest extends TestBase {
        @Test
        public void GOOGLE1() {
            System.out.println("Google1 Test Started! " + "Thread Id: " +  Thread.currentThread().getId());
            getDriver().navigate().to("http://www.google.com");
            System.out.println("Google1 Test's Page title is: " + getDriver().getTitle() +" " + "Thread Id: " +  Thread.currentThread().getId());
            Assert.assertEquals(getDriver().getTitle(), "Google");
            System.out.println("Google1 Test Ended! " + "Thread Id: " +  Thread.currentThread().getId());
        }

        @Test
        public void GOOGLE2() {
            System.out.println("Google2 Test Started! " + "Thread Id: " +  Thread.currentThread().getId());
            getDriver().navigate().to("http://www.google.com");
            System.out.println("Google2 Test's Page title is: " + getDriver().getTitle() +" " + "Thread Id: " +  Thread.currentThread().getId());
            Assert.assertEquals(getDriver().getTitle(), "Google");
            System.out.println("Google2 Test Ended! " + "Thread Id: " +  Thread.currentThread().getId());
        }

        @Test
        public void GOOGLE3() {
            System.out.println("Google3 Test Started! " + "Thread Id: " +  Thread.currentThread().getId());
            getDriver().navigate().to("http://www.google.com");
            System.out.println("Google3 Test's Page title is: " + getDriver().getTitle() +" " + "Thread Id: " +  Thread.currentThread().getId());
            Assert.assertEquals(getDriver().getTitle(), "Google");
            System.out.println("Google3 Test Ended! " + "Thread Id: " +  Thread.currentThread().getId());
        }
    }

这是我在控制台中得到的:


Chrome_tests started ***
Firefox_tests started ***
Safari_tests started ***
*** Tests GOOGLE1 skipped...

org.openqa.selenium.SessionNotCreatedException: Could not create a session: The Safari instance is already paired with another WebDriver session.
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
remote stacktrace: 
Command duration or timeout: 25.97 seconds

Caused by: org.openqa.selenium.SessionNotCreatedException: Could not create a session: The Safari instance is already paired with another WebDriver session.
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
remote stacktrace: 
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '10.0.2'
Driver info: driver.version: unknown

org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@1b7d4b97
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown

Caused by: org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@1b7d4b97
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '10.0.2'
Driver info: driver.version: unknown

org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@3f5cca9c
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown

Caused by: org.openqa.selenium.SessionNotCreatedException: Unable to create session from org.openqa.selenium.remote.NewSessionPayload@3f5cca9c
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-05T14:56:13.134Z'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.4'
Driver info: driver.version: unknown
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Sashas-MacBook-Pro.local', ip: '192.168.88.183', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '10.0.2'
Driver info: driver.version: unknown


Sep 11, 2019 7:07:32 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Sep 11, 2019 7:07:32 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
*** Running test method GOOGLE1...
Directory already exists: /Users/Sasha/Documents/Selenium_projects/testng_maven/SeleniumGrid/TestReport
*** Running test method GOOGLE2...
Google2 Test Started! Thread Id: 20
Google1 Test Started! Thread Id: 16
Google2 Test's Page title is: Google Thread Id: 20
Google1 Test's Page title is: Google Thread Id: 16
Google1 Test Ended! Thread Id: 16
*** Executed GOOGLE1 test method successfully...
Google2 Test Ended! Thread Id: 20
*** Executed GOOGLE2 test method successfully...
Sep 11, 2019 7:07:42 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
*** Running test method GOOGLE3...
Google3 Test Started! Thread Id: 20
Google3 Test's Page title is: Google Thread Id: 20
Google3 Test Ended! Thread Id: 20
*** Executed GOOGLE3 test method successfully...
Chrome_tests ending ***
log4j:WARN No appenders could be found for logger (freemarker.cache).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

Test ignored.
*** Running test method GOOGLE1...

Test ignored.
*** Running test method GOOGLE2...
*** Tests GOOGLE2 skipped...
Firefox_tests ending ***

Test ignored.
*** Running test method GOOGLE1...
*** Tests GOOGLE1 skipped...

Test ignored.
*** Running test method GOOGLE2...
*** Tests GOOGLE2 skipped...
Safari_tests ending ***
===============================================
Suite
Total tests run: 7, Passes: 3, Failures: 0, Skips: 4
Configuration Failures: 3, Skips: 5
===============================================


Process finished with exit code 0

https://prnt.sc/p4tzjr

标签: javaseleniumparallel-processinggridtestng

解决方案


Safari 一次只能处理 1 个浏览器,类似于 IE 和 Edge。Firefox 和 Chrome 应该能够处理更多。从苹果看到这个链接

在任何给定时间只能激活一个 Safari 浏览器实例,并且一次只能将一个 WebDriver 会话附加到浏览器实例。这些约束确保模拟行为(鼠标、键盘、触摸等)准确反映用户在 macOS 窗口环境中可以执行的操作,并防止测试相互竞争窗口和键盘焦点。


推荐阅读