开发者

Which BDD framework allows a simplistic approach to "story writing"? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers. 开发者_运维知识库

We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.

Closed 8 years ago.

Improve this question

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


You want to have a look at:

  • easyb,
  • or JBehave ant its Getting Started guide,
  • and maybe Specatular and its Getting Started guide.

Also, this presentation on BDD in Java and Groovy could be of interest.


We use Cucumber, which is a Ruby framework but by bundling JRuby into your project you can easily access your Java objects. It does mean you write your step definitions in Ruby, but it also minimises the amount of Java you write :)

The story format in Cucumber is exactly as you describe in your example, and re-use of story lines is trivial.


The robotframework may be of interest. You can read the details in the user guide here: http://robotframework.googlecode.com/svn/tags/robotframework-2.5.4/doc/userguide/RobotFrameworkUserGuide.html#behavior-driven-style

Robotframework is written in python and new keywords can be implemented in python or jython.

There is also a thesis on the use of RF for ATDD here: http://www.niksula.cs.hut.fi/~jprantan/thesis/thesis_juha_rantanen.pdf


In newer versions of JBehave, you can use the JUnitStories class, which lets one Java class act as the runner for multiple plain text stories. Would this do what you need?


Not really what you are looking for, but you may want to have a look at Spock.


I don't think it provides the level of reuse you're looking for but also have a look at Concordion, a BDD framework similar to Fitnesse but much easier to use (specifications are written in plain text, in the form of HTML pages). And it integrates just directly with JUnit and thus also with Maven.

See also

  • Concordion: Agile Acceptance Testing with free-form text.


Cucumber JVM is exactly what you are looking for. Simple steps that can be reused, works transparently with JUnit, integrates well with Spring (and many others). The only one additional file that has to be added is a class annotated with @RunWith(Cucumber.class) - one class no matter how many tests and steps you have.


jBehave or Cucumber can be used. Both of them are good.

For jbehave you can visit: http://jbehave.org/

I am using jBehave now. I know very little about Cucumber. I studied little about "Cucumber-JVM".

Guess, both of them are nice


You could have a look at JGiven. Instead of a text file for your scenario you would write a JUnit test like this:

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

Then you write your step definitions in a so-called stage classes. Typically you have for each stage one class so that they are better reusable. So in your case I would define three stage classes:

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

Now you can reuse these stage classes in other scenarios. In your example you could reuse the GivenUser stage class and you would define the new stage classes WhenBalanceChange and 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");
    }
}

Note that in JGiven the $ character in a method name is a placeholder for the method argument and will be replaced by it in the generated report.

Disclaimer: I am the author of JGiven.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