Selenium Grid 总是执行不需要的额外测试实例

Selenium Grid always executes an unwanted extra instance of my test

背景

我设置了一个 Selenium Grid 项目以在两个不同的浏览器 Chrome 和 Firefox 中执行我的测试。我正在使用 Gradle 来执行我的测试。测试将成功执行两次,一次在 Chrome 中,一次在 Firefox 中,正如预期的那样,然后第三个实例将在默认浏览器中执行并失败。

预期结果

  1. 一个 Chrome 实例将打开,规范将 运行,它会通过。
  2. 一个 Firefox 实例(使用 geckodriver)将打开,规范将 运行,它会通过。
  3. Gradle 任务将成功完成。

实际结果

  1. 一个 Chrome 实例将打开,规范将 运行,它会通过。
  2. 一个 Firefox 实例(使用 geckodriver)将打开,规范将 运行,它会通过。
  3. 一个新的 Firefox 实例(使用 firefoxdriver)将打开,规范不会 运行,并且会失败。
  4. Gradle 任务将失败,因为最后一次测试执行失败。

我的想法

代码

我在 Bitbucket 上创建了一个重现此问题的示例项目。关于如何 运行 示例测试的说明包含在自述文件中。

作为一个片段,这是我的示例规范:

class W3SchoolsFormExampleSpec extends Specification {

    def 'Test form submission is successful on W3Schools'() {
        when: 'Name info is submitted into the form'
            open('https://www.w3schools.com/html/html_forms.asp')

            $(byName('firstname')).setValue('Clark')
            $(byName('lastname')).setValue('Kent')

            $x('//*[@id="main"]/div[3]/div/form/input[3]').click()

        and: 'Switch to newly opened tab'
            switchTo().window(1)

        then: 'New page should display the passed-in request params'
            $x('/html/body/div[1]').shouldHave(text('firstname=Clark&lastname=Kent'))
    }
}

这是我的 build.gradle 文件的片段:

test {
    // Prevent Gradle from strangely executing Spock tests twice
    actions = []
}

task testW3SchoolsForm(type: Test) {
    outputs.upToDateWhen { false }

    doFirst {
        // Check to see that the Selenium drivers are installed
        if (!file("C:/Selenium/chromedriver.exe").exists()) {
            throw new GradleException(
                    'ERROR: Please install the web drivers in the correct location.'
            )
        }

        // Register the hub
        GridLauncherV3.main('-role', 'hub')

        // Register the Chrome and Firefox nodes
        GridLauncherV3.main('-role', 'node',
                '-browser', 'broswerName=chrome,platform=WINDOWS',
                '-hub', 'http://localhost:4444/grid/register',
                '-port', '4446'
        )
        GridLauncherV3.main('-role', 'node',
                '-browser', 'broswerName=firefox,platform=WINDOWS',
                '-hub', 'http://localhost:4444/grid/register',
                '-port', '4446'
        )
    }
}

enum BrowserType {
    CHROME('chrome'),
    FIREFOX('gecko')

    def browserString

    BrowserType(browserString) {
        this.browserString = browserString
    }
}

BrowserType.values().each { browserType ->
    tasks.create("testW3SchoolsForm${browserType}", Test) {
        // Force the tests to run every time
        outputs.upToDateWhen { false }

        // Allow parallel execution
        maxParallelForks = 3
        forkEvery = 0

        def drivers = [
                (BrowserType.CHROME): 'chromedriver.exe',
                (BrowserType.FIREFOX): 'geckodriver.exe'
        ]

        def browserProperty = browserType.browserString
        def webdriverPath = file("C:/Selenium/${drivers[browserType]}")

        // Set the respective system properties for each browser
        systemProperties["webdriver.${browserProperty}.driver" as String] = webdriverPath
        systemProperties['selenide.browser'] = browserType.browserString

        filter {
            include 'com/example/dummy/W3SchoolsFormExampleSpec.class'
        }

        testLogging {
            events 'PASSED', 'FAILED', 'STARTED', 'SKIPPED'
        }

        testW3SchoolsForm.dependsOn "testW3SchoolsForm${browserType}"
    }
}

关于为什么我的测试的第三个实例会在默认的 Selenium 浏览器中执行的任何想法?

经过几天的反复试验并通过在 Gradle forums 上发帖找到解决方案,我找出了原因,这可能对未来的读者有所帮助。

创建自定义 Test 任务时要小心。

默认情况下,应用 JavaGroovy 插件将自动创建一个默认 Test 任务,该任务会在您的 test 源目录下执行所有测试。

当您通过执行以下操作创建自定义测试任务时:

task testABC(type: Test) {
    filter {
        include "ABCTest"
    }
}

...执行这个测试任务也会执行默认的test任务。如果您希望禁用默认 test 任务的执行,请设置 test.enabled = false.