spock的扩展

528 阅读3分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

spock是支持扩展的,目前官方给出了很多扩展,也支持自定义扩展。扩展性确实是衡量一个开源框架很重要的一点,官方提供的功能很难满足所有人的要求,如果支持了扩展的能力,那自然会留住很多用户。

首先,spock可以通过配置文件来配置,通过SpockConfig.groovy文件来配置,比如打开和关闭调用栈:

runner {
  filterStackTrace false
}

是否开启并行,在parallel指定需要并行的单测case:

runner {
  parallel {
    //...
  }
}

当然,除了外部的全局配置,可以单独配置到具体的方法上。spock的单独配置是基于注解的,官方也提供了很多强大的注解:

Ignore

可以在运行单测时忽略某些方法,而不用全部注释掉代码。Ignore注解中提供注释的功能,可以写忽略的原因。

@Ignore("TODO")
def "my feature"() { ... }

也可以在整个类上加Ignore,整个类的所有case就都会忽略:

@Ignore
class MySpec extends Specification { ... }

然后,我们常常并不会忽略全部,只是会忽略其中一部分,但又不想每个方法都去写Ignore,就是懒怎么办?有办法。

IgnoreRest

使用了IgnoreRest的方法及其下面的方法都会被忽略掉,相当于在这画一条线,剩余的全部忽略。

def "I'll not be ignored"() { ... }

@IgnoreRest
def "I'll run"() { ... }

def "I'll also be ignored"() { ... }

这样做是不是还是太粗暴了,就像当年以秦岭为线,以北的就供暖,以南的就不供暖,只留南方人在寒冬中瑟瑟发抖。不过spock显然不会这么粗暴。

IgnoreIf

对,就是在某些条件下才忽略:

@IgnoreIf({ System.getProperty("os.name").toLowerCase().contains("windows") })
def "I'll run everywhere but on Windows"() {

spock提供了一些官方的方法来获取一些环境和变量:

  • sys 一系列的系统变量
  • env 一系列的环境变量
  • os 操作系统
  • jvm jvm的版本和
  • instance 这里可以写自定义的表达式。

下面挨个举例子: 在windows下运行时忽略

@IgnoreIf({ os.windows })
def "I will run everywhere but on Windows"() { }

在windows或者java8时忽略,写多个是或的关系

@IgnoreIf({ os.windows })
@IgnoreIf({ jvm.java8 })
def "I'll run everywhere but on Windows or anywhere on Java 8"() { }

满足这个表达式时忽略,可以写任意的断言

@IgnoreIf({ PreconditionContext it -> it.os.windows })
def "I will run everywhere but not on Windows"() { }

这里是Ignore,那还我需要在某些条件下才运行呢?有有有。

Requires

这个和Ignore正好相反:

@Requires({ os.windows })
def "I'll only run on Windows"() { }

PendingFeature

这个注解有点意思,这是表示那些没被完全实现的逻辑,如果遇到有不符合预期也不会直接报错。但也会报错,分为以下几个情况:

  • 普通的case如果发生错误会直接标记成skipped
  • 如果是数据驱动测试的case,部分数据错误也会被标记成skipped
  • 如果数据驱动测试的全部case都失败了,才会被标记成失败

例子:

@PendingFeature
def "not implemented yet"() { ... }

当然也有pendingif:

@PendingFeatureIf({ os.windows })
def "I'm not yet implemented on windows, but I am on other operating systems"() { }

此外还有timeout,retry等等的比较常规的注解,几乎可以覆盖绝大多数场景了。