使用ScalaTest测试多个数据集

时间:2011-03-20 15:00:29

标签: scala scalatest

有没有方便的方法对多个数据集执行测试 - 比如JUnit的参数化测试?

3 个答案:

答案 0 :(得分:10)

有一项新功能可用于测试ScalaTest 1.5中的多个数据集,您现在可以将其作为快照进行尝试。它发布在scala-tools.org:

组ID:org.scalatest artifact id:scalatest 版本:1.5-SNAPSHOT

您混合(或导入TableDrivenPropertyChecks的成员),然后您可以定义这样的表:

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

将var元组的元组列表传递给Table。每个元组都必须具有相同的元素,在这种情况下,每个元组都有4个元素(4个成员)。第一个元组是所有字符串,它们定义列的名称。随后的元组每个都定义一行数据。您可以在元组中放置任何类型,但通常每列都包含相同的类型。虽然如果你想要你可以有任何类型的列可以包含任何东西。您可以拥有1到22列的表。如果您需要超过22列(Scala中的最大元组大小当前为22),您可以在一列或多列中使用复合类型。

一旦你有了一张桌子,就可以像这样检查它们:

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

forAll需要两个参数列表。第一个是表,第二个是“属性函数”,它表示对于表的每一行都应该为true的东西。 forAll将占用表的每一行(当然,跳过列名的标题行)并确保该属性成立。如果没有,则会收到一条错误消息,指出表中哪一行失败,指定列的值是什么等等。

表是数据元组的Seq,因此您也可以像Seq一样使用它。例如,您可以获得一个Seq of Option [Exception],指示哪些行失败如下:

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

结果Seq包含表中每行数据的一个选项,如果属性为该行传递,则为None;如果属性失败,则为[Exception]。 Some中的例外包含有关失败的所有细节。

答案 1 :(得分:6)

Shared tests对您来说很有趣。它们允许您定义一些测试集,如此堆栈示例中所示:

  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)
    }
  }

然后在实际规范中你可以像这样使用它:

behave like nonEmptyStack(stackWithOneItem, lastValuePushed)

因此换句话说, nonEmptyStack 是一组参数化测试,可以与您要测试的不同数据集一起使用。

答案 2 :(得分:4)

数据驱动测试的另一种可能性是使用以下语法:

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)
    }
  }
}

默认情况下,测试并行执行,除非在build.sbt中设置parallelExecution in Test := false