groovy - 是否可以随机化 Spock 测试的执行顺序?

标签 groovy spock

大多数情况下,spock 测试似乎都是按相同的顺序执行的。

是否可以设置一些选项以随机顺序执行它们?

更新:正如tim_yates评论的“测试应该被隔离,顺序不重要”,我想我应该解释为什么我想拥有这个功能......

我们进行了一次代码撤退,我们试图将测试变成绿色。因此,我们在被测类中实现了一个状态,然后该状态将用于返回所有测试的正确结果。

为了避免这种邪恶的编码,我认为以随机顺序执行测试会很棒:-)

最佳答案

After Leonard Brünings suggestion, I've replaced the solution based on extending Sputnik with using annotation-driven extension.

您可以创建自己的 Spock 扩展来随机化功能。考虑以下示例。

package com.github.wololock

import spock.lang.Specification

@RandomizedOrder
class RandomSpockSpec extends Specification {

    def "test 1"() {
        when:
        def number = 1

        then:
        println "[${new Date().format("HH:mm:ss.SSS")}] number ${number}"
    }

    def "test 2"() {
        when:
        def number = 2

        then:
        println "[${new Date().format("HH:mm:ss.SSS")}] number ${number}"
    }

    def "test 3"() {
        when:
        def number = 3

        then:
        println "[${new Date().format("HH:mm:ss.SSS")}] number ${number}"
    }

    def "test 4"() {
        when:
        def number = 4

        then:
        println "[${new Date().format("HH:mm:ss.SSS")}] number ${number}"
    }

    def "test 5"() {
        when:
        def number = 5

        then:
        println "[${new Date().format("HH:mm:ss.SSS")}] number ${number}"
    }
}

src/test/groovy/com/github/wololock/RandomSpockSpec.groovy

该规范包含 5 个将数字打印到控制台的功能。我们使用自定义 @RandomizeOrder 注释(请参阅 "Annotation-Driven Local Extension" 文档)。首先,我们创建一个注释类。

package com.github.wololock

import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension
import org.spockframework.runtime.model.SpecInfo

final class RandomizedOrderExtension extends AbstractAnnotationDrivenExtension<RandomizedOrder> {

    public static final String SPOCK_RANDOM_ORDER_SEED = "spock.random.order.seed"

    private static final long seed = System.getProperty(SPOCK_RANDOM_ORDER_SEED)?.toLong() ?: System.nanoTime()

    static {
        println "Random seed used: ${seed}\nYou can re-run the test with predefined seed by passing -D${SPOCK_RANDOM_ORDER_SEED}=${seed}\n\n"
    }

    @Override
    void visitSpecAnnotation(RandomizedOrder annotation, SpecInfo spec) {
        final Random random = new Random(seed)

        final List<Integer> order = (0..(spec.features.size())) as ArrayList

        Collections.shuffle(order, random)

        spec.features.each { feature ->
            feature.executionOrder = order.pop()
        }
    }
}

src/test/groovy/com/github/wololock/RandomizedOrderExtension.groovy

此扩展做了一件事 - 在 visitSpec 访问者方法中,我们为所有功能方法分配随机执行顺序。它支持预定义的种子,因此每当您想要重新创建特定订单时,您都可以从控制台读取种子值,并可以在下次运行中传递它。例如,添加以下参数 -Dspock.random.order.seed=1618636504276 将使用预定义种子对功能进行随机排列。

当我们运行用@RandomizedOrder注释的测试时,我们将看到方法的顺序与声明顺序不同。

enter image description here

关于groovy - 是否可以随机化 Spock 测试的执行顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55542364/

相关文章:

json - Grails 3 JSON 渲染无法渲染列表?

grails - Grails 2.0.0.RC1错误Spock测试

groovy - 在 Groovy 中同时循环多个列表

java - 如何访问默认包中的java类?

xml - 如何在使用 XmlSlurper 解析 xml 时读取带连字符的属性名称(例如 model_name)

Groovy star 导入和 "partial"包的使用

performance - Spock 性能问题

spring - 如何在 Spock 测试中将 @Value 注释与 Spring PropertyPlaceholderConfigurer 一起使用?

gradle - 在 Spring 启动应用的Spock单元测试中未找到给定的测试

unit-testing - 在 Controller 测试期间无法保存