Spock — это среда тестирования с открытым исходным кодом для Java и Groovy, которая привлекает все больше поклонников, особенно в сообществе Groovy. Это позволяет вам писать краткие, выразительные тесты, используя вполне читаемую нотацию в стиле BDD. Он даже поставляется с собственной встроенной библиотекой.
Ой. Я думал, что он был научно-фантастическим персонажем. Могу ли я увидеть пример?
Конечно. Вот простой код из ката кодирования, который я недавно сделал:
import spock.lang.Specification;
class RomanCalculatorSpec extends Specification {
def "I plus I should equal II"() {
given:
def calculator = new RomanCalculator()
when:
def result = calculator.add("I", "I")
then:
result == "II"
}
}
В Споке у вас нет тестов, у вас есть спецификации . Это обычные классы Groovy, которые расширяют класс спецификаций, который на самом деле является классом JUnit. Ваш класс содержит набор спецификаций, представленных методами с забавными названиями методов в кавычках ™. Забавный метод names-in-quotes ™ использует преимущества волшебства Groovy, чтобы вы могли выразить свои требования в очень удобочитаемой форме. А поскольку эти классы являются производными от JUnit, вы можете запускать их из Eclipse, как обычный модульный тест Groovy, и они создают стандартные отчеты JUnit, что хорошо для серверов CI.
Другое дело: обратите внимание на структуру этого теста? Мы используем Дано: , когда: а потом: выразить действия и ожидаемые результаты. Эта структура является обычной в поведенчески-ориентированной разработке, или BDD, таких фреймворках, как Cucumber и easyb. Хотя тесты в стиле Спока, как правило, более лаконичны и более технически ориентированы, чем такие инструменты, как Cucumber и easyb, которые часто используются для автоматизации приемочных испытаний. Но я отвлекся …
На самом деле, пример, который я привел ранее, был немного кратким. Мы могли бы сделать наши намерения более понятными, добавив текстовые описания после меток when: и then:, как я сделал здесь:
def "I plus I should equal II"() {
when: "I add two roman numbers together"
def result = calculator.add("I", "I")
then: "the result should be the roman number equivalent of their sum"
result == "II"
}
Это отличная прояснение ваших идей и документирование вашего API.
Но где же операторы AssertEquals?
Ага! Я рад, что ты спросил! Спок использует функцию под названием Power Asserts . Утверждение после того, как : ваше утверждение. Если этот тест не пройден, Спок покажет подробный анализ того, что пошло не так, в следующем формате:
I plus I should equal II(com.wakaleo.training.spocktutorial.RomanCalculatorSpec)
Time elapsed: 0.33 sec <<< FAILURE!
Condition not satisfied:
result == "II"
| |
I false
1 difference (50% similarity)
I(-)
I(I)
at com.wakaleo.training.spocktutorial
.RomanCalculatorSpec.I plus I should equal II(RomanCalculatorSpec.groovy:17)
Ницца! Но в JUnit у меня есть @Before и @After для светильников. Могу ли я сделать это в Споке?
Конечно, но вы не используете аннотации. Вместо этого вы реализуете методы setup () и cleanup () (которые запускаются до и после каждой спецификации). Я добавил один здесь, чтобы показать вам, как они выглядят:
import spock.lang.Specification;
class RomanCalculatorSpec extends Specification {
def calculator
def setup() {
calculator = new RomanCalculator()
}
def "I plus I should equal II"() {
when:
def result = calculator.add("I", "I")
then:
result == "II"
}
}
Вы также можете определить setupSpec () и cleanupSpec (), которые запускаются непосредственно перед первым тестом и сразу после последнего.
Я большой поклонник параметризованных тестов в JUnit 4. Могу ли я сделать это в Споке!
Вы уверены, что можете! На самом деле это одна из черт Спока!
def "The lowest number should go at the end"() {
when:
def result = calculator.add(a, b)
then:
result == sum
where:
a | b | sum
"X" | "I" | "XI"
"I" | "X" | "XI"
"XX" | "I" | "XXI"
"XX" | "II" | "XXII"
"II" | "XX" | "XXII"
}
Этот код будет запускать тест 5 раз. Переменные , Ь , а сумма инициализируются из строк в таблице в где: п. И если какой-либо из тестов не пройден, вы получите
Это тоже круто. Как насчет насмешек? Могу ли я использовать Mockito?
Конечно, если хочешь. но Спок на самом деле поставляется со своей собственной насмешливой структурой, которая довольно аккуратна. Вы устанавливаете макет или заглушку с помощью метода Mock (). Я показал два возможных способа использования этого метода здесь:
given:
Subscriber subscriber1 = Mock()
def subscriber2 = Mock(Subscriber)
...
Вы можете настроить эти макеты на поведение определенным образом. Вот несколько примеров. Вы можете сказать, что метод должен возвращать определенное значение, используя оператор >> :
subscriber1.isActive() >> true
subscriber2.isActive() >> false
Или вы можете получить метод, чтобы вызвать исключение при его вызове:
subscriber.activate() >> { throw new BlacklistedSubscriberException() }
Затем вы можете проверить результаты несколькими различными способами. Вот более сложный пример, чтобы показать вам некоторые из ваших вариантов:
def "Messages published by the publisher should only be received by active subscribers"() {
given: "a publisher"
def publisher = new Publisher()
and: "some active subscribers"
Subscriber activeSubscriber1 = Mock()
Subscriber activeSubscriber2 = Mock()
activeSubscriber1.isActive() >> true
activeSubscriber2.isActive() >> true
publisher.add activeSubscriber1
publisher.add activeSubscriber2
and: "a deactivated subscriber"
Subscriber deactivatedSubscriber = Mock()
deactivatedSubscriber.isActive() >> false
publisher.add deactivatedSubscriber
when: "a message is published"
publisher.publishMessage("Hi there")
then: "the active subscribers should get the message"
1 * activeSubscriber1.receive("Hi there")
1 * activeSubscriber2.receive({ it.contains "Hi" })
and: "the deactivated subscriber didn't receive anything"
0 * deactivatedSubscriber.receive(_)
}
Это выглядит аккуратно. Так что же лучше всего использовать Спока?
Спок отлично подходит для модульного или интеграционного тестирования проектов Groovy или Grails. С другой стороны, такие инструменты, как easyb amd cucumber , вероятно, лучше подходят для автоматизированных приемочных испытаний — формат менее технический, а отчетность больше подходит для тех, кто не является разработчиком.
From http://www.wakaleo.com/blog/303-an-introduction-to-spock