In specs2, conditionally executing subtests on result returned from function that may throw exceptions
bdd, scala, specs2, testing
Solution
One possibility is to use a condition as in @alexwriteshere answer:
"parent test" in {
val thing: Option[Thing] = maybeGiveMeAThing("foo", "bar" "baz")
thing match {
case Some(thing) =>
"child test 1" in ok
"child test 2" in ok
case None =>
"skipped tests" in skipped
}
}
However you need to add an `Example` in the `None` case so that the block of the `in` method has an acceptable type.
The big drawback with this approach though is that the specification is being executed while being defined. This means that:
- if there's an exception with the `maybeGiveMeAThing` then the whole specification will blow up
- if you choose to exclude the examples using the `thing`, you will still have it being built
Another option is to use a `Step` saying that any previous failure will skip all the next examples:
class MySpec extends mutable.Specification {
"This is a test with a thing" >> {
lazy val thing: Option[Thing] = maybeGiveMeAThing("foo", "bar" "baz")
"the thing should be ok" >> {
thing must beOk
}
step(stopOnFail = true)
"other examples with thing" >> {
"ex1" >> ok
"ex2" >> ok
}
}
}
Problem
In specs2, what is the proper way to express a pattern of subtests that only execute if its "parent" test returned a result without throwing an exception? I have a function `maybeGiveMeAThing`, and it can either return a `Thing`, or throw exceptions. A call looks like this: `val thing: Thing = maybeGiveMeAThing("foo", "bar" "baz"`) I want to test that with a certain set of inputs, that `maybeGiveMeAThing` successfully returns a Thing without throwing an exception, and using the Thing returned, do further tests to ensure that it is the correct `Thing` returned for the parameters given to `maybeGiveMeAThing`. The way I have the tests currently set up, if the call to `maybeGiveMeAThing` throws an exception, the entire test suite gets aborted. This would be the logic I prefer: - If a `Thing` was returned successfully, proceed with a set of subtests that analyze the contents of thing - If `maybeGiveMeAThing` threw an exception (any exception), skip the subtests that analyze thing, but continue with the rest of the tests My existing test code looks roughly like: ``` // ... "with good parameters" in { var thing: Thing = null "return a Thing without throwing an exception" in { thing = maybeGiveMeAThing("some", "good", "parameters", "etc.") } should not(throwA[Exception]) "the Thing returned should contain a proper Foo" in { thing.foo mustBe "bar" } //... etc ... } // ... } ``` ...although this feels like it's way off from the right way to do it. What would be the proper way? (I would like to avoid using `var`s if I can help it.)