Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing multiple data sets with ScalaTest

is there any convenient way execute tests on multiple data sets - like in JUnit's parametrized tests?

like image 583
Jarek Avatar asked Mar 20 '11 15:03

Jarek


People also ask

What is ScalaTest used for?

ScalaTest is one of the most popular, complete and easy-to-use testing frameworks in the Scala ecosystem. Where ScalaTest differs from other testing tools is its ability to support a number of different testing styles such as XUnit and BDD out of the box.

What is a fixture in ScalaTest?

Regarding to the ScalaTest documentation: A test fixture is composed of the objects and other artifacts (files, sockets, database connections, etc.) tests use to do their work. When multiple tests need to work with the same fixtures, it is important to try and avoid duplicating the fixture code across those tests.

How do I run ScalaTest in eclipse?

To run all ScalaTest suites in a selected file, you can select the file using 2 different ways: By choosing an opened Scala source file containing ScalaTest suite(s) in the editor. By choosing the Scala source file containing ScalaTest suite(s) from Project Explorer/Navigator.


2 Answers

There's a new feature for testing multiple data sets coming in ScalaTest 1.5, which you can currently try as a snapshot. It is released at scala-tools.org:

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

You mix in (or import the members of) TableDrivenPropertyChecks, then you can define tables like this:

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 a var arg list of tuples to Table. Each tuple has to have the same arity, in this case each tuple has arity 4 (4 members). The first tuple is all strings, and these define names for the columns. The subsequent tuples each define one row of data. You can put any type in the tuple, but in general each column would contain the same type. Though if you wanted you could have columns of type Any that can contain anything. You can have table with 1 to 22 columns. If you need more than 22 columns (the max tuple size in Scala is currently 22), what you could do is use a compound type in one or more columns.

Once you have a table, you can check them with forAll like this:

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

forAll takes two parameter lists. The first is a table and the second is a "property function," which expresses something that should be true for every row of the table. forAll will take each row of the table (skipping the heading row of column names, of course) and make sure the property holds. If it doesn't, you get a nice error message saying which row of the table failed, what the values of the named columns were, etc.

A Table is a Seq of the data tuples, so you can also use it like a Seq. For example, you could get a Seq of Option[Exception] indicating which rows failed like this:

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

The resulting Seq contains one Option for each row of data in the table, which is a None if the property passed for that row, and Some[Exception] if the property failed. The exception in the Some contains all the details about the failure.

like image 199
Bill Venners Avatar answered Oct 20 '22 18:10

Bill Venners


Shared tests can be interesting to you. They allow you to define some set of tests like in this stack 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 actual spec you can use it like this:

behave like nonEmptyStack(stackWithOneItem, lastValuePushed)

So in other words nonEmptyStack is parametrized set of tests that you can use with different data sets you want to test.

like image 37
tenshi Avatar answered Oct 20 '22 16:10

tenshi