Behavior-driven development (BDD) is an agile process designed to keep the focus on a stakeholder value throughout the whole project. The premise of BDD is that the requirement has to be written in a way that everyone—be they business representative, analyst, developer, tester, manager, and so on—understands it. The key is to have a unique set of artefacts that are understood and used by everyone—a collection of user stories. Stories are written by the whole team and used as both requirements and executable test cases. It is a way to perform TDD with a clarity that cannot be accomplished with unit testing. It is a way to describe and test functionality in (almost) natural language and make it runnable and repeatable.
A story is composed of scenarios. Each scenario represents a concise behavioral use case and is written in natural language using steps. Steps are a sequence of the preconditions, events, and outcomes of a scenario. Each step must start with the words Given, When, or Then. Given is for preconditions, When is for actions, and Then is for performing validations.
This was only a brief introduction. There is a whole chapter, Chapter 7, BDD - Working Together with the Whole Team, dedicated to this topic. Now, it is time to introduce JBehave and Cucumber as two of the many available frameworks for writing and executing stories.
JBehave is a Java BDD framework used for writing acceptance tests that are able to be executed and automated. The steps used in stories are bound to Java code through several annotations provided by the framework:
dependencies { ... testCompile 'org.jbehave:jbehave-core:3.9.5' ... }
@Given("I go to Wikipedia homepage") public void goToWikiPage() { open("http://en.wikipedia.org/wiki/Main_Page"); }
@When("I enter the value $value on a field named " +"$fieldName") public void enterValueOnFieldByName(String value, String fieldName){ $(By.name(fieldName)).setValue(value); } @When("I click the button $buttonName") public void clickButonByName(String buttonName){ $(By.name(buttonName)).click(); }
@Then("the page title contains $title") public void pageTitleIs(String title) { assertThat(title(), containsString(title)); }
Validations are declared using the Then
annotation. In this example, we are validating the page title as expected.
These steps can be found in the WebSteps
class in the https://bitbucket.org/vfarcic/tdd-java-ch02-example-web.git repository.
Once we have defined our steps, it is time to use them. The following story combines those steps in order to validate a desired behavior:
Scenario: TDD search on wikipedia
It starts with naming the scenario. The name should be as concise as possible, but enough to identify the user case unequivocally; it is for informative purposes only:
Given I go to Wikipedia homepage When I enter the value Test-driven development on a field named search When I click the button go Then the page title contains Test-driven development
As you can see, we are using the same steps text that we defined earlier. The code related to those steps will be executed in a sequential order. If any of them, the execution is halted and the scenario itself is considered failed.
Even though we defined our steps ahead of stories, it can be done the other way around with a story being defined first and the steps following. In that case, the status of a scenario would be pending, meaning that the required steps are missing.
This story can be found in the wikipediaSearch.story
file in the https://bitbucket.org/vfarcic/tdd-java-ch02-example-web.git repository.
To run this story, execute the following:
$> gradle testJBehave
While the story is running, we can see that actions are taking place in the browser. Once it is finished, a report with the results of an execution is generated. It can be found in build/reports/jbehave
.
For brevity, we excluded the build.gradle
code to run JBehave stories. The completed source code can be found in the https://bitbucket.org/vfarcic/tdd-java-ch02-example-web.git repository.
For further information on JBehave and its benefits, visit http://jbehave.org/.
Cucumber was originally a Ruby BDD framework. These days it supports several languages including Java. It provides functionality that is very similar to JBehave.
Let's see the same examples written in Cucumber.
The same as any other dependency we have used until now, Cucumber needs to be added to build.gradle
before we can start using it:
dependencies { ... testCompile 'info.cukes:cucumber-java:1.2.2' testCompile 'info.cukes:cucumber-junit:1.2.2' ... }
We will create the same steps as we did with JBehave, using the Cucumber way:
@Given("^I go to Wikipedia homepage$") public void goToWikiPage() { open("http://en.wikipedia.org/wiki/Main_Page"); } @When("^I enter the value (.*) on a field named (.*)$") public void enterValueOnFieldByName(String value, String fieldName){ $(By.name(fieldName)).setValue(value); } @When("^I click the button (.*)$") public void clickButonByName(String buttonName){ $(By.name(buttonName)).click(); } @Then("^the page title contains (.*)$") public void pageTitleIs(String title) { assertThat(title(), containsString(title)); }
The only noticeable difference between these two frameworks is the way Cucumber defines steps text. It uses regular expressions to match variables types, unlike JBehave that deduces them from a method signature.
The steps code can be found in the WebSteps
class in the https://bitbucket.org/vfarcic/tdd-java-ch02-example-web.git repository:
Let's see how the story looks when written using the Cucumber syntax:
Feature: Wikipedia Search Scenario: TDD search on wikipedia Given I go to Wikipedia homepage When I enter the value Test-driven development on a field named search When I click the button go Then the page title contains Test-driven development
Note that there are almost no differences. This story can be found in the wikipediaSearch.feature
file in the https://bitbucket.org/vfarcic/tdd-java-ch02-example-web.git repository.
As you might have guessed, to run a Cucumber story, all you need to do is run the following Gradle task:
$> gradle testCucumber
The result reports are located in the build/reports/cucumber-report
directory. This is the report for the above story.
The full code example can be found in the https://bitbucket.org/vfarcic/tdd-java-ch02-example-web.git repository.
For a list of languages supported by Cucumber or for any other details, visit https://cukes.info/.
Since both JBehave and Cucumber offer a similar set of features, we decided to use JBehave throughout the rest of this book. There is a whole chapter dedicated to BDD and JBehave.
3.12.163.175