Troubleshooting

This section presents some of the common pitfalls you might face when using specs2 and Scala

vals vs lazy vals

The common symptom here is a NullPointerException for some attributes of your specification. You can refer to this link for an explanation of variable initialization in Scala. In the meantime the basic fix is to use a lazy val instead of a val.

Lost expectations

You might expect the following specification to fail:

class ShouldItFail extends Specification { def is = s2"""
  Should this example fail? $e1
"""
  def e1 = {
    1 must_== 100000 // do you expect this to fail
    10 must_== 10
  }
}

However, as explained in Structure - Thrown expectations, the first expectation is lost because, by default, no exceptions are thrown in an acceptance specification. In that case you can either:

No evidence parameter for AsResult

Here is a mysterious AsResult message

class MysteriousAsResult extends mutable.Specification {
  "Try this" in {
    1 must_== 1
    println("this is ok, right?")
  }
}

[error] could not find implicit value for evidence parameter of type org.specs2.execute.AsResult[Unit]

What’s happening? Each example must return a value of type T where T has an AsResult instance. This is the case if T is a Boolean, a MatchResult, a ScalaCheck Prop etc… (see AsResult typeclass). In the class above the return value is Unit which doesn’t have an AsResult instance.

To fix this you can either:

implicit def unitAsResult: AsResult[Unit] = new AsResult[Unit] {
  def asResult(r: =>Unit) =
    ResultExecution.execute(r)(_ => Success())
}

Type mismatch

This is also a tricky one, showing the limitations of embedding a pseudo-natural language into a programming language:

class Inference extends mutable.Specification {
  "It doesn't mean what you think it does" >> {
    List(1, 2, 3) must not beNull
    List(1, 2) must have size(2)
  }
}

[error] type mismatch;
[error]  found   : List[Int]
[error]  required: org.specs2.matcher.Matcher[List[Int]]
[error]     List(1, 2) must have size(2)
[error]         ^

The first statement is parsed as issue.must(not).beNull as if beNull was a method expecting an argument on the next line (this is well explained in this StackOverflow question).

The possible fixes are:

Yrangepos

The Yrangepos scalac option (see Quick Start) is necessary to get proper Fragment locations when using s2 interpolated strings. However this option sometimes breaks some macros with messages like [info] Unpositioned tree #931. In that case you should remove that option from your build. You will still be able to use s2 interpolation strings but fragment locations will be less precise.

Custom output

You created a custom Notifier or another class for reporting and when you use it nothing happens. In that case add the verbose argument to the command line and you will get more messages including exceptions and stacktraces about what is going on.