Testing multiple datasets with ScalaTest

Is there any convenient way to run tests on multiple datasets - for example, in parameterized JUnit tests?

+7
source share
3 answers

A new feature has appeared for testing the many data sets included in ScalaTest 1.5, which you can now try as a snapshot. It is released at scala -tools.org:

group id: org.scalatest Artifact id: scalatest version: 1.5-SNAPSHOT

You mix (or import items) TableDrivenPropertyChecks, then you can define tables as follows:

val examples = Table( ("a", "b", "c", "d"), ( 1, 1, 1, 1), ( 1, 1, 1, 1), ( 1, 1, 1, 1), ( 1, 1, 1, 1) ) 

You pass the list of var arg tuples to the table. Each tuple must have the same clarity, in which case each tuple has arity 4 (4 members). The first tuple is all the rows, and they define the column names. In subsequent tuples, each defines one row of data. You can put any type in a tuple, but in general, each column will contain the same type. Although, if you wanted, you could have columns of type Any, which can contain anything. You can have a table with 1 to 22 columns. If you need more than 22 columns (the maximum size of a tuple in Scala is currently 22), then you can use a composite type in one or more columns.

Once you have a table, you can check them using for this:

 forAll (examples) { (a, b, c, d) => a + b + c + d should equal (4) } 

forAll accepts two parameter lists. The first is a table, and the second is a โ€œproperty functionโ€ that expresses what should be true for each row of the table. forAll will take each row of the table (of course, skipping the header line of the column names) and make sure the property is complete. If this is not the case, you will receive an error message indicating which row of the table has failed, what are the values โ€‹โ€‹of the named columns, etc.

A table is a Seq data tuple, so you can also use it as a Seq. For example, you can get a Seq of Option [Exception] indicating which rows fail as follows:

 for ((a, b, c, d) <- examples) yield { failureOf { a + b + c + d should equal (4) } } 

As a result, Seq contains one parameter for each row of data in the table, which is None if the property is passed for this row, and Some [Exception] if the property fails. An exception in Some contains all the details of the failure.

+8
source

General tests may be of interest to you. They allow you to define a certain set of tests, for example, in this example:

  def nonEmptyStack(stack: Stack[Int], lastItemAdded: Int) { "be non-empty" in { assert(!stack.empty) } "return the top item on peek" in { assert(stack.peek === lastItemAdded) } "not remove the top item on peek" in { val size = stack.size assert(stack.peek === lastItemAdded) assert(stack.size === size) } "remove the top item on pop" in { val size = stack.size assert(stack.pop === lastItemAdded) assert(stack.size === size - 1) } } 

and then in the actual specification you can use it like this:

 behave like nonEmptyStack(stackWithOneItem, lastValuePushed) 

In other words, nonEmptyStack is a parameterized set of tests that you can use with different sets of data that you want to test.

+6
source

Another option for data-based testing is to use the following syntax:

 class SampleTest extends FunSuite { val input = List((1, 1), (4, 2), (9, 3)) input.foreach{i => test(s"Test of math.sqrt(${i._1})") { assert(math.sqrt(i._1) === i._2) } } } 

By default, tests are run in parallel, unless you installed parallelExecution in Test := false in build.sbt.

+3
source

All Articles