[img_assist | nid = 836 | title = | desc = | link = none | align = right | width = 240 | height = 210] Эндрю Гловер является соавтором Groovy в действии и написал тестовую среду под названием easyb. Новая структура способствует более «разговорному» подходу к модульному тестированию.
Q: Привет, Эндрю, ты соавтор Groovy in Action и автор фреймворка easyb test . Что такое easyb?
A: easyb — это система проверки истории, построенная в духе разработки, основанной на поведении. Он написан в основном для Groovy и предназначен для работы с Groovy и Java. С easyb вы можете писать истории, которые помогают проверять приложения — например, a Stack
. С помощью стеков вы можете выдвигать и выдвигать значения — push
метод должен помещать вещи в некоторую коллекцию, а pop
метод должен удалять их, верно? Используя easyb, вы можете создать историю, которая представляет собой серию сценариев, которые читаются как
учитывая некоторый контекст,
когда что-то происходит,
тогда должно произойти что-то еще
С этим форматом вы могли бы написать несколько сценариев, таких как «pop вызывается в стеке с одним значением» или «peek вызывается в стеке с одним значением» — тогда вы можете кодировать конкретный сценарий с помощью given
s, when
s и then
s, например этот:
scenario "pop is called on stack with one value", {
given "an empty stack with foo", {
stack = new Stack()
stack.push("foo")
}
when "pop is called", {
popVal = stack.pop()
}
then "foo should be returned", {
popVal.shouldBe "foo"
}
and
then "the stack should be empty", {
stack.empty.shouldBe true
}
}
easyb также поддерживает гибкий синтаксис проверки — видите shouldBe
вызов, который автоматически подключен ко всему в контексте сценария? Вы можете использовать shouldBeEqual
, shouldBeEqualTo
, shouldEqual
и, конечно , негативы , которые так же, как shouldNotBe
и т.д., и т.д.
Намерение состоит в том, чтобы создать исполняемую документацию — кто-то, скажем, клиент или бизнес-аналитик мог бы написать текст истории, а затем разработчик может реализовать вещи, как я делал выше. Кстати, при выполнении этого конкретного сценария (который является одним из немногих в одной истории), вы можете создать отчет, который описывает, какие истории были запущены, который выглядит примерно так:
История: в стеке
сценарий pop с одним значением вызывается с одним значением,
заданным пустым стеком с foo
при вызове pop,
затем должен быть возвращен foo,
тогда стек должен быть пустым
В: Easyb предназначен для модульного тестирования? Или его также можно использовать для интеграционного тестирования?
A: Да и Да! Это зависит только от вас, как вы используете его — из коробки, фреймворк поставляется с плагином, который поддерживает управление базой данных через DbUnit , так что есть много поддержки для интеграционного тестирования. Например, если вы обнаружите, что конкретная история требует определенных предварительных данных, вы можете поместить эти данные в базу данных с помощью database_model
вызова, который принимает стандартную информацию о соединении JDBC (URL, имя пользователя, драйвер и т. Д.), А затем String
представляет стандарт DbUnit. FlatXmlDataSet
тип. Так, например, в given
предложении вы можете заполнить базу данных следующим образом:
given "the database is properly seeded", {
database_model("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:hsql://127.0.0.1", "sa", ""){
return new File("./src/conf/seed.xml").text
}
}
Это облегчает интеграционное тестирование, не так ли? Плагин DbUnit представляет собой отдельный файл jar, который вы можете загрузить с веб-сайта easyb — просто убедитесь, что у вас есть этот jar в вашем classpath, и easyb найдет его, если вы вызовете database_model
вызов. Наша цель с плагинами состоит в том, чтобы иметь различные из них, которые облегчают тестирование более высокого уровня, поэтому возможно, что будет плагин Selenium.
Я склонен находить, что использование формата истории даже на объекте (то есть на уровне модульного тестирования) помогает управлять вещами в истинном стиле TTD — например, взять классический пример Money из примера JUnit Test Infected — учитывая add
метод, вы Можно написать модульный тест (в JUnit) так:
public class MoneyTest extends TestCase {
public void testSimpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
Assert.assertTrue(expected.equals(result));
}
}
Написание того же кода на easyb примерно так:
scenario "two moneys of the same currency are added", {
given "one money object is added to another", {
total = new Money(12, "CHF").add(new Money(14, "CHF"))
}
then "the total amount should be the sum of the two", {
total.amount().shouldBe 26
}
}
Обратите внимание, что в процессе написания простой истории я был вынужден думать о сценариях (до того, как набрал строку кода), и при этом я быстро обнаружил, что думаю о других сценариях — например, о двух Money
объектах разных валют. JUnit также не мешает вам так думать, но я считаю, что формат истории почти напрашивается заранее.
Q: Какие преимущества дает разработчикам easyb?
A: это легко! Серьезно, однако, easyb заставляет вас думать о поведении — о том, как все должно работать, а затем позволяет вам выразить эти ожидания естественным образом — order.getPrice().shouldBe "$56"
вместо того assert
и того и другого .
Истории также способствуют сотрудничеству — они представляют собой механизм, соединяющий развитие и заинтересованные стороны, во многом как предназначены Fit и Fitnesse. Плюс, easyb это весело! История DSL и структура ожиданий довольно забавны в использовании — вы также можете быстро связать ожидания, такие как
var.shouldNotBe null
and
var.length().shouldEqual 6
Отсутствие круглых скобок и использование пробелов делает это легко кодировать и легко читать.
В: Почему вы решили написать easyb на Groovy, а не на другом динамическом языке?
A: У Ruby уже есть RSpec, который является превосходной средой, и я хотел сделать нечто подобное доступным для мира Java — Groovy был для меня естественным выбором, так как я достаточно хорошо в этом разбираюсь. Не смотря на предвзятость, создание DSL в Groovy невероятно просто: мне также выпала роскошь кодировать первоначальный прототип с Venkat Subramaniam и Джеффом Брауном, которые являются удивительно талантливыми разработчиками Groovy.
Вопрос: По вашему мнению, способен ли easyb заменить обычные модули модульного тестирования, такие как JUnit или TestNG, в проектах разработки?
A: Вы, конечно, могли бы, если бы у вас были сильные чувства по этому поводу, но TestNG (и JUnit 4) имеют некоторые неотразимые особенности! Например, TestNG проводит феноменальное параметрическое тестирование и поддерживает параллельное тестирование, группы тестирования и т. Д. Это зрелые, хорошо продуманные фреймворки, которые предлагают некоторые замечательные функции, которые нельзя упускать из виду. Я все еще использую обе структуры, где это уместно, и призываю людей делать то же самое.
В: Есть ли интеграция с JUnit или TestNG, чтобы истории easyb стали частью наборов тестов и непрерывной интеграции?
A: На данный момент нет интеграции с JUnit или TestNG; тем не менее, вы, безусловно, можете запускать свои истории easyb через Ant (готовится плагин Maven) следующим образом:
<easyb failureProperty="easyb.failed">
<classpath>
<path refid="build.classpath" />
<pathelement path="target/classes" />
</classpath>
<report location="target/story.txt" format="txtstory" />
<behaviors dir="behavior">
<include name="**/*Story.groovy" />
</behaviors>
</easyb>
Таким образом, вы можете легко настроить процесс CI, который запускает истории easyb по расписанию или при изменении кода.
В: Есть ли в easyb интеграция с IDE?
A: Не в данный момент, к сожалению. Он запускается через класс Java, поэтому вы можете легко создать профиль в Eclipse для запуска историй.
Спасибо за отличное интервью, Андрей!