每次 Geb Spock 测试后退出驱动程序

Quit driver after each Geb Spock test

我正在 Sauce Connect 中进行 运行 Geb/Spock 测试,我希望每个 test 都有唯一的 RemoteWebDriver 实例。这样,Sauce 报告将按测试划分,这使得诊断故障变得容易。我(现在)不关心额外的性能开销,因为就目前而言 运行 我们通过一个 RemoteWebDriver 实例进行的所有 Geb 测试根本没有帮助——需要很长时间来协调结果与Sauce screenshots/screencasts,当发生超时时(在 Sauce Connect 上的长时间 运行 作业中很可能发生)通常会有一些测试失败溢出。

我在扩展 GebReportingSpec 的 class 中试过这个:

def cleanup() {
    if (System.getProperty('geb.env')?.contains('sauce')) {
        setSauceJobStatus()
        driver.quit()
    }
}

当然,我在 setup() 方法中创建了一个新的 RemoteWebDriver。

通过这种方法,我每次测试都获得了一个独特的 Sauce Connect 会话,并且所有结果都在 Sauce 中得到了精美的组织。但是,由于以下原因,所有测试均失败:

"org.openqa.selenium.remote.SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()?"

原来GebReportingSpec中的cleanup()方法调用了这个方法:

void report(String label = "") {
    browser.report(ReporterSupport.toTestReportLabel(_gebReportingSpecTestCounter, _gebReportingPerTestCounter++, _gebReportingSpecTestName.methodName, label))
}

抛出此堆栈跟踪:

at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:125)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:572)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:622)
at org.openqa.selenium.remote.RemoteWebDriver.getPageSource(RemoteWebDriver.java:459)
at geb.report.PageSourceReporter.getPageSource(PageSourceReporter.groovy:42)
at geb.report.PageSourceReporter.writePageSource(PageSourceReporter.groovy:38)
at geb.report.PageSourceReporter.writeReport(PageSourceReporter.groovy:29)
at geb.report.CompositeReporter.writeReport(CompositeReporter.groovy:31)
at geb.Browser.report(Browser.groovy:788)
at geb.spock.GebReportingSpec.report(GebReportingSpec.groovy:44)
at geb.spock.GebReportingSpec.cleanup(GebReportingSpec.groovy:39)

假设在调用 GebReportingSpec cleanup() 方法时 WebDriver 实例仍然存在,以便可以准备报告信息。

所以,我的方法显然不是 "Geb way"...我想知道是否有人可以告诉我如何为每个 Spock 测试正确创建一个独特的驱动程序?

如果你使用browser.quit(),那么你会得到一个异常,测试就会失败。您可以在 class 的开头尝试以下代码片段,它应该可以正常工作:

def setup() {       
    browser.config.cacheDriver = false
    browser.driver = browser.config.driver
}

def cleanup() {
    browser.close()
}

干杯!

不幸的是,您遇到了 GebReportingSpec 实现的限制以及继承层次结构中 Spock 设置和清理方法的固定执行顺序。您应该做的是以覆盖 GebSpec.resetBrowser() 而不是 cleanup():

的方法退出浏览器
void resetBrowser() {
    def driver = browser.driver
    super.resetBrowser()
    if (System.getProperty('geb.env')?.contains('sauce')) {
        driver.quit()
    }
}

获取驱动程序的本地引用然后调用 super 方法很重要,因为调用 super 方法将清除浏览器引用,这意味着您将无法在之后获得驱动程序。

另外,你不应该在 setup() 中创建一个新的 RemoteWebDriver 但你应该 disable driver caching 这意味着每个驱动程序请求都会创建一个新的驱动程序(每个请求一个驱动程序创建浏览器并为每个测试创建一个新浏览器)而不是重复使用缓存的浏览器。