ScalaCheck не дает сбоев?

Я пытаюсь использовать ScalaTest со ScalaCheck для тестирования на основе свойств. У меня есть тесты, описанные ниже:

import org.scalatest.prop.PropertyChecks
import org.scalatest.{FlatSpec, Matchers}


object Calc {
  def add(a:Int, b:Int) = a+b

  def div(a:Int, b:Int) = a/b
}


class PropSpec1 extends FlatSpec with Matchers with PropertyChecks {
  behavior of Calc.getClass.getName


  it should "add integers" in {
    forAll { (a: Int, b: Int) =>
      Calc.add(a, b) shouldEqual a + b
    }
  }

  it should "divide integers" in {
    forAll {
      (a:Int, b:Int) => Calc.div(a, b) shouldEqual a/b
    }
  }
}

Теперь я вижу, что если я продолжаю запускать тесты в PropSpec1 снова и снова, иногда второй тест проходит успешно, но в большинстве случаев он терпит неудачу. Теперь, если 0 не проверяется на b, то, очевидно, он пройдет, но я бы подумал, что это одна из вещей, которую он будет пытаться делать всегда. Я вижу такое же поведение при повторном запуске sbt clean test; иногда оба теста проходят.

Это нормально для тестирования на основе свойств, или мне нужно что-то делать (например, всегда предоставлять свой собственный генератор)?


person ashic    schedule 25.01.2017    source источник


Ответы (1)


но я бы подумал, что это одна из вещей, которые он всегда будет пытаться

Предположения — корень всех зол.

По сути, все, что вы попросили Scalacheck сгенерировать для вас, это образец Int. Действительный Int может быть одним из ~ 4 миллиардов значений.

Поскольку вы знаете, что 0 приведет к сбою этой функции (выдается исключение), вы можете просто отфильтровать его следующим образом:

forAll { (a:Int, b:Int) =>
  whenever(a != 0 && b != 0) {
    Calc.div(a, b) mustEqual a/b
  }
}

P.S. Если вы проверите scaladoc для функции whenever, там будет пример, аналогичный тому, что вы просили здесь.

person goralph    schedule 25.01.2017
comment
Спасибо... Я знаю про всякий раз. Я больше заинтересован в том, чтобы заставить его попробовать пограничные случаи или, по крайней мере, сказать ему не забыть попробовать 0 (что в данном случае не имеет смысла, но является более общей проблемой). Есть что-то для этого? - person ashic; 25.01.2017
comment
Насколько мне известно, вам нужно будет предоставить собственный генератор. Может есть другой способ, может кто подскажет. - person goralph; 25.01.2017