2011-03-20 141 views
7

是否有任何方便的方式在多个数据集上执行测试 - 就像在JUnit的参数化测试中一样?使用ScalaTest测试多个数据集

+0

我想看看Scalacheck,它可以从Scalatest中使用。 – 2011-03-20 23:35:45

回答

8

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

组ID:org.scalatest 工件ID:scalatest 版本:1.5快照

您在混合(或导入的成员)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 arg列表传递给Table。每个元组都必须具有相同的元组,在这种情况下,每个元组都有4个元素(4个成员)。第一个元组是所有字符串,并且这些定义了列的名称。随后的元组每个定义一行数据。您可以将任何类型放入元组中,但通常每列都会包含相同的类型。虽然如果你想要的话,你可以有任何可以包含任何东西的类型的列。你可以有1到22列的表格。如果你需要超过22列(Scala中的最大元组大小是22),你可以做的是在一列或多列中使用复合类型。

一旦你有一个表,你可以用FORALL检查它们是这样的:

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

FORALL需要两个参数列表。第一个是表格,第二个是“属性函数”,表示表格的每一行应该是真的。 forAll将占用表中的每一行(当然,跳过列名称的标题行)并确保该属性成立。如果没有,你会得到一个很好的错误信息,说明表中的哪一行失败,指定列的值是多少,等等。

表是数据元组的一个序列,所以你也可以使用它就像一个Seq。例如,你可以得到选项[异常]表示的序列的行未能像这样:

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

得到的序列包含在表中,这是一个无如果属性传递数据的每一行一个选项对于那一行,以及一些[异常]如果属性失败。 Some中的例外包含关于失败的所有细节。

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被参数化可以使用您想要测试的不同数据集的一组测试。

3

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

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