首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >NoSuchSessionException:会话id无效-带有PageObjects的TestNG parallel=classes

NoSuchSessionException:会话id无效-带有PageObjects的TestNG parallel=classes
EN

Stack Overflow用户
提问于 2018-12-20 03:30:42
回答 1查看 3.7K关注 0票数 1

我试图并行执行两个基本的testng类,但我似乎做错了什么。如果我按顺序运行这些类,一切都很好。

当我并行运行这些类时,我收到一个NoSuchSessionException,来自两个类的操作只在一个浏览器中执行(两个浏览器都打开facebook页面,但所有操作只在一个浏览器上执行)

代码语言:javascript
复制
9-12-2018 21:24:23 INFO  Log:21 - ===============================================
19-12-2018 21:24:23 INFO  Log:21 - ===============================================
19-12-2018 21:24:23 INFO  Log:21 - Test started.
19-12-2018 21:24:23 INFO  Log:21 - Test started.
Dec 19, 2018 9:24:26 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Dec 19, 2018 9:24:26 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
beforeClass thread id = 13
beforeClass hashcode of webDriver instance = 1876669297

org.openqa.selenium.NoSuchSessionException: invalid session id
  (Driver info: chromedriver=2.43.600233 (523efee95e3d68b8719b3a1c83051aa63aa6b10d),platform=Linux 4.9.93-linuxkit-aufs x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
Build info: version: '3.12.0', revision: '7c6e0b3', time: '2018-05-08T14:04:26.12Z'
System info: host: 'LENOVO', ip: '10.0.75.1', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '10.0.2'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities {acceptInsecureCerts: false, acceptSslCerts: false, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 2.43.600233 (523efee95e3d68..., userDataDir: /tmp/.org.chromium.Chromium...}, cssSelectorsEnabled: true, databaseEnabled: false, goog:chromeOptions: {debuggerAddress: localhost:40401}, handlesAlerts: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, rotatable: false, setWindowRect: true, takesHeapSnapshot: true, takesScreenshot: true, unexpectedAlertBehaviour: , unhandledPromptBehavior: , version: 70.0.3538.102, webStorageEnabled: true, webdriver.remote.sessionid: e76393c8805f3970c6ad0e910d7...}

    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:488)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
    at org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40)
    at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:80)
    at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:44)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:543)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:276)
    at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:83)
    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:564)
    at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:51)
    at com.sun.proxy.$Proxy15.click(Unknown Source)
    at pageObjects.HomePage1.setUsername(HomePage1.java:26)
    at uiTests.BaseTest.logIn(BaseTest.java:129)
    at uiTests.transactions.firstClass.class1Test1(firstClass.java:16)
    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:564)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:131)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:658)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:792)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1103)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:140)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:122)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:844)

class1 thread id = 13
class1 hashcode of webDriver instance = 1876669297
beforeClass thread id = 14
beforeClass hashcode of webDriver instance = 1321310502
class2 thread id = 14
class2 hashcode of webDriver instance = 1321310502
afterclass2 thread id = 14
afterclass2 hashcode of webDriver instance = 1321310502
afterclass1 thread id = 13
afterclass1 hashcode of webDriver instance = 1876669297

===============================================
parallelTest
Total tests run: 2, Passes: 1, Failures: 1, Skips: 0
===============================================

DriverFactory

代码语言:javascript
复制
package utils;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;

import java.net.MalformedURLException;
import java.net.URL;

public class DriverFactory {
    public static WebDriver createInstance(String browserType) throws MalformedURLException {
        WebDriver driver = null;

        if (browserType.toLowerCase().contains("chrome")) {
            switch (Constants.RUNNER) {
                case "localhost":
                    driver = createLocalChromeDriver();
                    break;
                case "remote":
                    driver = createRemoteChromeDriver();
                    break;
                default:
                    Log.error("  !!! The value for Constants.RUNNER is not correct; Valid options are: localhost, remote");
                    Assert.fail();
            }
        }
        return driver;
    }

    private static WebDriver createLocalChromeDriver() {
        System.setProperty("webdriver.chrome.driver", "src/main/resources/drivers/chromedriver.exe");

        ChromeOptions options = new ChromeOptions();
        options.addArguments("start-maximized");
        options.addArguments("--incognito");

        WebDriver driver = new ChromeDriver(options);
        driver.manage().deleteAllCookies();
        return driver;
    }

    private static WebDriver createRemoteChromeDriver() throws MalformedURLException {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("start-maximized");
        options.addArguments("--incognito");

        WebDriver driver = new RemoteWebDriver(new URL(Constants.SELENIUM_GRID_ADDR_LOCAL), options);
        driver.manage().deleteAllCookies();
        return driver;
    }
}

DriverManager

代码语言:javascript
复制
package utils;

import org.openqa.selenium.WebDriver;

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

    public static WebDriver getWebDriver() {
        return webDriver.get();
    }

    public static void setWebDriver(WebDriver driver) {
        webDriver.set(driver);
    }
}

BasePage

代码语言:javascript
复制
public class BasePage {
    public WebDriver driver;

    public static final int DEFAULT_WAIT_ELEMENT_TIMEOUT = 5;
    public static final int DEFAULT_WAIT_PAGE_TIMEOUT = 30;
    private static final String CHAR_LIST ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

