问题
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():
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 @Before and doing a different action if had already been initialized, but I don't know what that other action would be.
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
public class InitializeWebDriver {
public static WebDriver driver = null;
@Before
public void beforeScenario() {
driver = new ChromeDriver();
}
@After
public void afterScenario() {
driver.quit();
}
}
CommonSteps.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!
回答1:
I don't think driver is null, that would cause a NullPointerException and it would have no way of knowing to convert it to a SessionNotFoundException. So it looks like driver has been created and then ended, i.e. .quit() has been called too soon, as suggested in the error message.
Here's what I think is happening:
- It starts the first test and calls the
@Before. This causesInitializeWebDriver.driverto be set as the newWebDriver. - Only after that does it load the class
CommonSteps, soCommonSteps.driveris set to theWebDriverthat was just created. - The test runs successfully, and
.quit()is called on theWebDriver, in the@Aftermethod. - Then it starts the second test. A new
WebDriveris created in the@Beforemethod.InitializeWebDriver.driveris updated; however,CommonSteps.driveris not updated, because thedriver = InitializeWebDriver.driver;only happens whenCommonStepsis first loaded. - Therefore, when it gets to
driver.get(value),driveris the originalWebDriver, which has already been.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.
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.
来源:https://stackoverflow.com/questions/41352248/sessionnotfoundexception-session-id-is-null-using-webdriver-after-calling-quit