Самый простой способ, который приходит мне в голову, - это подготовить данные перед запуском методов тестирования на основе какого-либо условия (например, среды выполнения), а затем использовать эти предопределенные данные в своих тестах. Рассмотрим следующий пример:
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']) })
Полагаю, вы видите, насколько проблематичным оно становится.