Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Learn JBehave testing with this guide. Set up BDD in Java, write Given-When-Then stories, run tests on a cloud Selenium Grid, and debug common pitfalls.

Ravi Kumar
March 15, 2026
JBehave testing binds behavior scenarios to Java test scripts. It turns acceptance criteria into executable tests inside your build pipeline.
When a JBehave scenario fails, it maps to a real business flow breaking, not a CSS selector changing.
What Is JBehave Framework
JBehave is a Java-based BDD framework that uses Given-When-Then syntax to create executable test stories, bridging the gap between business requirements and test automation.
How to Get Started With JBehave Testing?
Setting up JBehave involves creating a Maven project, writing story files, and configuring a runner class. Follow these steps to get started:
JBehave is the Behavior-Driven Development (BDD) framework built for Java. It expresses tests as plain-language user stories that double as living documentation.
It uses its own plain-text story format that employs Given-When-Then keywords to structure each scenario. Each keyword carries a distinct responsibility in the test flow.
Here is the component breakdown of JBehave:

JBehave integrates natively with Java, uses plain-language Given-When-Then stories, and aligns developers, QA, and business teams around shared executable specifications.
If you are exploring other BDD frameworks for Java, you can also refer to this guide on Cucumber testing for comparison.
Clone the sample project, run mvn clean install to download JBehave Core and Selenium dependencies, and optionally set cloud credentials to run tests on a remote grid.
You need Java 17 or later and Maven 3.8 or later installed on your machine.
An IDE such as IntelliJ IDEA or Eclipse with the JBehave Support plugin is strongly recommended for step navigation and syntax validation.
For this guide, I'll run tests on a cloud Selenium Grid offered by TestMu AI (Formerly LambdaTest).
TestMu AI is a full-stack agentic AI quality engineering platform that helps teams test smarter and deliver faster. It runs Selenium testing with Behave on real browsers instantly, with no local infrastructure setup needed.
Note: Run JBehave tests across 3000 real environments. Try TestMu AI Now!
Clone the sample project to get a working JBehave structure:
git clone https://github.com/Ravikumar7210/LambdaTest_JBehave_Testing.git
cd jbehave-login-testThis project includes:
Ensure Maven is installed, then run:
mvn clean installThis downloads all required libraries, including:
Skip this step if you are running tests locally. To run on a cloud Selenium Grid like TestMu AI, set your credentials as environment variables:
set LT_USERNAME=your_user_name
set LT_ACCESS_KEY=your_access_keyOr add them permanently via System Properties → Environment Variables. Never hardcode credentials in source files.
Write a .story file with Given-When-Then steps, implement Java step definitions, configure a JUnitStories runner, and execute with mvn test locally or on a cloud grid.
Use Spring Initializr or your IDE to create a new Maven project. Add the following dependencies in pom.xml:
<properties>
<java.version>17</java.version>
<spring-boot.version>3.3.4</spring-boot.version>
<jbehave.version>5.2.0</jbehave.version>
<selenium.version>4.26.0</selenium.version>
<webdrivermanager.version>5.9.1</webdrivermanager.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot core -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- JBehave core + Spring integration -->
<dependency>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-core</artifactId>
<version>${jbehave.version}</version>
</dependency>
<dependency>
<groupId>org.jbehave</groupId>
<artifactId>jbehave-spring</artifactId>
<version>${jbehave.version}</version>
</dependency>
<!-- Selenium WebDriver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
</dependency>
<!-- WebDriverManager (optional for local runs) -->
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>${webdrivermanager.version}</version>
</dependency>
<!-- Testing stack -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Create a file at src/main/resources/stories/login.story:
Narrative:
In order to access my account
As a registered user
I want to log in and see my dashboard
Scenario: Valid login
Given the user is on the login page
When the user enters valid credentials
Then the user should see the dashboardThis story describes a user journey in plain language. I keep steps free of selectors, waits, and browser configuration — that boundary is what makes stories readable to non-engineers.
Create a class at: src/test/java/steps/LoginSteps.java
This class maps each .story step to a Java method using JBehave annotations. The annotation text must match the story wording exactly.
@Component
public class LoginSteps {
@Autowired
private WebDriver driver;
private WebDriverWait wait;
@BeforeScenario
public void beforeScenario() {
driver.manage().window().maximize();
wait = new WebDriverWait(driver, Duration.ofSeconds(20));
ltLog("Starting scenario: Valid login");
}
@AfterScenario
public void tearDown() {
if (driver != null) {
ltLog("Closing WebDriver after scenario");
driver.quit();
}
}
@Given("the user is on the login page")
public void openLoginPage() throws InterruptedException {
driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
Thread.sleep(1000);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("input-email")));
ltLog("Navigated to login page and email field visible");
}
@When("the user enters valid credentials")
public void enterCredentials() {
driver.findElement(By.id("input-email")).sendKeys("[email protected]");
driver.findElement(By.id("input-password")).sendKeys("Ravil@1234");
driver.findElement(By.cssSelector("input[type='submit']")).click();
ltLog("Entered credentials and submitted login form");
}
@Then("the user should see the dashboard")
public void verifyDashboard() {
try {
By heading = By.cssSelector("h2");
By breadcrumbLast = By.cssSelector("ul.breadcrumb li:last-child");
wait.until(ExpectedConditions.or(
ExpectedConditions.textToBePresentInElementLocated(heading, "My Account"),
ExpectedConditions.textToBePresentInElementLocated(breadcrumbLast, "Account")
));
ltLog("Dashboard verified (heading/breadcrumb matched)");
ltMarkStatus("passed", "Login scenario completed successfully");
} catch (TimeoutException e) {
ltLog("Dashboard verification timed out");
ltMarkStatus("failed", "Dashboard not visible after login");
throw e;
}
}
private void ltLog(String message) {
try {
((JavascriptExecutor) driver).executeScript("lambda-comment=" + message);
} catch (Exception ignored) { }
}
private void ltMarkStatus(String status, String reason) {
try {
((JavascriptExecutor) driver).executeScript("lambda-status=" + status);
((JavascriptExecutor) driver).executeScript("lambda-comment=" + reason);
} catch (Exception ignored) { }
}
}Create a runner class at: src/test/java/runners/LoginStoryRunner.java
This class tells JBehave where to find stories, which step classes to use, and what report formats to produce.
@SpringBootTest
public class JBehaveRunnerTest {
@Autowired
private ApplicationContext context;
@Test
void runStories() {
Configuration configuration = new MostUsefulConfiguration()
.useStoryLoader(new LoadFromClasspath(this.getClass()))
.useStoryReporterBuilder(new StoryReporterBuilder()
.withDefaultFormats()
.withFormats(Format.CONSOLE, Format.TXT, Format.HTML)
.withPathResolver(new FilePrintStreamFactory.ResolveToSimpleName())
);
InjectableStepsFactory stepsFactory = new SpringStepsFactory(configuration, context);
StoryFinder finder = new StoryFinder();
// Pick up all .story files under /stories/
List<String> stories = finder.findPaths(
codeLocationFromClass(this.getClass()),
"stories/*.story",
""
);
Embedder embedder = new Embedder();
embedder.useConfiguration(configuration);
embedder.useStepsFactory(stepsFactory);
embedder.runStoriesAsPaths(stories);
// Quit driver after all stories
WebDriver driver = context.getBean(WebDriver.class);
if (driver != null) {
System.out.println("Closing WebDriver session at end of run");
driver.quit();
}
}
}Run the below command to execute the test:
mvn testThis will:

Open target/jbehave/view/index.html in your browser. It groups failures by story and scenario so you can trace which flow broke.

The TestMu AI Web Automation dashboard shows session details, execution logs, video recordings, and screenshots for each JBehave test run.

Most JBehave failures trace back to the same recurring mistakes. I've seen these patterns across projects of different sizes, and knowing them before you hit them saves significant debugging time.
When a test fails, the root cause is rarely obvious. In my experience, these tips help you pinpoint the problem quickly without guesswork.
This guide covered JBehave from the ground up, including its architecture, the reasons Java teams choose it for BDD, and how its Given-When-Then model maps business requirements to executable tests.
The walkthrough covered setting up a Maven project, writing story files, mapping steps to Java methods, configuring a runner class, and executing tests with HTML reports.
Common pitfalls like misconfigured runners, unmatched step definitions, and poor story organization were also addressed alongside practical debugging techniques for tracing failures quickly.
Teams scaling JBehave beyond local execution often rely on cloud platforms for Java automation testing online, where TestMu AI provides access to real browsers and OS combinations.
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance