Какая структура BDD позволяет упростить подход к "написанию истории"?
Я пытаюсь использовать BDD очень простым способом, чтобы свести к минимуму количество Java-кода. Я хочу создать ровно два файла, один из них - моя история:
Given user is named "John Doe"
And user is authenticated
When user changes his password to "a1b2c3"
Then user password equals to "a1b2c3"
Далее я создаю класс Java:
public class UserManipulator {
@Given("$user is named $name")
public User shouldExistOrBeCreated(String name) {
User user = //...
return user;
}
@Given("$user is authenticated")
public void shouldBeLoggedIn() {
// ...
}
@When("$user changes his password to $pwd")
public void shouldChangePassword(User user, String pwd) {
// ...
}
@Then("$user password equals to $pwd")
public void shouldHaveThisPassword(User user, String pwd) {
assertEquals(user.getPassword(), pwd);
}
}
И что это. Я не хочу иметь больше файлов, больше тестов модулей. Я хочу, чтобы некоторые BDD-рамки находили мой файл истории, разбирали все мои файлы Java и запускали их один за другим. Можно ли достичь?
пс. Здесь важны возможные повторное использование методов Java в других моих историях. Например, это история №2:
Given user is named "Michael Doe" <-- reuse
When user adds $100.00 to his account
Then user account balance is $100.00
Ответы
Ответ 1
Мы используем Cucumber, который является структурой Ruby, но, связав JRuby с вашим проектом, вы можете легко получить доступ к своим Java-объектам. Это означает, что вы пишете свои определения шагов в Ruby, но это также минимизирует количество Java, которое вы пишете:)
Формат истории в Cucumber точно так же, как вы описываете в своем примере, а повторное использование сюжетных линий тривиально.
Ответ 2
Робот-диаграмма может представлять интерес. Вы можете прочитать информацию в руководстве пользователя здесь:
http://robotframework.googlecode.com/svn/tags/robotframework-2.5.4/doc/userguide/RobotFrameworkUserGuide.html#behavior-driven-style
Robotframework написан на питоне, и новые ключевые слова могут быть реализованы в python или jython.
Существует также тезис об использовании RF для ATDD:
http://www.niksula.cs.hut.fi/~jprantan/thesis/thesis_juha_rantanen.pdf
Ответ 3
Вы хотите посмотреть:
Кроме того, это презентация на BDD в Java и Groovy может представлять интерес.
Ответ 4
Не то, что вы ищете, но вы можете взглянуть на Spock.
Ответ 5
В новых версиях JBehave вы можете использовать класс JUnitStories, который позволяет одному классу Java действовать как бегун для нескольких текстовых историй. Будет ли это делать то, что вам нужно?
Ответ 6
Я не думаю, что он обеспечивает уровень повторного использования, который вы ищете, но также смотрите Concordion, BDD рамки, подобные Fitnesse, но гораздо проще в использовании (спецификации написаны в виде обычного текста, в виде HTML-страниц). И он интегрируется непосредственно с JUnit и, следовательно, с Maven.
См. также
Ответ 7
JCM огурца - именно то, что вы ищете. Простые шаги, которые можно использовать повторно, прозрачно работают с JUnit, хорошо интегрируются с Spring (и многими другими). Единственный дополнительный файл, который должен быть добавлен, - это класс, аннотированный с помощью @RunWith (Cucumber.class) - один класс независимо от того, сколько тестов и шагов у вас есть.
Ответ 8
jBehave или огурец могут использоваться. Оба они хороши.
Для jbehave вы можете посетить: http://jbehave.org/
Теперь я использую jBehave. Я очень мало знаю о Огурце. Я мало изучил "Огурец-JVM".
Угадайте, оба они приятные
Ответ 9
Вы можете посмотреть JGiven. Вместо текстового файла для вашего сценария вы должны написать тест JUnit следующим образом:
public class UserManipulatorTest
extends ScenarioTest<GivenUser, WhenPasswordChange, ThenUser> {
@Test
public void user_can_change_his_password() {
given().user_is_named( "John Doe" )
.and().user_is_authenticated();
when().user_changes_his_password_to( "a1b2c3" );
then().user_password_equals_to( "a1b2c3" );
}
}
Затем вы пишете определения шага в так называемых этапах. Обычно у вас есть для каждого этапа один класс, чтобы они были лучше повторного использования. Поэтому в вашем случае я бы определил три этапа:
public class GivenUser extends Stage<GivenUser> {
@ProvidedScenarioState
User user;
public GivenUser user_is_named(String name) {
user = //...
return self();
}
public GivenUser user_is_authenticated() {
// ...
return self();
}
}
public class WhenPasswordChange extends Stage<WhenPasswordChange> {
@ExpectedScenarioState
User user;
public WhenPasswordChange user_changes_his_password_to(String pwd) {
// ...
return self();
}
}
public class ThenUser extends Stage<ThenUser> {
@ExpectedScenarioState
User user;
public ThenUser user_password_equals_to(String pwd) {
assertEquals(user.getPassword(), pwd);
return self();
}
}
Теперь вы можете повторно использовать эти сценические классы в других сценариях. В вашем примере вы можете повторно использовать класс StageEventer, и вы бы определили новые классы этапа WhenBalanceChange и ThenBalance:
public class BalanceTest
extends ScenarioTest<GivenUser, WhenBalanceChange, ThenBalance> {
@Test
public void user_can_add_balance_to_his_account() {
given().user_is_named("Michael Doe");
when().user_adds_$_to_his_account("$100.00");
then().user_account_balance_is("$100.00");
}
}
Обратите внимание, что в JGiven символ $в имени метода является заполнителем аргумента метода и будет заменен им в сгенерированном отчете.
Отказ от ответственности: Я автор JGiven.