哪种BDD框架允许采用简单的方法来编写“故事”?

时间:2010-10-08 12:22:11

标签: java testing bdd jbehave

我正在尝试以非常简单的方式使用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文件,然后逐个运行它们。有可能实现吗?

PS。这里重要的是我的其他故事中可能的重用 Java方法。例如,这是故事2:

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

9 个答案:

答案 0 :(得分:5)

您想看看:

此外,这个presentation on BDD in Java and Groovy可能会引起人们的兴趣。

答案 1 :(得分:5)

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

Cucumber中的故事格式正如您在示例中所描述的那样,重复使用故事情节是微不足道的。

答案 2 :(得分: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

答案 3 :(得分:4)

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

答案 4 :(得分:3)

不是你想要的,但你可能想看看Spock

答案 5 :(得分:2)

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

另见

答案 6 :(得分:2)

Cucumber JVM正是您所寻找的。可以重用的简单步骤,与JUnit透明地工作,与Spring(以及许多其他人)很好地集成。必须添加的唯一一个附加文件是使用@RunWith(Cucumber.class)注释的类 - 无论您有多少测试和步骤,都可以使用一个类。

答案 7 :(得分:2)

可以使用jBehave或Cucumber。两者都很好。

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

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

猜猜,他们俩都很好

答案 8 :(得分: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的作者。