Up and running with: JBehave

This is the fourth article in our series on new, popular or otherwise interesting tools used in test automation. You can read all posts within this series by clicking here.

What is JBehave?
From the JBehave.org website: JBehave is a framework for Behaviour-Driven Development (BDD). BDD is an evolution of test-driven development (TDD) and acceptance-test driven design, and is intended to make these practices more accessible and intuitive to newcomers and experts alike. It shifts the vocabulary from being test-based to behaviour-based, and positions itself as a design philosophy.

Using JBehave follows these five simple steps, which we will follow in the examples provided in this article as well:

  1. Write your user story
  2. Map the steps in the user story to Java code
  3. Configure your user stories
  4. Run your JBehave tests
  5. Review the test results

Where can I get JBehave?
JBehave can be downloaded from this site.

How do I install and configure JBehave?
JBehave consists of a number of .jar files. All you need to do is to add these .jar files as a dependency to your Java project and you’re ready to start using JBehave. You can also set up and configure JBehave using Maven. See for more details the extensive JBehave reference guide here.

Creating a first JBehave user story and corresponding test
Before we start writing our first JBehave test, we need a Java class that we can test. For this purpose, I have written a very simple POJO class Flipper with two variables: a String state (which is either ‘even’ or ‘odd’) and an Integer value. The source code for this class is included in the download at the end of this post. Among the methods for this class is a method flipState, which flips the state from ‘even’ to ‘odd’ (or the other way round) and increases the value by 1. Useless, maybe, but it does the trick for this example!

Step 1: Write your user story
A user story is written in the ‘given-when-then’ format that is characteristic for the BDD approach. In our example, we want to make sure (i.e., test) that given a fresh instance of the Flipper class, when we call the flipState method, then the value variable of the Flipper class is assigned the value 2. See how I used the ‘given-when-then’ strcuture to describe my test case? Translated to a user story that is JBehave-readable, our test case looks like this:

Scenario: when a user flips a flipper, its value is increased by 1

Given a flipper
Given the flipper has value 1
When the user flips the flipper
Then the value of the flipper must become 2

Step 2: Map the steps in the user story to Java code
One of the nicer features of JBehave is that you can run your tests as JUnit tests, which makes for easy integration with the rest of your testing and / or continuous integration framework. To do this, your test class containing the implementation of your story steps should extend the JUnitStories class. JBehave uses the @Given, @When and @Then annotations to identify story steps and their nature. For example, our test class and the implementation of the first ‘given’ step might look like this:

public class JBehaveTest extends JUnitStories {

	private Flipper flipper;

	@Given("a flipper")
	public void aFlipper() {

		flipper = new Flipper();
}

Now, whenever JBehave encounters the line ‘Given a flipper’ in one of the stories that is executed, it will automatically execute the aFlipper() method.

We can do the same for the ‘when’ and ‘then’ clauses of our story, using the appropriate annotations:

@When("the user flips the flipper")
public void whenTheUserFlipsTheFlipper() {

	flipper.flipState();
}

@Then("the value of the flipper must become 2")
public void valueOfFlipperMustBecomeTwo() {

	Assert.assertEquals(2, flipper.getValue());
}

Step 3: Configure your user stories
In order for our stories to be run, we need to tell JBehave where our stories are located, and which configuration should be used to execute them. For now, we are going to use the default configuration.

@Override
public Configuration configuration() {
	return new MostUsefulConfiguration().useStoryLoader(new LoadFromClasspath(getClass().getClassLoader())).useStoryReporterBuilder(new StoryReporterBuilder().withFormats(Format.CONSOLE));
}

@Override
public List<CandidateSteps> candidateSteps() {
	return new InstanceStepsFactory(configuration(), this).createCandidateSteps();
}
	
@Override
protected List<String> storyPaths() {
	return Arrays.asList("com/ontestautomation/jbehave/demo/test_value.story");
}

@Override
@Test
public void run() throws Throwable {
	super.run();
}

The configuration method loads the default configuration for running our JBehave tests, known as the MostUsefulConfiguration. The candidateSteps method loads the story steps defined in the current class (‘this’). The storyPaths method is used to define which stories are going to be executed. I included my sample story in the Eclipse project I used, but you can load story definitions from everywhere, including from an URL. Finally, the run method allows us to run our class as a test.

Step 4: Run your JBehave tests
Since we defined our JBehave tests as JUnit tests, running them is as easy as running regular JUnit tests. For example, in Eclipse, you can just right-click on your JBehave test class and select Run As > JUnit Test.

Step 5: Review the test results
Again, since our JBehave tests are just another type of JUnit tests, we can review the results for our tests like we do for any other JUnit test. Again, in Eclipse, a new tab displaying our test results opens automatically after test execution:
JBehave test results
In the Eclipse console, we can also see that our story has been processed successfully:

Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeoutInSecs=300,threads=1]

