Как сообщить о результатах в Sauce Labs, используя Geb/Spock?

Я хочу использовать Java REST API Sauce Labs для отправки статуса Pass/Fail обратно на панель управления SauceLabs. Я использую Geb+Spock, и моя сборка Gradle создает каталог результатов теста, где результаты выводятся в формате XML. Моя проблема в том, что XML-файл результатов не создается, пока не завершится очистка спецификации SpockSpec(). Это заставляет мой код сообщать о результатах предыдущего теста, а не о текущем. Ясно не то, что я хочу!

Есть ли способ получить результаты изнутри cleanupSpec(), не полагаясь на XML? Или способ получить результаты в файл ранее? Или какая-то альтернатива, которая будет намного лучше, чем любая из них?

Некоторый код:

В build.gradle Я указываю testResultsDir, Вот где XML-файл записывается после выхода спецификации Spock:

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

Здесь setupSpec() а также cleanupSpec() в моем классе LoginSpec:

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. Мне нужен способ добраться до значений текущего прогона.

Спасибо!

2 ответа

Решение

Отчеты о тестах генерируются после того, как спецификация закончила выполнение, а генерация выполняется системой сборки, как в вашем случае Gradle. Спок не знает об этом, поэтому вы не можете получить эту информацию из теста.

С другой стороны, вы можете легко получить эту информацию от Gradle. Тестовое задание имеет два метода, которые могут вас заинтересовать: addTestListener() и afterSuite(). Кажется, что более чистым решением здесь было бы использовать первый метод, реализовать тестовый слушатель и поместить вашу логику в afterSuite() слушателя (а не в конфигурацию задачи). Возможно, вам потребуется поместить эту реализацию слушателя в buildSrc, так как похоже, что у вас есть зависимость от SauceREST, и вам нужно будет собрать и скомпилировать свой класс слушателя, прежде чем использовать его в качестве аргумента для addTestListener() в build.gradle ваш проект.

Следуя предложению erdi, я создал вспомогательную библиотеку Sauce Gradle, которая предоставляет erdi тестов, который анализирует выходные данные теста XML и вызывает API-интерфейс REST Sauce для установки статуса "пройти / не пройти".

Библиотеку можно включить, добавив в файл 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 для каждого теста, чтобы SauceListener мог связать задание Sauce со статусом прохождения / сбоя. Для этого включите следующий вывод в стандартный вывод:

SauceOnDemandSessionID=SELENIUM_SESSION_ID
Другие вопросы по тегам