Найти результат / статус теста в Specification.cleanup () - PullRequest
0 голосов
/ 03 июня 2018

Кажется разумным, что нужно сделать ... например, регистрировать что-то, когда тест не пройден, а не если он не делает.

Я нашел это , дляНапример, с 2013 года ... в то время не было ни простых, ни эффективных ответов.А теперь?

Я надеялся, что подходящее свойство / метод может быть найдено в org.spockframework.runtime.SpecificationContext ... или, может быть, org.spockframework.runtime.model.SpecInfo ... но я ничего не вижу.

позже

Чтобы ответить на вопрос о том, что я хотел бы сделать: на самом деле мой Specification s "угон" System.out (используя PrintStream), чтобы я могзахватить вывод до System.out и затем проанализировать его.NB для записи, я знаю, что пуристы Спока могут не одобрить тесты, заинтересованные в выводе терминала, но я не такой пурист, особенно когда говорю о тестах, отличных от модульных тестов.

Получив этовыводить таким образом, что это означает, что он не выводится нигде, нет причин систематически регистрировать его и загромождать файл журнала ... но если тест не пройден, я хочу это сделать.То же самое потенциально для System.err ...

1 Ответ

0 голосов
/ 04 июня 2018

Прежде всего, регистрация неудачных тестов - это задача вашей тестовой платформы (JUnit, Spock).Поэтому неудивительно, что сам статус теста не доступен из самого теста.В любом случае, если вам нужно что-то более необычное в Споке, принятый ответ , а также Петровский ответ в другом потоке все еще действителен.Нет более простого способа узнать, провалился ли тест по методу cleanup().

В любом случае, он не так сложен, как кажется, потому что вы настраиваете его только один раз, а потом он просто работает.,Поскольку вы не упомянули, что именно вы хотите войти в систему cleanup(), я собираюсь немного поразмышлять.В демонстрационных целях я просто регистрирую имя метода объекта, полученное из контекста спецификации, и класс возникшей ошибки (чтобы не печатать полное причудливое сообщение об ошибке Спока дважды), полученное из прослушивателя прогона, зарегистрированногоГлобальное расширение, которое я собираюсь представить здесь.

Глобальное расширение Spock:

Расширение регистрирует прослушиватель запуска, который записывает информацию об ошибке всякий раз, когда возникает ошибка теста.В начале каждого объекта или итерации (для объектов с where: блоками) последняя записанная ошибка очищается, чтобы не переходить в следующий объект / итерацию.

package de.scrum_master.stackoverflow

import org.spockframework.runtime.AbstractRunListener
import org.spockframework.runtime.extension.AbstractGlobalExtension
import org.spockframework.runtime.model.ErrorInfo
import org.spockframework.runtime.model.FeatureInfo
import org.spockframework.runtime.model.IterationInfo
import org.spockframework.runtime.model.SpecInfo

class MyGlobalExtension extends AbstractGlobalExtension {
  @Override
  void visitSpec(SpecInfo spec) {
    spec.addListener(new ErrorListener())
  }

  static class ErrorListener extends AbstractRunListener {
    ErrorInfo errorInfo

    @Override
    void beforeFeature(FeatureInfo feature) {
      errorInfo = null
    }

    @Override
    void beforeIteration(IterationInfo iteration) {
      errorInfo = null
    }

    @Override
    void error(ErrorInfo error) {
      errorInfo = error
    }
  }
}

Как зарегистрироватьсярасширение Spock:

Вам также необходимо добавить файл META-INF/services/org.spockframework.runtime.extension.IGlobalExtension в ресурсы teast, чтобы зарегистрировать расширение.Файл просто имеет следующее содержимое:

de.scrum_master.stackoverflow.MyGlobalExtension

Кстати, это не спок или Groovy, а стандартная функция Java SE, называемая провайдерами услуг .

Пример теста с использованием расширения:

Этот тест довольно глуп, но показывает, как он работает для обычных методов и методов с where: блоками как с @Unroll.

package de.scrum_master.stackoverflow

import spock.lang.Specification
import spock.lang.Unroll

class TestFailureReportingTest extends Specification {

  def cleanup() {
    specificationContext.currentSpec.listeners
      .findAll { it instanceof MyGlobalExtension.ErrorListener }
      .each {
        def errorInfo = (it as MyGlobalExtension.ErrorListener).errorInfo
        if (errorInfo)
          println "Test failure in feature '${specificationContext.currentFeature.name}', " +
            "exception class ${errorInfo.exception.class.simpleName}"
        else
          println "Test passed in feature '${specificationContext.currentFeature.name}'"
      }
  }

  def normalFeature() {
    expect:
    0 == 1
  }

  def parametrisedFeature() {
    expect:
    a == b

    where:
    a | b
    2 | 3
    4 | 5
    6 | 6
  }

  @Unroll
  def unrolledParametrisedFeature() {
    expect:
    a == b

    where:
    a | b
    6 | 7
    8 | 9
    0 | 0
  }
}

PS: информация об ошибке не доступна еще в блоке cleanup: внутри метода объекта, потому что расширение включается только после завершения всего объекта / итерации, включая этот блок.Таким образом, вам действительно нужно использовать метод cleanup(), но вы все равно хотели это, и это позволит избежать дублирования кода.

PPS: Конечно, вы также можете просто сделать общее ведение журнала из перехватчика метода и пропустить весь cleanup() метод.Но тогда вы больше не сможете сделать свой вывод журнала специфичным для теста, и он будет там для всех ваших тестов, а не только для того, который вы выберете - если, конечно, вы не жестко запрограммируете правильный фильтр имени пакета или спецификациив перехватчик или убедитесь, что перехватчик читает соответствующий файл конфигурации при запуске Spock.

...