NoSuchSessionException 会话 ID 为空。调用quit()后使用WebDriver?并行运行 java 测试时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51617800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:10:19  来源:igfitidea点击:

NoSuchSessionException Session ID is null. Using WebDriver after calling quit()? when running the java tests in parallel

javaseleniumnullpointerexceptionsessionid

提问by Y_Sh

Getting NoSuchSessionException Session ID is null. Using WebDriver after calling quit()? error when running the java test in parallel via cross-browsers.

获取 NoSuchSessionException 会话 ID 为空。调用quit()后使用WebDriver?通过跨浏览器并行运行 java 测试时出错。

The test execution looks fine but in the end the NoSuchSessionException error appeared. I do understand that the driver should be initialized somewhere but it's not clear how to do that.

测试执行看起来不错,但最终出现了 NoSuchSessionException 错误。我知道驱动程序应该在某处初始化,但不清楚如何做到这一点。

The project info: selenium WD, java, testng, maven. Test is being built on jenkins and run on saucelabs.

项目信息:selenium WD、java、testng、maven。测试是在 jenkins 上构建的,并在sauslabs 上运行。

Main class looks like:

主类看起来像:

  public class NewCustomerReg extends RemoteTestBase {
  @Test (dataProvider = "browsers")

  public void RegisterNewUser (String browser, String version, String os, 
  Method method) throws Exception {

    this.createRemoteDriver(browser, version, os, method.getName());
    Application app = new Application(driver);

    app.homePage().homePageDisplayed();
    Log.info("Validate Home Page");

    app.homePage().registerToOrder.click();
    Log.info("Click Register To Order link on the home page");

    app.registerToOrderPage().registerAsNewCustomer.click();
    Log.info("Click on Register As New Customer button");

    driver.close();
 }

The RemoteTestBase that are extended by the main class:

由主类扩展的 RemoteTestBase:

public class RemoteTestBase {

public WebDriver driver;
private static String baseUrl;
ConfigFileReader configRead;
protected PropertyLoader propertyRead;
public Logger Log = Logger.getLogger(BasicTest_Local.class.getName());
private static final String SAUCE_ACCESS_KEY = 
System.getenv("SAUCE_ACCESS_KEY");
private static final String SAUCE_USERNAME = System.getenv("SAUCE_USERNAME");

@BeforeMethod

@DataProvider(name = "browsers", parallel = true)
public static Object[][] sauceBrowserDataProvider(Method testMethod) throws 
JSONException {

    String browsersJSONArrayString  = 
    System.getenv("SAUCE_ONDEMAND_BROWSERS");
    System.out.println(browsersJSONArrayString);
    JSONArray browsersJSONArrayObj = new JSONArray(browsersJSONArrayString);

    Object[][] browserObjArray = new Object[browsersJSONArrayObj.length()] 
    [3];
    for (int i=0; i < browsersJSONArrayObj.length(); i++) {
        JSONObject browserObj = 
    (JSONObject)browsersJSONArrayObj.getJSONObject(i);
        browserObjArray[i] = new Object[]{browserObj.getString("browser"), 
    browserObj.getString("browser-version"), browserObj.getString("os")};
    }
    return browserObjArray;
   }

   void createRemoteDriver(String browser, String version, String os, String 
   methodName) throws Exception {

    DesiredCapabilities capabilities = new DesiredCapabilities();
    Class<? extends RemoteTestBase> SLclass = this.getClass();
    capabilities.setCapability("browserName", browser);
    if (version != null) {
        capabilities.setCapability("browser-version", version);
    }
    capabilities.setCapability("platform", os);
    capabilities.setCapability("name", SLclass.getSimpleName());
    capabilities.setCapability("tunnelIdentifier", "hdsupply");


    driver = (new RemoteWebDriver(new URL("http://" + SAUCE_USERNAME + ":" + 
    SAUCE_ACCESS_KEY + "@ondemand.saucelabs.com:80/wd/hub"), capabilities));

    randomuser = new RandomDataSelect();
    configRead = new ConfigFileReader();
    propertyRead = new PropertyLoader();
    baseUrl = propertyRead.getProperty("site.url");
    getURL();
}



private void getURL () {

    driver.get(baseUrl);
    driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
    this.annotate("Visiting page..." + driver.toString());


}

private void printSessionId() {

    String message = String.format("SauceOnDemandSessionID=%1$s job- 
    name=%2$s",
            (((RemoteWebDriver) driver).getSessionId()).toString(), "some job 
    name");
    System.out.println(message);
}



@AfterMethod(description = "Throw the test execution results into saucelabs")
public void tearDown(ITestResult result) throws Exception {

    ((JavascriptExecutor) driver).executeScript("sauce:job-result=" + 
 (result.isSuccess() ? "passed" : "failed"));
    printSessionId();
    driver.quit();
}
void annotate(String text)
{
    ((JavascriptExecutor) driver).executeScript("sauce:context=" + text);
}
}

The error log:

错误日志:

Session ID is null. Using WebDriver after calling quit()?
Build info: version: '3.11.0', revision: 'e59cfb3', time: '2018-03- 
11T20:26:55.152Z'
System info: host: 'gfmwsb01lds.hsi.hughessupply.com', ip: '10.224.196.74', 
os.name: 'Linux', os.arch: 'amd64', os.version: '2.6.32-504.8.1.el6.x86_64', 
java.version: '1.8.0_161'
Driver info: driver.version: RemoteWebDriver
org.openqa.selenium.NoSuchSessionException: Session ID is null. Using 
WebDriver after calling quit()?
Build info: version: '3.11.0', revision: 'e59cfb3', time: '2018-03- 
11T20:26:55.152Z'
System info: host: 'gfmwsb01lds.hsi.hughessupply.com', ip: '10.224.196.74', 
os.name: 'Linux', os.arch: 'amd64', os.version: '2.6.32-504.8.1.el6.x86_64', 
java.version: '1.8.0_161'
Driver info: driver.version: RemoteWebDriver
at 
org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.
java:125)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.
java:545)
at org.openqa.selenium.remote.RemoteWebDriver$RemoteWebDriverOptions
$RemoteTimeouts.implicitlyWait(RemoteWebDriver.java:779)
at com.hdsupplysolutions.tests.RemoteTestBase.getURL(RemoteTestBase.java:83)
at 
com.hdsupplysolutions.tests.RemoteTestBase.createRemoteDriver(RemoteTestBase.
java:75)
at 
com.hdsupplysolutions.tests.***.RegisterNewUser(NewCustomerRegi.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.
java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at 
org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocation
Helper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(
TestMethodWithDataProviderMethodWorker.java:71)
at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(
TestMethodWithDataProviderMethodWorker.java:14)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
java:624)
at java.lang.Thread.run(Thread.java:748)

回答by Corey Goldberg

Here is an explanation of what is happening:

以下是对正在发生的事情的解释:

You are calling driver.close()in RegisterNewUser. This will close the current window. If no open windows remain, the driver quits. So, when your tearDowncalls driver.quit()the session has already ended and you get an error.

您正在呼叫driver.close()RegisterNewUser。这将关闭当前窗口。如果没有打开的窗户,驱动程序将退出。因此,当您tearDown调用driver.quit()会话时,会话已经结束并且您收到错误消息。

Solutions you could use:

您可以使用的解决方案:

  • don't call driver.close()in your test and let the teardown handle it
  • 不要调用driver.close()您的测试并让拆解处理它

or

或者

  • in teardown, check for a valid session and only call driver.quit()if one exists
  • 在拆卸中,检查有效的会话,并且只有driver.quit()在存在时才调用