ScalaCheck is a tool for testing Scala and Java programs, based on property specifications and

automatic test data generation. The basic idea is that you define a property that specifies the

behaviour of a method or some unit of code, and ScalaCheck checks that the property holds.

All test data are generated automatically in a random fashion, so you don't have to worry about

any missed cases.

In this tutorial, we explain the basics of ScalaCheck, how it works and several interesting

use-cases. You can learn more about it at https://github.com/rickynils/scalacheck/wiki/User-Guide.

- Download and install Eclipse Indigo (3.7): http://www.eclipse.org/indigo/
- Download and install Scala IDE for version 2.9.x: http://scala-ide.org/download/current.html
- Download the ScalaCheck 1.10.0 testing library: https://oss.sonatype.org/index.html#nexus-search;quick~scalacheck_2.9.2

We first do the following preparatory steps.

- Create a new Scala project in Eclipse.
- Create a folder
`lib`

. - Copy the ScalaCheck 1.10.0 JAR file into the
`lib`

folder. - Go to Project -> Properties -> Java Build Path -> Add JARs and select the ScalaCheck JAR from the
`lib`

folder. - Create a source folder
`src/test/scala`

. - Create a new package
`pp.scalacheck`

in the source folder above. - Create a new file
`StringSpecification.scala`

in the package above.

Alternatively, you can download the entire project from: http://github.com/axel22/scalacheck-tutorial

`String`

sWe will now write a few ScalaCheck tests that test certain `String`

properties.

We import the contents of the ScalaCheck package and its `forAll`

statement:

```
package pp.scalacheck
import org.scalacheck._
import Prop.forAll
```

Next, we define an object `StringSpecification`

which will contain multiple properties

of `String`

s. The first such property will test that the concatenation of two strings`x`

and `y`

always starts with the string `x`

.

```
object StringSpecification extends Properties("String") {
property("startsWith") = forAll { (x: String, y: String) =>
(x + y).startsWith(x)
}
// ... more properties will follow ...
}
```

We defined the property named `"startsWith"`

saying that

it must be true that for all `String`

s `x`

and `y`

their concatenation is

starts with `x`

.

Each `Properties`

object is a complete application in ScalaCheck - it has a `main`

method defined, which simply tests all the properties.

This means that we can run it in Eclipse, so lets do exactly that.

We click Run -> Run As -> Scala Application to obtain the following output:

```
+ String.startsWith: OK, passed 100 tests.
```

We get an output saying that ScalaCheck generated `100`

different `String`

s

and that our property was true for all of them.

Lets write another property. This one states that the length of then concatenation of

two `String`

s is always longer than one of those `String`

s.

```
property("concatenation length") = forAll { (x: String, y: String) =>
x.length < (x + y).length
}
```

Running the test suite again we get:

```
! String.concatenation length: Falsified after 0 passed tests.
> ARG_0: ""
> ARG_1: ""
```

Ooops! ScalaCheck is telling us that this seemingly simple property of `String`

s

isn't true at all. In fact, it even produces a small counterexample -- what if we

have 2 empty `String`

s? In that case our property does not hold.

Let lets fix it to state that the concatenation is longer or equal to one of the

two `String`

s:

```
property("concatenation length") = forAll { (x: String, y: String) =>
x.length <= (x + y).length
}
```

Running the tests now yields:

```
+ String.startsWith: OK, passed 100 tests.
+ String.concatenation length: OK, passed 100 tests.
```

You can try writing a couple of your own properties.

Automatic generation of input data is particularly useful for testing collections,

so lets write a couple of collection properties.

We create a new file in `pp.scalacheck`

called `ListSpecification.scala`

and write

the following property saying that reversing a list twice gives back the original

list:

```
object ListSpecification extends Properties("List") {
property("double reverse") = forAll { (lst: List[Int]) =>
lst.reverse.reverse == lst
}
}
```

ScalaCheck is smart enough to know how the generate arbitrary lists of

integers for us. Running the tests yields:

```
+ List.double reverse: OK, passed 100 tests.
```

Lets write another property involving lists, stating that reversing two lists

and zipping them is the same as first zipping them and then reversing the

resulting list of pairs (for example, for `1 :: 2 :: Nil`

and `2 :: 4 :: Nil`

we get `(2, 4) :: (1, 2) :: Nil`

).

```
property("zip reverse") = forAll { (a: List[Int], b: List[Int]) =>
(a.reverse zip b.reverse) == (a zip b).reverse
}
```

It's not apparent at first sight that this property does not always hold:

```
! List.zip reverse: Falsified after 3 passed tests.
> ARG_0: List("0")
> ARG_1: List("-1", "0")
```

In fact, the property always fails when the lists don't have the same length.

We can fix the property by ensuring that both lists do have the same length:

