11

I'm trying to use BDD in a very simple way, in order to minimize the amount of Java code. I want to create exactly two files, one is my story:

Given user is named "John Doe" 
And user is authenticated
When user changes his password to "a1b2c3"
Then user password equals to "a1b2c3"

Next, I create a Java class:

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);
  }
}

And that's it. I don't want to have any more files, any more unit tests. I want some BDD-framework to find my story file, parse all my Java files, and run them one by one. Is it possible to achieve?

ps. What is important here is a possible reuse of Java methods in my other stories. For example, this is the story no.2:

Given user is named "Michael Doe"   <-- reuse
When user adds $100.00 to his account
Then user account balance is $100.00
4

9 回答 9

5

你想看看:

此外,这个关于 Java 和 Groovy 中的 BDD 的演示文稿可能会很有趣。

于 2010-10-08T12:28:50.697 回答
5

机器人框架可能很有趣。您可以在此处阅读用户指南中的详细信息: http ://robotframework.googlecode.com/svn/tags/robotframework-2.5.4/doc/userguide/RobotFrameworkUserGuide.html#behavior-driven-style

Robotframework 是用 python 编写的,新的关键字可以用 python 或 jython 实现。

这里还有一篇关于使用 RF 进行 ATDD 的论文:http: //www.niksula.cs.hut.fi/~jprantan/thesis/thesis_juha_rantanen.pdf

于 2010-10-10T19:27:11.373 回答
5

我们使用Cucumber,它是一个 Ruby 框架,但是通过将 JRuby 捆绑到您的项目中,您可以轻松访问您的 Java 对象。这确实意味着您在 Ruby 中编写步骤定义,但它也最大限度地减少了您编写的 Java 量 :)

Cucumber 中的故事格式与您在示例中描述的完全一样,并且重复使用故事情节是微不足道的。

于 2010-10-10T08:25:37.610 回答
4

在较新版本的 JBehave 中,您可以使用 JUnitStories 类,它允许一个 Java 类充当多个纯文本故事的运行器。这会做你需要的吗?

于 2010-12-22T18:03:32.993 回答
3

不是您真正想要的,但您可能想看看Spock

于 2010-10-10T06:44:11.910 回答
2

可以使用 jBehave 或 Cucumber。他们俩都很好。

对于 jbehave,您可以访问:http: //jbehave.org/

我现在正在使用 jBehave。我对黄瓜知之甚少。我对“Cucumber-JVM”的研究很少。

猜猜两个都不错

于 2012-12-18T10:39:04.837 回答
2

Cucumber JVM正是您正在寻找的。可以重用的简单步骤,与 JUnit 透明地工作,与 Spring(和许多其他)很好地集成。唯一需要添加的附加文件是一个用 @RunWith(Cucumber.class) 注释的类——不管你有多少测试和步骤,一个类。

于 2012-09-29T09:19:11.757 回答
2

我不认为它提供了您正在寻找的重用级别,但也可以看看Concordion,一个类似于 Fitnesse 但更易于使用的 BDD 框架(规范以纯文本形式编写,以 HTML 页面的形式) . 它直接与 JUnit 集成,因此也与 Maven集成。

也可以看看

于 2010-10-10T07:55:38.507 回答
1

你可以看看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();
    }
}

现在您可以在其他场景中重用这些阶段类。在您的示例中,您可以重用 GivenUser 阶段类,并且您将定义新的阶段类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 的作者。

于 2014-04-18T23:16:44.810 回答