Java SessionNotFoundException:会话 ID 为空。调用quit()后使用WebDriver?(硒)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41352248/
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 23:18:23  来源:igfitidea点击:

SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()? (Selenium)

javaselenium-webdriverselenium-chromedrivercucumber-jvm

提问by kroe761

I am trying to write some selenium automated UI tests using Cucumber/Java. If I have only one test in my feature file, everything works fine. But if I add a second test, I get this error on driver.get():

我正在尝试使用 Cucumber/Java 编写一些 selenium 自动化 UI 测试。如果我的功能文件中只有一个测试,则一切正常。但是,如果我添加第二个测试,则会出现以下错误driver.get()

org.openqa.selenium.remote.SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()?
Build info: version: '2.51.0', revision: '1af067dbcaedd7d2ab9af5151fc471d363d97193', time: '2016-02-05 11:20:57'

Basically, I am initializing the webdriver variable on the InitializeWebdriver class in one package, and then referencing it in the other (step definition) classes. I did have the step definition listed below as a part of the InitializeWebdriver class, and it was working just fine (until moved on to a different step in a different class. So I moved that step to a CommonSteps.java file to see if it would then fail, and it did. So now I'm just stuck. I was thinking of doing an if (driver.equals(null))in the @Beforeand doing a different action if had already been initialized, but I don't know what that other action would be.

基本上,我在一个包中的 InitializeWebdriver 类上初始化 webdriver 变量,然后在其他(步骤定义)类中引用它。我确实将下面列出的步骤定义作为 InitializeWebdriver 类的一部分,并且它工作得很好(直到移到不同类中的不同步骤。所以我将该步骤移至 CommonSteps.java 文件以查看它是否然后会失败,而且确实如此。所以现在我被卡住了。我正在考虑在if (driver.equals(null))in 中@Before执行一个操作,如果已经初始化,则执行不同的操作,但我不知道其他操作会是什么。

Here is my code:

这是我的代码:

tests.feature

测试功能

Feature:  Two tests

Background:
    Given I navigate to "http://www.google.com"

Scenario: Test one
    When something happens

Scenario: Test two
    When something else happens

InitializeWebDriver.java

初始化WebDriver.java

public class InitializeWebDriver {

    public static WebDriver driver = null;

    @Before
    public void beforeScenario() {
        driver = new ChromeDriver();
    }

    @After
    public void afterScenario() {
        driver.quit();
    }
}

CommonSteps.java

通用步骤.java

import myPackage.InitializeWebDriver;

public class CommonSteps {

    static WebDriver driver = InitializeWebDriver.driver;

    @Given("^I navigate to \"([^\"]*)\"$")
    public void i_navigate_to(String url) {
        driver.get(value);
    }

Thanks!

谢谢!

采纳答案by David Knipe

I don't think driveris null, that would cause a NullPointerExceptionand it would have no way of knowing to convert it to a SessionNotFoundException. So it looks like driverhas been created and then ended, i.e. .quit()has been called too soon, as suggested in the error message.

我不认为drivernull,这会导致 aNullPointerException并且它无法知道将其转换为 a SessionNotFoundException。所以它看起来driver已经被创建然后结束,即被.quit()调用得太快了,正如错误消息中所建议的那样。

Here's what I think is happening:

这是我认为正在发生的事情:

  1. It starts the first test and calls the @Before. This causes InitializeWebDriver.driverto be set as the new WebDriver.
  2. Only after that does it load the class CommonSteps, so CommonSteps.driveris set to the WebDriverthat was just created.
  3. The test runs successfully, and .quit()is called on the WebDriver, in the @Aftermethod.
  4. Then it starts the second test. A new WebDriveris created in the @Beforemethod. InitializeWebDriver.driveris updated; however, CommonSteps.driveris not updated, because the driver = InitializeWebDriver.driver;only happens when CommonStepsis first loaded.
  5. Therefore, when it gets to driver.get(value), driveris the original WebDriver, which has already been .quit().
  1. 它开始第一个测试并调用@Before. 这导致InitializeWebDriver.driver被设置为新的WebDriver.
  2. 只有在那之后它才加载 class CommonSteps,所以CommonSteps.driver设置WebDriver为刚刚创建的 。
  3. 测试成功运行,并在方法中.quit()WebDriver,上调用@After
  4. 然后它开始第二次测试。WebDriver@Before方法中创建了一个新的。InitializeWebDriver.driver已更新;但是,CommonSteps.driver不会更新,因为driver = InitializeWebDriver.driver;只有在CommonSteps第一次加载时才会发生。
  5. 因此,当它到达时driver.get(value)driver是原来的WebDriver,已经是.quit()

This is assuming you're running the tests in series. If they're in parallel then it will be a bit different.

这是假设您正在连续运行测试。如果它们是并行的,那么它会有点不同。

Basically the problem is that you're using static attributes for WebDriver, which shouldn't be shared between different test runs. It's a while since I've done this stuff, and I don't remember how you store variables scoped to a test run. (In any case I wouldn't be able to answer with certainty, since you haven't said which test framework you're using: JUnit, or something else?) So you'll have to fix it yourself, or ask how to get test-scoped variables in whatever framework you're using.

基本上问题在于您使用的是 的静态属性WebDriver,不应在不同的测试运行之间共享。我已经有一段时间没有做这些事情了,我不记得你是如何存储范围为测试运行的变量的。(在任何情况下,我都无法肯定地回答,因为您没有说您使用的是哪个测试框架:JUnit 还是其他什么?)所以您必须自己修复它,或者询问如何在您使用的任何框架中获取测试范围的变量。

That's if you want to do it properly. If you just want a cheap fix, and if you're not planning to run tests in parallel, I suspect that you can fix it by changing driver.get(value);to InitializeWebDriver.driver.get(value);. In fact, I suggest you try changing that anyway, just to make sure I'm right about this.

那就是如果你想正确地做到这一点。如果您只是想要一个廉价的修复,并且如果您不打算并行运行测试,我怀疑您可以通过更改driver.get(value);InitializeWebDriver.driver.get(value);. 事实上,我建议你无论如何都要尝试改变它,以确保我对此是正确的。