Spock测试套件入门

Spock测试套件

Spock套件基于一个单元测试框架,它有比junit更为简洁高效的测试语法。

核心概念

整体认识

Spock中一个单元测试类名叫Specification。所有的单元测试类,都需要继承Specification

class MyFirstSpecification extends Specification {
  // fields
  // fixture methods
  // feature methods
  // helper methods
}

对于spock来说,Specification代表了一个软件、应用、类的使用规范,其中的所有单元测试方法,被称为feature,即功能。

一个feature method的执行逻辑大概是如下几步:

  1. setup 设置该功能的前置配置
  2. stimulus 提供一个输入,触发该功能
  3. response 描述你期望该功能的返回值
  4. cleanup 清理功能的前置配置

所以,对spock来说,一个单元测试,其实是这个软件应用提供的功能使用规范,这个规范中提供了每个功能的使用说明书,输入什么,会得到什么,大体是按这个看法,去写单元测试的。

前置、后置

就像junit一样,我们可以对整个单元测试类做一些前置,并清理。也可以对每个单元测试的方法做一些前置后清理。

其跟Junit的类比关系为

setupSpec 对应 @BeforeClass
setup 对应 @Before
cleanup 对应 @After
cleanupSpec 对应 @AfterClass

同时由于Spock的单元测试本身是会集成Specification 父类的,所以父类中的前置、后置方法也会被调用,不过不用显示调用,会自动调用。

一个测试功能方法执行时,其整体的执行顺序为:

super.setupSpec

sub.setupSpec

super.setup

sub.setup

**feature method

sub.cleanup

super.cleanup

sub.cleanupSpec

super.cleanupSpec

同junit的类比

Feature 方法

blocks

feature的具体写法有很多的block组成,这些block对应的feature方法本身的四个阶段(setup, stimulus, reponse, cleanup) 。每个block对应阶段示意图

典型的用法
    def '测试++'(){
        given:
            def x = 5
        when: def result = calculateService.plusPlus(x)
        then: result == 6
    }
  • given也可以写成setup,feature方法里的given其实跟外面的setup方法功能一样,都是做测试功能的前置设置。只是单独的setup方法,是用来写对每个测试feature都有用的测试。只跟当前feature相关的设置,请放在feature方法内的given标签
  • when 标签用来实际调用想要测试的feature
  • then 中对when的调用返回进行结果验证,这里不需要写断言,直接写表达式就是断言
异常condition

then中的断言在spock中叫condition。比如Java中的Stack在没有元素时,进行Popup,则会EmptyStackException异常。我们期望它确实会抛出这个异常,那么写法如下

def '异常2'() {
        given:
        def stack = new Stack()
        when:
        def result = stack.pop()
        then:
        EmptyStackException e = thrown()
    }

它并不会抛出EmptyStackException,我们要测试这个预期的话,代码如下:

    def '异常2'() {
        given:
        def stack = new Stack()
        stack.push("hello world")
        when:
        stack.pop()
        then:
        EmptyStackException e = notThrown()
    }
then和expect的区别

前面说了when block用来调用,then用来判断预期结果。但有的时候,我们的调用和预期判断并不复杂,那么可以用expect将两者合在一起,比如以下两段代码等价

when:
def x = Math.max(1, 2)

then:
x == 2
expect:
Math.max(1, 2) == 2
cleanup block的用法
def 'cleanup'() {
        given:
        def file = new File("/some/path")
        file.createNewFile()

        // ...

        cleanup:
        file.delete()
    }

用于清理feature测试执行后的一些设置,比如打开的文件链接。该操作即便测试的feature出异常,依然会被调用

同样,如果多个测试feature都需要这个cleanup.那么建议将cleanup的资源提到setup方法中,并在cleanup方法中去清理

测试用例中的文本描述

为了让单元测试可读性更高,可以将测试方法中每一部分用文本进行描述,多个描述可以用and来串联

    def '异常2'() {
        given:'设置stack对象'
        def stack = new Stack()

        and:'其它变量设施'
        stack.push('hello world')


        when:'从sta
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值