Можно ли рандомизировать порядок, в котором выполняются тесты Спока? - PullRequest
2 голосов
/ 05 апреля 2019

похоже, что спок тесты выполняются в том же порядке, в большинстве случаев.

Можно ли установить какой-либо параметр для их выполнения в случайном порядке?

Обновление: как прокомментировал tim_yates "тесты должны быть изолированными, а порядок не должен иметь значения", я думаю, что должен объяснить, почему я хотел бы иметь эту функцию ...

У нас было отступление кода, где мы пытались просто сделать тесты зелеными. Таким образом, мы реализовали состояние в тестируемом классе, которое затем будет использоваться для возврата результата corerct для всех тестов.

Чтобы избежать такого злого кодирования, я подумал, что было бы здорово выполнять тесты в случайном порядке :-)

Ответы [ 2 ]

6 голосов
/ 06 апреля 2019

После предложения Леонарда Брюнингса я заменил решение, основанное на расширении 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}"
    }
}

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()
        }
    }
}

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

Это расширение делает одну вещь - в методе посетителя visitSpec мы назначаем случайный порядок выполнения для всех методов объектов.Он поддерживает предопределенный начальный уровень, поэтому всякий раз, когда вы захотите воссоздать определенный заказ, вы можете прочитать начальное значение из консоли и передать его при следующем запуске.Например, следующий добавленный параметр -Dspock.random.order.seed=1618636504276 будет перетасовывать объекты с использованием предопределенного начального числа.

Когда мы запустим тест, помеченный @RandomizedOrder, мы увидим методы в порядке, отличном от порядка объявления.

enter image description here

5 голосов
/ 06 апреля 2019

Поскольку вы хотите только рандомизировать порядок тестов внутри класса, это может быть достигнуто с помощью расширения.Взгляните на StepwiseExtension

private void sortFeaturesInDeclarationOrder(SpecInfo spec) {
    for (FeatureInfo feature : spec.getFeatures())
      feature.setExecutionOrder(feature.getDeclarationOrder());
 }

Вы можете просто рандомизировать порядок выполнения в своем собственном расширении.В зависимости от того, хотите ли вы это только выборочно или для всех ваших тестов.Вы можете создать AnnotationDrivenExtension или IGlobalExtension, см. документы о том, как это работает.

...