是否可以随机执行Spock测试的顺序? [英] Is it possible to randomize the order in which Spock tests are executed?
问题描述
大多数情况下,似乎spock测试都是以相同的顺序执行的.
it seems that spock tests are executed in the same order, most of the time.
是否可以设置一些选项以随机顺序执行它们?
Is it possible to set some option to execute them in a random order?
更新:当tim_yates评论测试应该隔离,顺序无关紧要"时,我想我应该解释一下我为什么要拥有此功能...
Update: as tim_yates commented "tests should be isolated, and order shouldn't matter", I think I should explain why I would like to have this feature...
我们进行了一次代码撤退,试图将测试变成绿色.因此,我们在被测类中实现了一个状态,然后将其用于返回所有测试的corerct结果.
We had a code retreat where we tried to just tried to turn the tests green. So we implemented a state in the class under test which then would be used to return the corerct result for all tests.
为了避免这种邪恶的编码,我认为最好以随机顺序执行测试:-)
To avoid such evil coding, I thought it would be great to execute tests in random order :-)
推荐答案
在 LeonardBrünings建议之后,我已替换了基于扩展的解决方案
Sputnik
使用注释驱动的扩展名.
After Leonard Brünings suggestion, I've replaced the solution based on extending
Sputnik
with using annotation-driven extension.
您可以创建自己的Spock扩展,以使功能随机化.请考虑以下示例.
You can create your own Spock extension that randomizes features. Consider the following example.
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}"
}
}
此规范包含5个将数字输出到控制台的功能.我们使用自定义的@RandomizeOrder
注释(请参见 由注释驱动的本地扩展程序" 文档).首先,我们创建一个注释类.
This specification contains 5 features that prints numbers to the console. We use a custom @RandomizeOrder
annotation (see "Annotation-Driven Local Extension" docs). Firstly, we create an annotation class.
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
的参数将使用预定义的种子对特征进行混洗.
This extension does one thing - in the visitSpec
visitor method we assign a random execution order to all feature methods. It supports predefined seed, so whenever you want to re-create a specific order, you can read the seed value from the console and you can pass it in the next run. For instance, the following parameter added -Dspock.random.order.seed=1618636504276
will shuffle features using predefined seed.
运行带有@RandomizedOrder
注释的测试时,我们将看到与声明顺序不同的方法.
When we run the test annotated with @RandomizedOrder
we will see methods in the order different than the declaration order.
这篇关于是否可以随机执行Spock测试的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!