retryAnalyzer:“NoSuchSessionException:会话ID为空。在调用quit()之后使用WebDriver”即使重新创建新会话也会被抛出

时间:2018-03-07 05:05:47

标签: java selenium selenium-webdriver testng selenium-chromedriver

我正在使用TestNG 6.9.10版和Selenium 3.8.1和Java 1.8

如果在@Test期间抛出异常,我会使用retryAnalyzer继续重启@Test。 每次异常都会在@Test

的中间抛出
  1. 我抓住它
  2. 将其写入日志文件
  3. 致电driver.quit()
  4. 然后重新扔掉它
  5. 然后,RetryAnalyzer将停止剩余的代码,并从@Test
  6. 的最开头重新启动
  7. 在我@Test的开头,我总是检查浏览器是否仍处于打开状态。如果是,请转到我要测试的网址。如果没有,请打开新的Chrome驱动程序并转到测试网址。
  8. 在此步骤中,系统会启动新的Chrome浏览器,并显示测试网址。
  9. 但在那之后,我将无法执行测试(例如执行driver.findElements()),即使我重新创建了一个新的驱动程序会话(在销毁之后),它也会抛出异常org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
  10. 使用driver.quit()销毁驱动程序会话后,我们可以通过WebDriver driver = new ChromeDriver();重新创建一个新的驱动程序会话吗?或者它不是重新创建新的驱动程序会话的正确方法?

    这是我的代码:

    public class myTest {
    
      private WebDriver driver;
    
      //This codes in BeforeTest below will initiate a new chrome driver session 
      @BeforeTest
      public void initiate() {
        System.setProperty("webdriver.chrome.driver", driverpathchrome);
        DesiredCapabilities caps = DesiredCapabilities.chrome();
        LoggingPreferences logPrefs = new LoggingPreferences();
        logPrefs.enable(LogType.BROWSER, Level.ALL);
        caps.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
        driver = new ChromeDriver(caps);
    
        driver.manage().window().maximize();
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
        driver.get("www.test.com");
        log.info("Chrome browser launched. Going to " + "www.test.com");
      }
    
    
      private boolean isBrowserOpen() {
        try {
          driver.getTitle();
          return true;
        } catch (Exception e) {
          return false;
        }
      }
    
      public boolean amISeeingLoginScreenNow() {
        if (driver.findElements(By.cssSelector(".login-box.smaller")).size() != 0) {
          return true;
        } else {
          return false;
        }
      }
    
      //This is the test methods
      @Test(retryAnalyzer = myTest.RetryAnalyzer.class)
      private void loginToTestURL() throws Exception {
    
        //This will check if the current browser session is still open. If not, then create a new driver session
        if (this.isBrowserOpen() == false) {
          Thread.sleep(3000);
    
          // Initiating new Browser 
          this.initiate();
        } else {
          driver.get("www.test.com");
        }
    
    
        this.method_will_not_throw_exception() {
          //some codes that will work OK
        }
    
    
        try {
          this.method_will_throw_exception() {
            //some codes that will throw exception
            this.amISeeingLoginScreenNow(); //In the 2nd try , at this stage, Selenium will get grumpy
          }
        } catch (Exception e) {
          //put exception in the log files then re-throw the exception
          //retryAnalyzer will get the exception and then start the test from the start of @Test
          driver.quit();
          throw new AssertionError();
        }
    
      }
    }
    

    抛出异常时,retryAnalyzer将从@Test开始。我总是通过调用this.initiate();重新创建一个新的驱动程序会话。之后,启动一个新的浏览器会话并转到测试URL。到现在为止还挺好。

    但是当执行driver.findElements() Selenium等其他代码时,抱怨并给我

    org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
    Build info: version: '3.8.1', revision: '6e95a6684b', time: '2017-12-01T18:33:54.468Z'
    System info: host: 'DEV2015003', ip: '10.0.1.164', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
    Driver info: driver.version: RemoteWebDriver
        at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:131) ~[selenium-remote-driver-3.8.1.jar:?]
        at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83) ~[selenium-remote-driver-3.8.1.jar:?]
        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:601) ~[selenium-remote-driver-3.8.1.jar:?]
        at org.openqa.selenium.remote.RemoteWebDriver.findElements(RemoteWebDriver.java:398) ~[selenium-remote-driver-3.8.1.jar:?]
        at org.openqa.selenium.remote.RemoteWebDriver.findElementsByCssSelector(RemoteWebDriver.java:469) ~[selenium-remote-driver-3.8.1.jar:?]
        at org.openqa.selenium.By$ByCssSelector.findElements(By.java:441) ~[selenium-api-3.8.1.jar:?]
        at org.openqa.selenium.remote.RemoteWebDriver.findElements(RemoteWebDriver.java:359) ~[selenium-remote-driver-3.8.1.jar:?]
        at myTest.myMainTest.amISeeingLoginScreenNow(SSDSearchPage.java:4219) ~[bin/:?]
    

    我想知道为什么Selenium会抱怨会话ID为空。我在@Test的最开始时重新创建了一个新会话。将出现一个新的浏览器会话并转到我的测试URL。这意味着已成功创建新的驱动程序会话。但是当执行driver.findElements()时,Selenium会感到不安。 可能有任何建议或指示?

    如果我没有调用driver.quit();一切都会安好的。没问题。 但我想重新启动浏览器并在每次retryAnalyzer重试测试时获得一个新会话。 非常感谢你。

1 个答案:

答案 0 :(得分:0)

好的,我得到了解决方案。

显然,在我使用Threaddriver.close()销毁驱动程序后,我必须立即重新初始化驱动程序,然后将异常抛向driver.quit()

retryAnalyzer获得异常并重试retryAnalyzer时,必须重新初始化驱动程序会话,必须启动新的Chrome浏览器会话并准备使用。

如果我在向@Test抛出异常之后重新初始化新的驱动程序会话,即在第二次尝试时重新初始化新的驱动程序会话(如果重新启动则无关紧要) - 在@Test的第一次初始化时)这似乎为时已晚。

我不知道为什么retryAnalyzer表现得像这样,或者背后的原因是什么,但这个解决方案对我有用。

此示例代码适用于我:

retryAnalyzer