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

rdm*_*ler 2 groovy spock

似乎大多数时候,Spock测试都是以相同的顺序执行的。

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

更新:正如tim_yates所说:“测试应该隔离,顺序无关紧要”,我想我应该解释一下为什么我要拥有此功能...

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

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

Szy*_*iak 6

LeonardBrünings提出建议之后,我已经Sputnik使用注释驱动的扩展替换了基于扩展的解决方案。

您可以创建自己的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}"
    }
}
Run Code Online (Sandbox Code Playgroud)

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

该规范包含5个将数字输出到控制台的功能。我们使用自定义@RandomizeOrder注释(请参阅“注释驱动的本地扩展”文档)。首先,我们创建一个注释类。

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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

在此处输入图片说明

  • 应该注意的是,测试应该是隔离的,顺序无关紧要。@Stepwise测试除外。我想这对于检查服务是否没有携带导致问题的未知状态可能很方便 (2认同)
  • 我同意。如果默认顺序是随机的,并且只有@Stepwise保证声明顺序(和单个失败中断),我会好的。 (2认同)

Leo*_*ngs 5

由于您只想随机化一个类中的测试顺序,因此可以通过扩展来实现。看看StepwiseExtension

private void sortFeaturesInDeclarationOrder(SpecInfo spec) {
    for (FeatureInfo feature : spec.getFeatures())
      feature.setExecutionOrder(feature.getDeclarationOrder());
 }
Run Code Online (Sandbox Code Playgroud)

您可以在自己的扩展中简单地随机化执行顺序。取决于您是只选择还是全部测试。您可以创建AnnotationDrivenExtensionIGlobalExtension查看有关其工作原理的文档