I am new to scalatest and a bit lost in the gigantic inconsistent mess of features
I am trying to write parameterized tests. It seems that the way to do that is via TableDrivenPropertyChecks
I managed to get it working with a test like:
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.prop.TableDrivenPropertyChecks
class MyTest extends AnyFunSpec with TableDrivenPropertyChecks {
describe("the test") {
val cases = Table(
("label", "a", "b"),
("case 2 > 1", 1, 2),
("case 4 > 3", 3, 4),
)
it("should...") {
forAll(cases) { (name: String, a: Int, b: Int) =>
assert(b > a)
}
}
}
}
It's fine, but when I run it under sbt
I just see:
[info] MyTest:
[info] the test
[info] - should...
If I inject a bad case into the table I can see the test fail so I know they are all being tested.
What I want is for the test runner to report something for each case in the table.
I have seen examples which look like they would provide this, e.g.: https://blog.knoldus.com/table-driven-testing-in-scala/
import org.scalatest.FreeSpec
import org.scalatest._
import org.scalatest.prop.TableDrivenPropertyChecks
class OrderValidationTableDrivenSpec extends FreeSpec with TableDrivenPropertyChecks with Matchers {
"Order Validation" - {
"should validate and return false if" - {
val orders = Table(
("statement" , "order")
, ("price is negative" , Order(quantity = 10, price = -2))
, ("quantity is negative" , Order(quantity = -10, price = 2))
, ("price and quantity are negative" , Order(quantity = -10, price = -2))
)
forAll(orders) {(statement, invalidOrder) =>
s"$statement" in {
OrderValidation.validateOrder(invalidOrder) shouldBe false
}
}
}
}
}
But if I try to do this in my test:
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.prop.TableDrivenPropertyChecks
class MyTest extends AnyFunSpec with TableDrivenPropertyChecks {
describe("the test") {
val cases = Table(
("label", "a", "b"),
("case 2 > 1", 1, 2),
("case 3 > 4", 3, 4),
)
it("should...") {
forAll(cases) { (label: String, a: Int, b: Int) =>
s"$label" in {
assert(b > a)
}
}
}
}
}
...I get the error: value in is not a member of String
from the s"$label" in {
part.
How do I get my TableDrivenPropertyChecks
to report something for each case in the table?
One of cool features of ScalaTest is that test is not a method, so you can define tests inside a loop:
Table(
("a", "b"),
(1, 2),
(3, 4)
).forEvery({ (a: Int, b: Int) => {
it(s"should pass if $b is greater then $a") {
assert(b > a)
}
}})
Or even without using Table
, just with any collection:
Seq(
(1, 2),
(3, 4)
).foreach {
case (a: Int, b: Int) =>
it(s"should pass if $b is greater then $a") {
assert(b > a)
}
}
This way you will get one test per each iteration of a loop, so all the cases will be executed independently, while in case of a loop in a single test it will fail on first failed assertion and won't check remaining cases.