ScalaTest — как использовать forEvery без печати всей коллекции?

Есть ли способ использовать инспектор ScalaTest forEvery без печати всей коллекции при каждом сбое теста? Коллекция, на которой я пытаюсь запустить тест, довольно велика (более тысячи элементов), и мне не очень интересно видеть ее содержимое в журналах тестирования, особенно если оскорбительная строка текста уже напечатана в собранной ошибке. Сообщения. Наличие шести тестов, использующих эту коллекцию, также не помогает.


person AlexBG    schedule 05.10.2014    source источник


Ответы (2)


Просто используйте forAll вместо forEvery.

Из документов:

  • forAll — успешно, если утверждение верно для каждого элемента
  • forEvery - то же, что и forAll, но перечисляет все неисправные элементы, если он не работает (тогда как forAll просто сообщает о первом неисправном элементе)
person alno    schedule 05.10.2014
comment
Список всех неисправных элементов — это именно то, что я хочу, иначе было бы достаточно простого foreach. Чего я не хочу, так это печатать всю коллекцию под элементами, не прошедшими тест. - person AlexBG; 05.10.2014
comment
В настоящее время нет способа предотвратить это. Это в конце, так что вы можете игнорировать его, если вам все равно. Можете ли вы объяснить, как трудно игнорировать? Нужно ли прокручивать его в стандартном выводе репортера? - person Bill Venners; 05.10.2014
comment
Как я уже сказал, коллекция, с которой я провожу тесты, огромна. Это более тысячи элементов, возможно, около 2 тысяч. Меня не волнуют несколько экранов текста, и это только в том случае, если один из тестов не пройден. Все становится только хуже, если есть более чем один сбой. Я уже нашел уродливое решение, и, к сожалению, кажется, что нет разумного способа отфильтровать текст. Я собираюсь опубликовать это через несколько часов, когда у меня будет доступ к моему ноутбуку. - person AlexBG; 06.10.2014

Итак, решение, которое я нашел, действительно уродливое и хакерское. Принцип работы forEvery (и, как я подозреваю, других инспекторов) заключается в том, что они пытаются получить итератор вашей коллекции, если могут, как для запуска тестов, так и для распечатки вашей коллекции. Мое решение передает правильный итератор только при первом запуске, и если инспектор снова пытается захватить итератор (что он делает только для вывода коллекции), он получает Seq.empty.iterator. Лучшее, что можно сказать об этом коде, это то, что он работает:

def forEvery[E](xs: TraversableOnce[E])(fun: E => Unit): Unit = {
  class SilentSeq[E](list: TraversableOnce[E]) extends Seq[E] {
    var silent: Boolean = false
    def length = 0
    def apply(i: Int) = list.toIterator.next()
    def iterator = {
      if (silent)
        Seq.empty.iterator
      else {
        silent = true
        list.toIterator
      }
    }
  }

  Inspectors.forEvery[E, Seq](new SilentSeq(xs))(fun)
}

Инспектор не использует ни длину, ни применение, поэтому все, что я туда добавляю, не имеет значения, если оно имеет правильный тип. Расширение Seq — это едва ли не самый простой способ, который я нашел, чтобы притвориться GenTraversable (что необходимо для использования итератора моего собственного класса). Я был бы рад найти любое решение, которое лучше, чем это.

person AlexBG    schedule 06.10.2014