JBehave – How to get started?

Reading Time: 4 minutes

Hi folks,

In this blog, we will explore yet another powerful BDD framework, JBehave. We will try to figure out the why’s and how’s of jBehave and later on will try some hands-on with selenium by integrating this framework with it. So, let’s get going.

What is jBehave?

As mentioned in the official documentation, JBehave is a framework for Behaviour-Driven-Development (BDD). BDD is an evolution of test-driven development (TDD) and acceptance-test driven design and, hence, the intent is 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.

Similar to other BDD frameworks, JBehave adopts the following concepts:

  • Story – represents an automatically executable increment of business functionality, comprises one or more scenarios
  • Scenarios – represent concrete examples of the behavior of the system
  • Steps – represent actual behavior using classic BDD keywords: GivenWhen and Then

JBehave is a pure Java framework and it is based upon JUnit itself. Now, let’s compare Jbehave with cucumber to get a better understanding of it.

JBehave vs Cucumber.

This segment pertains to answer the question, why JBehave? We cannot compare JBehave and cucumber to a full extent because they both are completely different frameworks. However, their existence serves the same purpose.

JBehave is pure java based framework and, on the other hand, cucumber is based on Ruby. Both are quite powerful BDD tools. For development purposes, you may use cucumber with JAVA by using cucumber-JVM, which is now pretty stable and easy to use. However, there still might be some mismatch as cucumber is using Ruby internally, cucumber-JVM is just a wrapper on the initial cucumber. All this rationale points to one conclusion only, if you are using a JAVA project it is safe to use JBehave with it.

Though, there is one thing where cucumber has an upper hand on JBehave, which is the test report. Cucumber has very attractive reporting, and on comparing it with JBehave, the HTML report generated by JBehave seems a bit old fashion. Hence, in conclusion, if you are working on a JAVA project, JBehave would be a better choice, if you ignore the reporting part.

I hope, you got some idea by JBehave now. Moving on, let’s see how we can use it with a testing framework, selenium.

JBehave with Selenium

If you have some experience with cucumber, then this will be a piece of cake for you. As you may already know, in BDD, mostly, we write tests in Gherkins syntax. Every step in the Gherkins links to a corresponding step definition. The step definition contains the main logic. In Gherkins, we have Given, When, Then and “And” keywords. There is no restriction on the usage of these keywords, we just need to link all these defined keywords in the tests to a corresponding step definition.

So, the first thing we need to do is, make our IDE recognise the .story file extension. For this, we need to add a plugin to our IDE, in my case it is Intellij, the plugin name is “JBehave Support”. Once installed, we can now add a .story file to your project.

Furthermore, we need to add Jebehave and selenium dependency. My pom.xml, looks something like this.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jBehave</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.jbehave/jbehave-core -->
        <dependency>
            <groupId>org.jbehave</groupId>
            <artifactId>jbehave-core</artifactId>
            <version>4.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>
    </dependencies>

</project>

Moving on, now create a folder named “resources” under “src” and inside the “test” folder. In resources, you can put all your .story files.

The sample story file that I’ve used for this demo, having the test scenario, looks like this.

Meta:

Narrative:
As a user
I want search Knoldus on google
So that I can search for my blogs

Scenario: DEMO Test
Given I open Google
When I search for my blogs
Then I assert the URL

Creating Step definition.

All the Given, When and Then statements specified in the story file need to be liked to the corresponding step definition. Lets us assume, the story file is named “Demo.story”. According to the standard best practices, the corresponding step definition class should be named “DemoSteps.java”. You can find the step definition file below.

package com.knoldus.StepDefinations;

import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class DemoSteps {

    WebDriver driver;

    @Given("I open Google")
    public void I_open_google() {
        System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver_linux64/chromedriver");
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://www.google.com/");
    }

    @When("I search for my blogs")
    public void I_serach_for_my_blogs(){
        driver.findElement(By.cssSelector("input[title='Search']")).sendKeys("Sparsh Bhardwaj blogs Knoldus");
        driver.findElement(By.cssSelector("input[title='Search']")).sendKeys(Keys.RETURN);

        driver.findElement(By.partialLinkText("Sparsh Bhardwaj, Author at Knoldus Blogs")).click();
    }

    @Then("I assert the URL")
    public void I_assert_the_URL(){
        String currentURL = driver.getCurrentUrl();
        Assert.assertEquals("https://blog.knoldus.com/author/sparsh79/",currentURL);
    }
}

And that’s pretty much it. We have now successfully written a test in Gherkins syntax using Jbehave and it should be able to execute now. But how should we run it? We cannot simply right-click on the story file and select the run option because you won’t find it there. In this case, we need to make our own runner.

JBehave Runner

JBehave’s documentation is very well structured, detailed and verbose. Hence, I didn’t find it much difficult to figure out the runner. Just like in cucumber, we need to define the cucumber runner using “cucumber.options”, similarly we need to do the same thing. The runner code is mentioned below.

package com.knoldus.Runner;

import com.knoldus.StepDefinations.DemoSteps;
import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.io.LoadFromClasspath;
import org.jbehave.core.junit.JUnitStories;
import org.jbehave.core.reporters.StoryReporterBuilder;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.InstanceStepsFactory;

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

import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
import static org.jbehave.core.reporters.Format.CONSOLE;

public class DemoTest extends JUnitStories {
    @Override
    public Configuration configuration() {
        return new MostUsefulConfiguration()
                .useStoryLoader(new LoadFromClasspath(this.getClass()))
                .useStoryReporterBuilder(new StoryReporterBuilder()
                        .withCodeLocation(codeLocationFromClass(this.getClass()))
                        .withFormats(CONSOLE));
    }

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

    @Override
        protected List<String> storyPaths() {
            StoryFinder finder = new StoryFinder();
            return finder.findPaths(codeLocationFromClass(this.getClass()).getFile(), Collections.singletonList("**/*.story"), Arrays.asList(""));
        }
}

In storyPaths(), we pass our .story file path to be parsed by JBehave. Actual steps implementation is provided in stepsFactory(). Then in configuration(), the story loader and story report are properly configured.

Now that we have everything ready, we can begin our story simply by running: mvn clean test.

That’s it, folks. I hope you may have found this useful. Do check out our other blogs, https://blog.knoldus.com/category/tech-blogs/test-automation/. Thanks!

Refrences

https://jbehave.org/reference/stable/

knoldus

Written by 

Sparsh is a QA Consultant having experience of more than 2 years. He is familiar with the core concepts of manual and automation, Karate, Cypress, Gatling, Rest Assured and Selenium are the tools that Sparsh is familiar with. He is always eager to learn new and advanced concepts in order to upskill himself.