【问题标题】:How to Report Results to Sauce Labs using Geb/Spock?如何使用 Geb/Spock 向 Sauce Labs 报告结果?
【发布时间】:2023-03-25 01:59:01
【问题描述】:

我想使用 Sauce Labs Java REST API 将通过/失败状态发送回 Sauce Labs 仪表板。我正在使用 Geb+Spock,我的 Gradle 构建创建了一个测试结果目录,结果以 XML 格式输出。我的问题是,在 Spock 规范的 cleanupSpec() 退出 after 之前,似乎不会生成结果 XML 文件。这导致我的代码报告上一次测试运行的结果,而不是当前的。显然不是我想要的!

有什么方法可以在不依赖 XML 的情况下从 cleanupSpec() 中获取结果?或者一种让结果更早归档的方法?还是有比这两种方法更好的替代方法?

一些代码:

在build.gradle 中,我指定testResultsDir。这是在 Spock 规范退出后写入 XML 文件的地方:

drivers.each { driver ->
    task "${driver}Test"(type: Test) {
        cleanTest
        systemProperty "geb.env", driver    
        testResultsDir = file("$buildDir/test-results/${driver}")
        systemProperty "proj.test.resultsDir", testResultsDir
    }
}

这是我的 LoginSpec 类中的 setupSpec() 和 cleanupSpec():

class LoginSpec extends GebSpec {
    @Shared def SauceREST client = new SauceREST("redactedName", "redactedKey")
    @Shared def sauceJobID
    @Shared def allSpecsPass = true

    def setupSpec() {
        sauceJobID = driver.getSessionId().toString()
    }

    def cleanupSpec() {
        def String specResultsDir = System.getProperty("proj.test.resultsDir") ?: "./build/test-results"
        def String specResultsFile = this.getClass().getName()
        def String specResultsXML = "${specResultsDir}/TEST-${specResultsFile}.xml"
        def testsuiteResults = new XmlSlurper().parse( new File( specResultsXML ))

        // read error and failure counts from the XML       
        def errors = testsuiteResults.@errors.text()?.toInteger()
        def failures = testsuiteResults.@failures.text()?.toInteger()

        if ( (errors + failures) > 0 ) { allSpecsPass = false }

        if ( allSpecsPass ) {
            client.jobPassed(sauceJobID)
        } else {
            client.jobFailed(sauceJobID)
        }
    }
}

该类的其余部分包含不与 SauceLabs 交互的登录规范。当我阅读 XML 时,发现它是在上一次 LoginSpec 运行结束时编写的。我需要一种方法来获取当前运行的值。

谢谢!

【问题讨论】:

  • 你能提供一些你的源代码吗?请将其包含在您的问题中。
  • 感谢您查看问题,加勒特!

标签: groovy automation spock geb saucelabs


【解决方案1】:

测试报告是在规范完成执行后生成的,并且生成是由构建系统执行的,在你的例子中是 Gradle。 Spock 对此一无所知,因此您无法从测试中获取该信息。

另一方面,您可以很容易地从 Gradle 获取这些信息。测试任务有两种您可能感兴趣的方法:addTestListener() 和 afterSuite()。似乎这里更清洁的解决方案是使用第一种方法,实现一个测试侦听器并将您的逻辑放在侦听器的afterSuite() 中(而不是任务配置)。您可能需要将该侦听器实现放在buildSrc 中,因为看起来您依赖于 SauceREST,并且您需要构建和编译您的侦听器类,然后才能将其用作 addTestListener() 的参数。你的项目的gradle。

【讨论】:

  • 感谢您的回应,@erdi。我将开始研究 addTestListener() 选项,并告诉你它是怎么回事。
  • 我按照 erdi 的建议创建了一个自定义测试侦听器来报告我的 SauceLabs 结果。我在收到 Ross Rowe 非常出色的代码解决方案之前就这样做了,所以我将把 erdi 的答案标记为一个。谢谢你,尔迪!
【解决方案2】:

根据erdi 的建议,我创建了一个Sauce Gradle helper 库,它提供了一个测试侦听器,用于解析测试XML 输出并调用Sauce REST API 来设置通过/失败状态。

可以通过将以下内容添加到您的 build.gradle 文件来包含该库:

import com.saucelabs.gradle.SauceListener

buildscript {
  repositories {
    mavenCentral()
    maven {
        url "https://repository-saucelabs.forge.cloudbees.com/release"
    }
  }
  dependencies {
    classpath group: 'com.saucelabs', name: 'saucerest', version: '1.0.2'
    classpath group: 'com.saucelabs', name: 'sauce_java_common', version: '1.0.14'
    classpath group: 'com.saucelabs.gradle', name: 'sauce-gradle-plugin', version: '0.0.1'
  }
}

gradle.addListener(new SauceListener("YOUR_SAUCE_USERNAME", "YOUR_SAUCE_ACCESS_KEY"))

您还需要为每个测试输出 Selenium 会话 ID,以便 SauceListener 可以将 Sauce Job 与通过/失败状态相关联。为此,请在标准输出中包含以下输出:

SauceOnDemandSessionID=SELENIUM_SESSION_ID

【讨论】:

  • 罗斯·罗,哇!这是一个极好的贡献。我的实现类似(甚至命名为“SauceListener!”),但不如您的代码优雅或健壮。通过查看您的代码,我学到了很多东西,我敢打赌,很多人都会感谢帮助程序库。我没有投票的积分,但是当我这样做时,我会回来投票。谢谢!
猜你喜欢
  • 2017-01-24
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 2015-09-22
  • 1970-01-01
  • 2014-10-02
相关资源
最近更新 更多