GEB:驱动程序未设置为Browser.driver

时间:2018-11-07 11:31:36

标签: java groovy automated-tests spock geb

我正在用GEB和Spock编写测试(我都是新手)。

驱动程序在GebConfig中声明(已更新-已添加完整的配置文件):

import geb.report.ReportState
import geb.report.Reporter
import geb.report.ReportingListener
import io.github.bonigarcia.wdm.WebDriverManager
import io.qameta.allure.Allure
import org.openqa.selenium.Dimension
import org.openqa.selenium.Point
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxOptions
import org.openqa.selenium.firefox.FirefoxProfile
import org.slf4j.LoggerFactory
import utils.Configuration

def logger = LoggerFactory.getLogger(this.class)

baseUrl = "${Configuration.getStringProperty("BASE_URL")}/${Configuration.getStringProperty("CONTEXT_PATH")}"

baseNavigatorWaiting = true
autoClearCookies = false
cacheDriver = false
reportsDir = 'build/test-reports'

driver = {
    WebDriver dr
    switch (Configuration.getStringProperty("BROWSER_NAME", "chrome").trim().toLowerCase()) {
        case "firefox":
        case "ff":
            dr = new FirefoxDriver(setUpFirefoxOptions())
            break

        case "google chrome":
        case "chrome":
        default:
            dr = new ChromeDriver(setUpGoogleChromeOptions())
    }

    if (Configuration.getBooleanProperty("SET_DRIVER_POSITION", false)) {
        dr.manage().window().setPosition(new Point(
                Configuration.getIntProperty("BROWSER_X_POS", 0),
                Configuration.getIntProperty("BROWSER_Y_POS", 0)))

        dr.manage().window().setSize(new Dimension(
                Configuration.getIntProperty("BROWSER_WIDTH", 1600),
                Configuration.getIntProperty("BROWSER_HEIGHT", 900)));
    } else {
        dr.manage().window().maximize()
    }

    return dr
}

static ChromeOptions setUpGoogleChromeOptions() {
    WebDriverManager.chromedriver().setup()

    ChromeOptions options = new ChromeOptions()

    String args = Configuration.getStringProperty("BROWSER_ARGS")
    if (args) {
        Arrays.stream(args.split("\\s")).each { options.addArguments(it) }
    }
    return options
}

static FirefoxOptions setUpFirefoxOptions() {
    WebDriverManager.firefoxdriver().setup()

    FirefoxOptions options = new FirefoxOptions()
    FirefoxProfile profile = new FirefoxProfile()

    profile.setPreference("network.automatic-ntlm-auth.trusted-uris", "http://,https://")
    options.setProfile(profile).setLegacy(false)
    return options
}

reportingListener = new ReportingListener() {
    void onReport(Reporter reporter, ReportState reportState, List<File> reportFiles) {
        def fileGroups = reportFiles.groupBy { it.name.split("\\.")[-1] }

        fileGroups['png']?.each {
            Allure.addAttachment(it.name, "image/png", new FileInputStream(it), "png")
        }
    }
}

测试示例如下(在下面添加了BaseTest代码):

class SimulationsRunningSpec extends BaseTest {
    def "My great test"() {
        println("test started")
        setup:
        to LoginPage

        when:
        println("when")

        then:
        println("then")
    }


     def cleanupSpec() {
        browser.quit()
        println "Clean up specification"
    }
}

然后我得到以下日志序列:

test started
Created driver
when
then

Created driver
Clean up specification 

因此,在调用to LoginPage时会创建驱动程序。

问题: 它没有设置为浏览器驱动程序,因此在调用browser.quit()时,将创建一个新实例,然后将其关闭(第一个实例仍处于打开状态)。

问题

  1. 如何将驱动程序正确设置为浏览器以通过browser.quit()将其关闭?

  2. 我是对的,如果我需要在 setupSpec 中创建驱动程序,我可以在那里简单地调用to LoginPage吗?还是在先决条件下初始化驱动程序的最佳方法是什么?

更新:

经过一些调试后,我发现由于某种原因,浏览器会null并会在cleanupSpec()中创建。 Spec是否扩展自定义基类的Geb类都没有关系。这重现了我的问题:

class TestSpec extends GebReportingSpec {

    def setupSpec() {
        to Page
        println "setupSpec browser: $browser"
    }

    def setup(){
        println "setup browser: $browser"
    }

    def "My first test"() {
        println("test started")

        when:
        println ''

        then:
        println ''
    }

    def cleanup() {
        println "cleanup browser: $browser"
    }

    def cleanupSpec() {
        println "cleanupSpec browser: $browser"
    }
}

这将产生以下输出:

setupSpec browser: geb.Browser@4beeb0e
setup browser: geb.Browser@4beeb0e
test started


cleanup browser: geb.Browser@4beeb0e
cleanupSpec browser: geb.Browser@5c73f672

最后两行显示browser中的cleanupSpec对象与setupSpec中的创建对象不同。

2 个答案:

答案 0 :(得分:1)

我不确定,为什么在您的cleanupSpec之前关闭浏览器。可能已经有其他机制解决了这个问题。

然而,您在cleanupSpec中获得了另一个实例这一事实完全是由于getBrowser被实现为惰性获取器这一事实。如您在code中所见,它将在必要时创建一个新实例。

通常,您不需要使用Geb呼叫browser.quit。 Geb会很好地解决这个问题。

更新

这是GebSpecYourSpec中发生的事情:

  1. GebSpec.setupSpec被触发⇒_browsernull
  2. YourSpec.setupSpec被触发⇒_browser仍为null,除非您在此处使用它
  3. GebSpec.setup被触发⇒_browser不变
  4. YourSpec.setup被触发⇒_browser可能被更改
  5. YouSpec的第一个功能被触发⇒使用了_browser,因此不再是null
  6. YourSpec.cleanup被触发⇒_browser不变
  7. GebSpec.cleanup被触发⇒ _browser被设置为null如您在code中所见,resetBrowser是除非YourSpec@Stepwise且已将_browser设置为null,如您所见here,否则将被调用。
  8. YourSpec.cleanupSpec被触发⇒_browsernull 除非您使用它,否则它将重新初始化
  9. GebSpec.cleanupSpec被触发⇒_browser仍为null

答案 1 :(得分:0)

这很奇怪,因为您看到浏览器已重新初始化以进行清理,所显示的内容是正确的。

对于第1点:您正在gebconfig中正确设置它。

对于第2点:您无需在setupSpec()中初始化浏览器,只需配置条目即可。

运行所有测试后,浏览器应自动关闭,除非您将以下内容添加到gebconfig中并设置为false:

quitCachedDriverOnShutdown = false 
在运行规范中的所有方法之后,将调用

setupSpec()。您显示给我们的是您规范中唯一的代码吗?您的规范是扩展GebSpec还是GebReportingSpec还是自定义基类?

我能想到的另一件事是,您在该规范中有2个测试,因此您两次看到“ Created driver”(创建的驱动程序),并且在运行所有测试之后将调用cleanUpSpec(),因此您会看到在结束。如果您调用了cleanup(),它将在每个测试之间运行。