1

I'm trying to use ScalaTest with ScalaCheck to do property based testing. I've got the tests outlined below:

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
    }
  }
}

Now what I'm seeing is that if I keep running the tests in PropSpec1 over and over, sometimes the second test passes, but most of the time it fails. Now, if 0 isn't tested for b, then obviously it'll pass, but I'd have thought that's one of the things it would always try. I see the same behaviour when running sbt clean test repeatedly; sometimes both tests pass.

Is this normal for property based testing, or is there something I need to do (like always providing my own generator)?

ashic
  • 6,367
  • 5
  • 33
  • 54

1 Answers1

0

but I'd have thought that's one of the things it would always try

Assumptions are the root of all evil.

Basically, all you've asked Scalacheck to generate for you is a sample of Int's. A valid Int can be one of ~4 billion values.

Since you know that a 0 will case a failure of this function (an Exception gets thrown) you can simply filter it out like so:

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

P.S If you check the scaladoc for the whenever function there is a similar example to what you've asked here.

goralph
  • 1,076
  • 9
  • 18
  • Thanks... I know about whenever. I'm more interested in forcing it to try edge cases, or at least telling it to remember to try 0 (which doesn't make sense in this case, but is a more general issue). Is there something for that? – ashic Jan 25 '17 at 18:40
  • To my knowledge you'd have to provide a custom generator. There might be some other way, maybe someone else will chime in. – goralph Jan 25 '17 at 18:44