```
property("zip reverse") = forAll { (a: List[Int], b: List[Int]) =>
val a1 = a.take(b.length)
val b1 = b.take(a.length)
(a1.reverse zip b1.reverse) == (a1 zip b1).reverse
}
```

ScalaCheck can test the properties of other collections as well. For example,

the following property of `Map`

s says that after you add a key-value pair to

any `Map`

, the size of the resulting map will increase:

```
property("+ and size") = forAll { (m: Map[Int, Int], key: Int, value: Int) =>
(m + (key -> value)).size == (m.size + 1)
}
```

Try to find a counterexample. Then use ScalaCheck to find check if your

counterexample is similar.

We've seen so far that ScalaCheck is pretty smart in practice with generating the

right data that can lead to counterexamples.

However, ScalaCheck cannot by default generate input data for datatypes it does not

know about.

For example, lets define a custom datatype called `Vector`

which describes two-dimensional

mathematical vectors. We also define 2 operations -- scalar multiplication and vector length.

```
case class Vector(x: Int, y: Int) {
def *(s: Int) = Vector(x * s, y * s)
def length: Double = math.sqrt(x * x + y * y)
}
```

Lets try to write a property involving this vector, for example, one that says that

if we multiply a vector with a scalar larger than `1.0`

, its length will increase.

Otherwise, its length will decrease.

```
property("* and length") = forAll { (v: Vector, s: Int) =>
if (s >= 1.0) (v * s).length >= v.length
else (v * s).length < v.length
}
```

The snippet above does not compile -- instead it produces some strange error message

about not finding an implicit value:

```
- could not find implicit value for parameter a1:
org.scalacheck.Arbitrary[pp.scalacheck.VectorSpecification.Vector]
```

What the compiler is trying to tell us here is that the ScalaCheck library knows nothing

about our user-defined `Vector`

datatype, so it can't generate input examples for it.

This is where ScalaCheck generators come into play.

A generator (`Gen`

) is an object which describes how input data is generated for

a certain type.

ScalaCheck comes with a range of predefined generators for basic datatypes.

For example, the generator `Arbitrary.arbitrary[Double]`

generates arbitrary real numbers:

```
val doubles = Arbitrary.arbitrary[Double]
```

The generator `Gen.oneOf`

generates the specified values, in the example below `true`

or `false`

:

```
val booleans = Gen.oneOf(true, false)
```

Another predefined generator `Gen.choose`

picks integer numbers within a given range:

```
val twodigits = Gen.choose(-100, 100)
```

How to use a generator in a property? We simply have to specify it after the `forAll`

:

```
property("sqrt") = forAll(ints) { d =>
math.sqrt(d * d) == d
}
```

Btw, the above property is not always true. Try to figure out a counterexample.

Finally, several basic generators can be combined into more complex generators,

and this is a recommended strategy to obtain generators for more custom datatypes.

This is done using for-comprehensions which you already saw on collections:

```
val vectors: Gen[Vector] =
for {
x <- Gen.choose(-100, 100)
y <- Gen.choose(-100, 100)
} yield Vector(x, y)
```

The above should be read as -- we define a generators called `vectors`

which generates`Vector`

s as follows: use a generator `choose`

to generate a value `x`

in the range from`-100`

to `100`

, and another generator `choose`

to generate a value `y`

in the same range,

then use these values to create `Vector(x, y)`

.

This (intuitive) for-comprehension is translated into a chain of (unintuitive) `map`

/`flatMap`

calls. Try to figure out what the desugared expression looks like!

Now that we have the generator for vectors, we can use it:

```
property("* and length") = forAll(vectors, ints) { (v: Vector, s: Int) =>
if (s >= 1.0) (v * s).length >= v.length
else (v * s).length < v.length
}
```

Alas, our property still fails because `s`

might be negative. Fix it to use only

positive scalars!

We conclude this short tutorial by showing how you can write an even more complex

generator. Lets create a custom datatype for binary trees of integers:

```
trait Tree
case class Node(left: Tree, right: Tree) extends Tree
case class Leaf(x: Int) extends Tree
val ints = Gen.choose(-100, 100)
def leafs: Gen[Leaf] = for {
x <- ints
} yield Leaf(x)
def nodes: Gen[Node] = for {
left <- trees
right <- trees
} yield Node(left, right)
def trees: Gen[Tree] = Gen.oneOf(leafs, nodes)
```

Just like the tree datatype, its generator consists of several cases and is mutually recursive.

Try to figure out how it works.

Then define a method `depth`

on `Tree`

s which returns the depth of the tree.

Write a ScalaCheck test to verify if for any two trees `x`

and `y`

, the tree`Node(x, y)`

is deeper than both `x`

and `y`

.