前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spock 测试框架的介绍和使用详解

Spock 测试框架的介绍和使用详解

作者头像
yawn
发布2019-09-11 14:32:20
3.6K0
发布2019-09-11 14:32:20
举报

Java项目中使用groovy简化测试 、 java项目测试框架spock的使用教程

简介

Spock 框架是一个基于groovy语法的测试框架,由于使用groovy,所以使用起来比 junit 更加灵活,测试用例的写法更加简单易懂,一目了然。

如果使用过junit,spock的则很容易上手,可以类比来学习。

使用

下面直接使用实例来介绍spock的用法:

1.加入依赖

代码语言:javascript
复制
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.2-groovy-2.4</version>
            <scope>test</scope>
        </dependency>
        <!-- Spock需要的groovy依赖 -->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.15</version>
        </dependency>
        <!-- spring boot spock -->
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>1.2-groovy-2.4</version>
            <scope>test</scope>
        </dependency>

2. 测试方法的生命周期

在junit使用时,主要用以下注解来标记测试类的方法:

代码语言:javascript
复制
@Test :标记需要运行的测试方法,一个测试类中可以有多个@Test方法;
@Before/@After :标记的方法,会在每个测试方法运行之前/之后运行一次;
@BeforeClass/@AfterClass :标记的方法会在测试类初始化时/销毁时运行;

spock 没有使用以上的注解形式,而是测试类需要继承 Specification 父类,重写父类中的以下方法,就可以自定义测试方法的生命周期:

代码语言:javascript
复制
def setup() {}         // run before every feature method
def cleanup() {}       // run after every feature method
def setupSpec() {}     // run before the first feature method
def cleanupSpec() {}   // run after the last feature method

所以有如下测试代码:

代码语言:javascript
复制
package com.yawn.spock

import spock.lang.Shared
import spock.lang.Specification

/**
 * spock 测试
 * @author yawn
 *     2019/6/10 9:43
 */
class CalculateSpec extends Specification {

    // 初始化
    def setupSpec() {
        calculateService = new CalculateService()
        println ">>>>>>   setupSpec"
    }
    def setup() {
        println ">>>>>>   setup"
    }
    def cleanup() {
        println ">>>>>>   cleanup"
    }
    def cleanupSpec() {
        println ">>>>>>   cleanupSpec"
    }

    def "test life cycle"() {
        given:
        def a = 1
        def b = 2

        expect:
        a < b

        println "test method finished!"
    }
}

运行结果为:

spock测试的生命周期方法执行顺序
spock测试的生命周期方法执行顺序

spock测试的生命周期方法执行顺序

3. 测试方法的格式

(1)given … expect … 格式:

given语句块为条件,expect为测试期望得到的结果,结果为true则通过测试。上面的示例就是这种格式的。

(2)given … when … then …

代码语言:javascript
复制
class CalculateSpec extends Specification {
    @Shared
    CalculateService calculateService

    // 初始化
    def setupSpec() {
        calculateService = new CalculateService()
    }
    // 测试方法
    def "test plus 1"() {
        given: "准备数据"
        def a = 1
        def b = 2

        when: "测试方法"
        def c = calculateService.plus(a, b)

        then: "校验结果"
        c == 4 - 1
    }

其中,@Share注解表示的是各个测试方法共享的一个实例。setupSpec() 方法中初始化了这个实例。

(3)when … then …

语义同上。

(4)given … expect … where …

代码语言:javascript
复制
def "test1"() {
    given: "准备数据"

    expect: "测试方法"
    z == calculateService.plus(x, y)

    where: "校验结果"
    x | y || z
    1 | 0 || 1
    2 | 1 || 3
}

expect 为核心的测试校验语句块。where 为多个测试用例的列举,很直观的写法。

以上测试方法的语义为:z是由x和y经过方法plus()运算后得到的结果,现在分别列出了两组x,y,z的值,来测试这个关系是否满足。

由于有两个测试用例,所以plus()方法会在这里运行两次。

(5)expect … where …

同上。

(6)expect …

同上。测试单个语句是否成立。

4.where 测试用例的列举格式:

where 后可列举多个测试用例,有以下不同的格式:

代码语言:javascript
复制
// 1 映射格式
    def "length of Spock's and his friends' names"() {
        expect:
        name.size() == length
        where:
        name     | length
        "Spock"  | 5
        "Kirk"   | 4
        "Scotty" | 6
    }
    // 2 数组列表格式 (每个数组顺序不能乱)
    def "length of Yawn's and his friends' names"() {
        expect:
        name.size() == length

        where:
        name << ["Yawn", "Tim"]
        length << [4, 3]
    }

5.verifyAll 校验多个表达式结果

代码语言:javascript
复制
    def "没有参数的 verifyAll"() {
        when:
        int z1 = calculateService.plus(1, 1)
        int z2 = calculateService.plus(1, 2)
        int z3 = calculateService.plus(1, 3)

        then:
        verifyAll {
            z1 == 1
            z2 == 3
            z3 == 3
        }
    }

verifyAll语句块可以分别校验多个boolean的结果。

6.with()和verifyAll() 取对象属性的值

代码语言:javascript
复制
    def "test person use with(p)"() {
        given: "init a person"
        Date now = new Date()
        Person p = new Person(name: "yawn", age: 18, birthday:   now)

        expect: "测试p"
        with(p) {
            name == "yawn"
            age < 20
            birthday == now
        }
    }

    def "多个预期值的测试使用 verifyAll()"() {
        when:
        Person p = new Person(name: "yawn", age: 18)

        then:
        verifyAll(p) {
            name == "yawn"
            age < 20
        }
    }

    static class Person {
        private String name
        private int age
        private Date birthday
    }

with()和verifyAll()传入对象后,可以直接使用其属性值。

7.多次执行被测试的语句:

代码语言:javascript
复制
def "多次执行测试语句"() {
        given:
        def a = 0

        expect: "aaa"
        3 * calculateService.plusPlus(a) == 3

        // 执行3次后结果为 3
    }

“3 * _” 表示这个语句会被执行三次,再与“==”后面的3进行比较。

本文来自  java技术分享站(jvm123.com)http://jvm123.com/2019/08/spock.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java项目中使用groovy简化测试 、 java项目测试框架spock的使用教程
    • 简介
      • 使用
        • 1.加入依赖
        • 2. 测试方法的生命周期
        • 3. 测试方法的格式
        • 4.where 测试用例的列举格式:
        • 5.verifyAll 校验多个表达式结果
        • 6.with()和verifyAll() 取对象属性的值
        • 7.多次执行被测试的语句:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档