    public void goToWebPage(String url) {
        Log.debug(" - opening URL: " + url);
        driver.get(url);
    }

    public void scrollToElement(WebElement webElement) {
        waitForElementToBeVisible(webElement, DEFAULT_WAIT_ELEMENT_TIMEOUT);
        ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", webElement);
        waitABit(500);
    }
-----------------
}

HomePage1

代码语言:javascript
复制
public class HomePage1 extends BasePage{
    @FindBy(xpath = "//input[@id='email']")
    private WebElement txtUsername;

    @FindBy(xpath = "//input[@id='pass']")
    private WebElement txtPassword;

    @FindBy(xpath = "//input[@value='Log In']")
    private WebElement btnLogIn;

    public HomePage1(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public void setUsername(String newValue) {
        waitForElementToBeVisible(txtUsername, DEFAULT_WAIT_ELEMENT_TIMEOUT);
        scrollToElement(txtUsername);
        txtUsername.click();
        txtUsername.clear();
        txtUsername.sendKeys(newValue);
    }

    public void setPassword(String newValue) {
        waitForElementToBeVisible(txtPassword, DEFAULT_WAIT_ELEMENT_TIMEOUT);
        scrollToElement(txtPassword);
        txtPassword.click();
        txtPassword.clear();
        txtPassword.sendKeys(newValue);
    }

    public void clickLogInBtn() {
        waitForElementToBeVisible(btnLogIn, DEFAULT_WAIT_ELEMENT_TIMEOUT);
        btnLogIn.click();
    }
}

BaseTest

代码语言:javascript
复制
public class BaseTest {
    private static HomePage1 homePage1;

    @BeforeClass
    @Parameters({"env", "browserType"})
    public void beforeClass(@Optional("test") String env, @Optional("chrome") String browser) throws Exception {
        WebDriver driver = null;
        driver = DriverFactory.createInstance(browser);
        DriverManager.setWebDriver(driver);

        System.out.println("beforeClass thread id = " + Thread.currentThread().getId());
        System.out.println("beforeClass hashcode of webDriver instance = " + DriverManager.getWebDriver().hashCode());

        homePage1 = new HomePage1(driver);
    }

    protected void logIn(String user, String pass) {
        homePage1.setUsername(user);
        homePage1.setPassword(pass);
        homePage1.clickLogInBtn();
    }
}

firstClass

代码语言:javascript
复制
import org.testng.annotations.*;
import uiTests.BaseTest;
import utils.DriverManager;

public class firstClass extends BaseTest {

    @Test()
    public void class1Test1() {
        System.out.println("class1 thread id = " + Thread.currentThread().getId());
        System.out.println("class1 hashcode of webDriver instance = " + DriverManager.getWebDriver().hashCode());

        homePage.goToWebPage("https://www.facebook.com/");
        homePage.waitABit(2000);
        logIn("aaa@yahoo.com", "aaa");
    }

    @AfterClass
    public void closeBrowser() {
        System.out.println("afterclass1 thread id = " + Thread.currentThread().getId());
        System.out.println("afterclass1 hashcode of webDriver instance = " + DriverManager.getWebDriver().hashCode());

        DriverManager.getWebDriver().quit();
    }
}

secondClass

代码语言:javascript
复制
import org.testng.annotations.*;
import uiTests.BaseTest;
import utils.DriverManager;

public class secondClass extends BaseTest {
    @Test
    public void class1Test1() {
        System.out.println("class2 thread id = " + Thread.currentThread().getId());
        System.out.println("class2 hashcode of webDriver instance = " + DriverManager.getWebDriver().hashCode());

        homePage.goToWebPage("https://www.facebook.com/");
        logIn("bbb@yahoo.com", "bbb");
    }

    @AfterClass
    public void closeBrowser() {
        System.out.println("afterclass2 thread id = " + Thread.currentThread().getId());
        System.out.println("afterclass2 hashcode of webDriver instance = " + DriverManager.getWebDriver().hashCode());

        DriverManager.getWebDriver().quit();
    }
}

testNgG.xml

代码语言:javascript
复制
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="parallelTest">
    <test name="notSoParallel" parallel="classes" thread-count="2">
        <classes>
            <class name="uiTests.transactions.firstClass" />
            <class name="uiTests.transactions.secondClass" />
        </classes>
    </test>

</suite>

pom.xml

代码语言:javascript
复制
<dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.0.0-beta1</version>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.12.0</version>
    </dependency>

Expectation:这两个类完全分开运行。

提前感谢您的任何建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-20 12:00:25

问题出在您的测试代码中。

在您的类BaseTest中,您已将homePage1声明为静态数据成员。这会导致BaseTest及其子类的所有实例共享同一个HomePage1实例。

当您按顺序运行时,持久化到HomePage1中的WebDriver对象将通过@BeforeClass@AfterClass正确地清理和初始化。

但是当并行运行时,有一个竞争条件,它会导致快速运行的测试类关闭driver对象,从而导致运行缓慢的测试类以一个没有有效会话的驱动程序结束。

要修复此更改,请使用private static HomePage1 homePage1;

转到private HomePage1 homePage1;

PS:您共享的代码中存在差异。您的测试类引用了一个名为homePage的对象,但我在测试类或基类BaseTest中都找不到任何这样的数据成员。BaseTest只有一个名为homePage1数据成员。但不确定断开的位置在哪里。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53858015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档