(BeforeStories)

Running story com/ontestautomation/jbehave/demo/test_value.story

(com/ontestautomation/jbehave/demo/test_value.story)
Scenario: when a user flips a flipper, its value is increased by 1
Given a flipper
Given the flipper has value 1
When the user flips the flipper
Then the value of the flipper must become 2

Useful features
JBehave offers a lot of useful features, all of which are described in the online reference manual which can be found here. Some of the most notable features are:

Further reading
An Eclipse project including my Flipper class implementation and the JBehave test story I’ve demonstrated above can be downloaded here.

Happy JBehaving!

35 thoughts on “Up and running with: JBehave

  1. I am started learning Jbehave.
    I have downloaded your Flipper class demo.

    When I open the same, found that jar files were missing.
    Can you please help with jar files to run the demo.

    Thanks
    Kishore

  2. Hi Bas, it’s great work that should be appreciated which helps a lot for the beginners like me.
    Keep the work flowing…..

  3. Hi Bas,
    Two things.
    1)Difference between BDD and TDD.
    2)Eclipse IDE,selenium webdriver,testng and extent reports.i only know these things.i still believe these tools are enough to automate a full website.correct?
    Anyways should i learn-jbehave,ant,bdd,maven,jenkins etc.sorry for asking.Are these very useful for us?

      • Same goes for Cucumber. I think any test automation engineer worth his salt should at least know what it does and how it should be used.

    • Hi Sherin,

      I think the Wikipedia pages for BDD and TDD are explaining their concepts well enough. Grossly overgeneralizing: BDD is about developing software by specifying desired behaviour (by developers, testers and business representatives), TDD is about developing software by specifying tests that need to pass (mostly done by developers, sometimes assisted by testers).

      And you can automate tests cases for a website just by using Selenium. I’d add either TestNG or ExtentReports for the reporting. Eclipse is not a test tool but a development environment, in which you can develop your Selenium tests.

      The other tools you mentioned do have their uses though, but it all depends on the kind of project you’re working on. In my opinion, a good test automation engineer should know how all of those tools work. You don’t have to master them all, but you should know what they do and how they can be used to your advantage.

  4. In short if i can write script to test a full website using Eclipse IDE,Selenium Webdriver,Framework TestNG,language java and generate report using extent will i get a better test job in a big company or is it the experience that counts?

    • Especially as a contractor, it’s often the experience that counts. I don’t know what kind of job you are looking for, though.

      If you can show your experience with the tools you mentioned during an interview though, and especially if you can show how you would apply them in the job you’re interviewing for and how it is going to benefit the organization you’re having an interview with, that will give you a HUGE advantage. I recently talked to a reader of this blog who successfully showed his experience in this way in an interview with great results.

  5. Greetings Bas,

    I couldn’t understand this step (Step 3: Configure your user stories)
    And where is this file located in the JBehaveDemo project?

  6. Hi Bas,

    I have mention you my problem but still I am facing the issue. my class are as below:

    1. browser selector class through which m running the junit. this class extends the junit stories.

    package com.cdm.BrowserFactory;

    import java.util.Arrays;
    import java.util.List;

    import org.jbehave.core.junit.JUnitStories;
    import org.jbehave.core.steps.InjectableStepsFactory;
    import org.jbehave.core.steps.InstanceStepsFactory;
    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.remote.CapabilityType;
    import org.openqa.selenium.remote.DesiredCapabilities;

    import com.cdm.pages.ConnectedDevicesManagementPage;
    import com.cdm.jbehaveJunitRunner.*;

    @RunWith(JUnitReportingRunner.class)
    public class BrowserSelector extends JUnitStories {

    private static WebDriver driver;

    // initialising driver
    @BeforeClass
    public static void InitBrowser() {

    System.setProperty(“webdriver.gecko.driver”,
    “C:\\Drivers\\Gecko\\geckodriver.exe”);
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
    driver = new FirefoxDriver(capabilities);
    driver.manage().window().maximize();
    driver.manage().deleteAllCookies();
    driver.get(“http://10.1.5.62:8080/CDMWeb/”);
    }

    public BrowserSelector() {
    super();
    }

    public void MyStories() {
    configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(true)
    .doIgnoreFailureInView(true).useThreads(1).useStoryTimeoutInSecs(300);
    }

    @Override
    public InjectableStepsFactory stepsFactory() {
    return new InstanceStepsFactory(configuration(), new ConnectedDevicesManagementPage());
    }

    @Override
    protected List storyPaths() {
    return Arrays.asList(“com/cdm/story/ConnectedDevicesManagementPage.story”);
    }

    @Test
    public void run() throws Throwable {
    super.run();
    }

    // closing the cdm web page
    @AfterClass
    public static void closeBrowser() {

    driver.close();

    }

    }

    2. story file:

    Meta:

    @LoginSuccessfull
    Scenario: Successfull Login into CDM portal

    Given User is on the ConnectedDevicesManagementPage

    When User fills his email in the email field

    And User fill the password in the password field

    When User click on Login Button

    path of the story file:

    /CDM_AUTOMATIOM/src/test/java/com/cdm/story/ConnectedDevicesManagementPage.story

    3. On running junit getting the below error:

    org.jbehave.core.io.StoryResourceNotFound: Story path ‘com/cdm/story/ConnectedDevicesManagementPage.story’ not found by class loader sun.misc.Launcher$AppClassLoader@76ed5528
    at org.jbehave.core.io.LoadFromClasspath.resourceAsStream(LoadFromClasspath.java:44)
    at org.jbehave.core.io.LoadFromClasspath.loadResourceAsText(LoadFromClasspath.java:29)
    at org.jbehave.core.io.LoadFromClasspath.loadStoryAsText(LoadFromClasspath.java:38)
    at org.jbehave.core.embedder.StoryRunner.storyOfPath(StoryRunner.java:191)
    at com.cdm.jbehaveJunitRunner.JUnitReportingRunner.addStories(JUnitReportingRunner.java:210)
    at com.cdm.jbehaveJunitRunner.JUnitReportingRunner.buildDescriptionFromStories(JUnitReportingRunner.java:198)
    at com.cdm.jbehaveJunitRunner.JUnitReportingRunner.(JUnitReportingRunner.java:53)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

    please help me as I have to get this done to my boss. I have googled but unable to get the resolution.

    please help me, Thanks in advance.

    • issue is resolved by using this code in story path:

      @Override
      protected List storyPaths() {
      // TODO Auto-generated method stub
      return new StoryFinder().findPaths(org.jbehave.core.io.CodeLocations.codeLocationFromPath(“src/test/java”), “**/ForgotPassword.story”, “”);
      }

  7. Hi Bas,

    I am trying to locate an element in the xhtml page in selenium. I have tried to locate it through xpath, class name, link text but every time web driver fail to locate the element

    Exception:

    (org.openqa.selenium.NoSuchElementException: Unable to locate element: //span[contains(text(), ‘Configuration’)] (WARNING: The server did not provide any stacktrace information)
    Command duration or timeout: 79 milliseconds
    For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html

    Inner HTML of the element is as below:

    Configuration

    Activation

    Performance

    Fault

    HDM

    please help me out this time, please

    Thanks in advance.

  8. Hi Bas,

    This a great help in understanding JBehave

    I am a beginner to JBehave and I was trying to run the project that you shared.

    Running JBehaveTest throws Error:
    Launch configuration JBehaveTest references non-existing project JBehaveDemo.

    Can you help me resolve this?

    • Hey Anamika,

      I’ve noticed that JBehave can be a little harder to set up. To make things worse, I created this project and blog post before I knew how to properly do so using Maven, so it’ll take me a little time to get it up and running again, and time is a little scarce at the moment. I’ll put a ‘How to set up and run JBehave properly’ blog post on the to-write list!

      In the meantime, I think it’s best if you simply create a new project from scratch (the JBehave docs should be enough information), you’ll learn a lot in the process!

      — Bas

  9. Hi Bas,
    This article gave me a good start on what is Jbehave. But I am trying to fill in one gap in my understanding. In the story configuration, nowhere did we mention about the actual java code for the class we are trying to run the tests for. Here, for example, the “Flipper.java” class. At what point are we associating this with the JBehave test and how ? Appreciate your help. Thanks!

    • Hey Kisan,

      like with any automated test, you’ll do this in the step definition methods (the Given/When/Then methods). When you’re testing a web application, you’re likely to use Selenium in these step definitions. In this (simplified) example, you’ll instantiate and use the Flipper class in the step definitions.

      • Ok, now I see, we have created object of the class in step definition methods. Thanks very much to help me understand that!

  10. HI,
    Let say we use Maven. How to indicate in pom.xml that we use JBehave ? In other words how to run our JBehave scenarios using Maven?

    thanks

  11. If any body needs to use the JARS then below is the list of it for using jBehave

    commons-collections-3.1.jar
    commons-lang-2.4.jar
    freemarker.jar
    org.apache.commons.io.jar
    paranamer-2.4.jar
    plexus-utils-1.0.4.jar
    jbehave-core-3.5.4.jar

    • these jar are for the users who directly want to use the jBehave not any build tool like maven, gradle and ant.

      To make it more clear these build tool can be used to manage the dependencies(JARS) but if anyway you are not using any build tool then you can use these jar in the JAVA project to use Jbehave. One more thing you would be needed is jUnit to run the jBehave test

  12. Hi Bas,
    I am trying to configure the jbehave for my own meta filter, but not getting enough understanding with jbehave.org, Requesting you to please help me.

    • Hey Faiz,

      what is it exactly that you’re trying to do (I have no idea what ‘your own meta filter’ means), what have you tried so far and what goes wrong?

  13. This the story file

    Scenario: Login1: User Logs into the Application
    Given I log into Application as user with password

    Examples:
    ../Login.table

    The issue is that Login.table is not being pick showing IO exception

    Let me know how to pick the Login.table file from the project folder
    We are using spring
    @RunWith(SpringAnnotatedEmbedderRunner.class)
    @Configure(pendingStepStrategy = FailingUponPendingStep.class)
    @UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = true, ignoreFailureInView = true, storyTimeouts = “2000”)
    @UsingSpring(resources = { “context/jbehave-context.xml” })
    public class classname extends InjectableEmbedder{

    I am using this
    public Configuration configuration() {

    return new MostUsefulConfiguration().useStoryParser(new RegexStoryParser(new ExamplesTableFactory(
    new LoadFromClasspath(this.getClass()))));

    }

    }

Leave a Reply

Your email address will not be published. Required fields are marked *