Запуск тестов в разных тестовых средах с использованием Spock - PullRequest
0 голосов
/ 17 мая 2018

В настоящее время я пишу тесты REST API с использованием REST Client и Spock.Я хочу, чтобы мои тесты можно было запускать в разных тестовых средах.Мои тестовые данные различаются в зависимости от тестовой среды, поэтому необходимо использовать и указывать разные входные данные для каждой среды.Для примера теста ниже

class MathSpec extends Specification {
    def "maximum of two numbers"() {
        expect:
            Math.max(a, b) == c

       where:
            a | b || c
            1 | 3 || 3
    }
}

Могу ли я указать разные таблицы данных для каждой среды?

class MathSpec extends Specification {
    def "maximum of two numbers"() {
         expect:
              Math.max(a, b) == c

         where:
              @TEST 
              a | b || c
              1 | 3 || 3

              @PROD
              a | b || c
              4 | 5 || 6

     }
 }

Если нет, как лучше решить эту проблему?Спасибо.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Спок имеет Многопараметрические каналы данных , чтобы справиться с этим. Вы можете переместить «логику» в метод, управляемый данными.

class MathSpec extends Specification {

   def "maximum of two numbers"(int a, int b, int c) {
        expect:
        Math.max(a, b) == c

        where:
        [a, b, c] << getData()
    }

    def getData() {
        if (System.getProperty("Staging"))
            [ [1, 3, 3] ]
       else
            [ [3, 5, 5] ]
   }
}

В вашем случае я бы использовал абстрактный метод getData().
Я бы реализовал в getData() в двух разных классах MathProductionSpec и MathStagingSpec
Я бы использовал спок аннотации для выполнения в соответствии с вашей средой.

пример:

abstract class MathSpec extends Specification {

    def "maximum of two numbers"(int a, int b, int c) {
        expect:
        Math.max(a, b) == c

        where:
        [a, b, c] << getData()
    }

    def abstract getData()
}
@Production
class MathProductionSpec extends MathSpec {
    def getData() {
        [ [4, 2, 4] ]
    }
}
@Staging
class MathStagingSpec extends MathSpec {
    def getData() {
        [ [1, 3, 3] ]
    }
}
0 голосов
/ 17 мая 2018

Самый простой способ, который приходит мне в голову, - это подготовить данные перед запуском методов тестирования на основе какого-либо условия (например, среды выполнения), а затем использовать эти предопределенные данные в своих тестах. Рассмотрим следующий пример:

import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

class EnvBasedDataSpec extends Specification {
    @Shared
    static Map data = [:]

    def setupSpec() {
        /* If you want to pick variable from env variables, use:
         * System.getenv().getOrDefault('execution.environment', 'test')
         *
         * If you want to provide variable like -Dexecution.environment=test, use:
         * System.getProperty('execution.environment', 'test')
         */
        def executionEnvironment = System.getProperty('execution.environment', 'test')

        switch (executionEnvironment) {
            case 'test':
                data = [a: 1, b: 3, c: 3]
                break
            case 'prod':
                data = [a: 2, b: 4, c: 4]
                break
        }
    }

    @Unroll
    def "maximum of two numbers (#a, #b) == #c"() {
        expect:
        Math.max(a, b) == c

        where:
        a       | b         || c
        data.a  | data.b    || data.c
    }
}

В этом примере мы готовим общий data, который содержит значения, которые мы будем использовать в тестах. Здесь мы ожидаем, что информация о среде выполнения будет передана как

-Dexecution.environment=value 

свойство (в качестве альтернативы вы можете передавать ту же информацию, используя переменные env). В этом примере мы также используем значение по умолчанию, если данное свойство отсутствует - test в этом случае (это предотвратит сбой теста, если вы забыли указать переменную среды выполнения).

Альтернатива: @IgnoreIf условное освобождение

Спок поддерживает условное исполнение. Посмотрите, как будет выглядеть тот же тест, если использовать @IgnoreIf подход:

import spock.lang.IgnoreIf
import spock.lang.Specification

class AlternativeEnvBasedDataSpec extends Specification {

    @IgnoreIf({ System.getProperty('execution.environment') == 'prod' })
    def "maximum of two numbers (test)"() {
        expect:
        Math.max(a, b) == c

        where:
        a  | b  || c
        1  | 3  || 3
    }

    @IgnoreIf({ System.getProperty('execution.environment') == 'test' })
    def "maximum of two numbers (prod)"() {
        expect:
        Math.max(a, b) == c

        where:
        a  | b  || c
        2  | 4  || 4
    }
}

К сожалению, этот подход требует большого дублирования: вы должны дублировать методы тестирования и не можете повторно использовать одно и то же имя (компилятор не позволяет это делать). Это довольно подвержено ошибкам - вы должны обращать внимание на одинаковое тело теста для всех методов, которые должны проверять один и тот же материал, но с разными данными. Другое дело, что условие, переданное @IgnoreIf, должно быть изменено, если вы введете 3-е окружение - в этом случае вы укажете его примерно так:

@IgnoreIf({ !(System.getProperty('execution.environment') in ['staging', 'prod']) })

Полагаю, вы видите, насколько проблематичным оно становится.

...