请不要误解,我丝毫没有诋毁JUnit的任何意思,我的意思只是……咳……换个更好用的……而且即便如此,你也不能真正的丢掉它,因为Spock自己也需要JUnit。
简单地讲,Spock是一个Groovy的BDD测试框架,如果你是第一次这个词,那不妨先看个Spock的例子,然后再去访问刚才给出的BDD链接:
def "subscribers receive published events at least once"() { when: publisher.send(event) then: (1.._) * subscriber.receive(event) where: event << ["started", "paused", "stopped"] }
上面的例子已经非常明白的展示了Spock中的测试例子,但Spock的优点远不仅此而已。
记得Groovy 1.7的新特性之一:Power Assert吗?它最早就来源于Spock。对于没有下载使用Groovy 1.7的读者,这里简单说明一下。假设代码中有一条Assert语句“assert 91 == a * b”,在a=10和b=9的情况下,语句肯定会失败。那么在console中会显示:
Exception thrown Assertion failed: assert 91 == a * b | | | | | 10| 9 | 90 false at ConsoleScript2.run(ConsoleScript2:4)
是不是非常直观?请屏住呼吸,Spock还有另一个让人激动的特性,如果你跟我一样经常需要开发一些和数据库打交道的应用,肯定会为之雀跃不已。它就是数据驱动测试。
看看下面的例子,不用我多说,你应该能够体会到给测试带来的便捷:
def "maximum of two numbers"() { expect: Math.max(a, b) == c where: a << [3, 5, 9] b << [7, 4, 9] c << [7, 5, 9] }
忘掉一遍又一遍的书写循环、赋值、计算、验证的过程,只需要按以上写法准备各个关键部分,测试就会自动地根据输入数据进行循环,整个测试过程更加清晰。如果你觉得上面的例子太小儿科,那看看实际跟数据库打交道的一个例子:
@Speck class DataDriven { @Shared sql = Sql.newInstance("jdbc:derby:spockdata" , "org.apache.derby.jdbc.EmbeddedDriver") def "maximum of two numbers"() { expect: Math.max(a, b) == c where: [a, b, c] << sql.rows("select a, b, c from maxdata") } }
如今,Spock 0.4发布在即,它的作者Peter Niederwieser最近开始撰写一系列该版本相关的文章。在Spock 0.4的新特性(1):数据表中,Peter展示了另一个让人尖叫的新功能。
在数据驱动的第一个例子中,where部分的赋值虽然简化了我们平常的做法,但依旧不太直观。在0.4中,借助数据表,你可以写成这样:
def "maximum of two numbers"() { expect: Math.max(a, b) == c where: a | b | c 3 | 7 | 7 5 | 4 | 5 9 | 9 | 9 }
太棒了!真的是一个数据表!不知道此时你的感想如何?而这,正是我想要的。而且,也正是这让我在旁观了Spock一段时间之后,下定决心使用它的主要原因。
本站会继续跟踪Spock 0.4的新特性这一系列。关于Spock的学习资料,不用说,当然还是官方网站上的最保险。