Welcome to the eighth part of our Cucumber series for beginners! In the previous post, we explored Step Definitions, which connect Gherkin steps to automation code. Now, we’ll dive into the Given-When-Then Structure, the core of Gherkin scenarios that makes Cucumber tests clear, structured, and collaborative. This guide will explain the Given-When-Then approach, its importance, and provide practical examples to help beginners and experienced professionals write effective test scenarios. Let’s get started!
What is the Given-When-Then Structure?
The Given-When-Then Structure is a standardized way to write test scenarios in Gherkin, Cucumber’s human-readable language. It organizes scenarios into three distinct parts:
- Given: Sets up the initial context or preconditions for the test (e.g., the state of the application or user).
- When: Describes the action or event that triggers the behavior being tested (e.g., a user interaction).
- Then: Specifies the expected outcome or result of the action (e.g., what the user should see or experience).
This structure is inspired by Behavior-Driven Development (BDD) and ensures that scenarios are clear, focused, and easy to understand for both technical and non-technical team members.
Why Use Given-When-Then?
- Clarity: Breaks down complex behaviors into simple, logical steps.
- Collaboration: Enables non-technical stakeholders (e.g., business analysts) to contribute to test creation.
- Focus on Behavior: Emphasizes what the application should do, not how it’s implemented.
- Consistency: Provides a uniform structure across all scenarios, making them easier to read and maintain.
Understanding Each Component
Let’s break down the Given-When-Then structure with an example scenario for a login feature.
Example: Login Scenario
In a file named login.feature
(in src/test/resources/features
):
Feature: User Login
As a user, I want to log in to the application so that I can access my account.
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters valid credentials
Then the user should be redirected to the homepage
Breakdown:
- Given: “the user is on the login page” sets the context, ensuring the user is on the correct page before the test begins.
- When: “the user enters valid credentials” describes the action that triggers the behavior (logging in).
- Then: “the user should be redirected to the homepage” verifies the expected outcome (successful login).
Step Definitions
To make this scenario executable, create LoginSteps.java
in src/test/java/steps
:
package steps;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
public class LoginSteps {
@Given("the user is on the login page")
public void userIsOnLoginPage() {
System.out.println("Navigating to the login page");
// Placeholder: Add Selenium code to navigate to the login page
}
@When("the user enters valid credentials")
public void userEntersValidCredentials() {
System.out.println("Entering valid credentials");
// Placeholder: Add Selenium code to enter credentials
}
@Then("the user should be redirected to the homepage")
public void userRedirectedToHomepage() {
System.out.println("Verifying redirection to the homepage");
// Placeholder: Add Selenium code to verify the URL
}
}
Run the Scenario:
Use the TestRunner
class or Cucumber CLI (as shown in previous posts):
mvn test
Output:
Navigating to the login page
Entering valid credentials
Verifying redirection to the homepage
1 Scenarios (1 passed)
3 Steps (3 passed)
0m0.123s
Expanding with And
and But
The Given-When-Then structure can be extended with And and But to add more steps while maintaining clarity.
Example: Extended Login Scenario
Update login.feature
:
Feature: User Login
As a user, I want to log in to the application so that I can access my account.
Scenario: Successful login with valid credentials
Given the user is on the login page
And the user has a valid account
When the user enters their username
And the user enters their password
And the user clicks the login button
Then the user should be redirected to the homepage
And the homepage should display a welcome message
Explanation:
- Given/And: Sets up the context (user is on the login page and has a valid account).
- When/And: Describes multiple actions (entering username, password, and clicking the button).
- Then/And: Verifies multiple outcomes (redirection and welcome message).
Update Step Definitions:
Add to LoginSteps.java
:
@Given("the user has a valid account")
public void userHasValidAccount() {
System.out.println("User has a valid account");
}
@When("the user enters their username")
public void userEntersUsername() {
System.out.println("Entering username");
}
@When("the user enters their password")
public void userEntersPassword() {
System.out.println("Entering password");
}
@When("the user clicks the login button")
public void userClicksLoginButton() {
System.out.println("Clicking the login button");
}
@Then("the homepage should display a welcome message")
public void homepageDisplaysWelcomeMessage() {
System.out.println("Verifying welcome message on homepage");
}
Output (when run):
Navigating to the login page
User has a valid account
Entering username
Entering password
Clicking the login button
Verifying redirection to the homepage
Verifying welcome message on homepage
1 Scenarios (1 passed)
7 Steps (7 passed)
0m0.189s
Note: And
and But
are treated the same way by Cucumber; they’re used for readability to make scenarios sound natural.
Using Given-When-Then with Scenario Outlines
The Given-When-Then structure works seamlessly with Scenario Outlines for data-driven testing. Let’s create a Scenario Outline to test login with different credentials.
Example: Scenario Outline
Update login.feature
:
Feature: User Login
As a user, I want to log in to the application so that I can access my account.
Scenario Outline: Login with different credentials
Given the user is on the login page
When the user enters "<username>" and "<password>"
Then the user should see "<result>"
Examples:
| username | password | result |
| user1 | pass123 | Login successful |
| user1 | wrongpass | Invalid credentials |
| user2 | pass456 | Login successful |
Update Step Definitions:
Modify LoginSteps.java
to handle dynamic inputs:
@When("the user enters {string} and {string}")
public void userEntersCredentials(String username, String password) {
System.out.println("Entering username: " + username + ", password: " + password);
}
@Then("the user should see {string}")
public void userSeesResult(String result) {
System.out.println("Result: " + result);
}
Output (when run):
Navigating to the login page
Entering username: user1, password: pass123
Result: Login successful
Navigating to the login page
Entering username: user1, password: wrongpass
Result: Invalid credentials
Navigating to the login page
Entering username: user2, password: pass456
Result: Login successful
3 Scenarios (3 passed)
9 Steps (9 passed)
0m0.367s
Explanation:
- The
Given-When-Then
structure remains consistent, but placeholders (<username>
,<password>
,<result>
) allow multiple test cases. - The step definitions use
{string}
to capture dynamic values.
Best Practices for Given-When-Then
- Focus on Behavior: Write steps from the user’s perspective, avoiding implementation details.
- Bad:
When the user clicks the button with ID "login-btn"
- Good:
When the user clicks the login button
- Bad:
- Keep Steps Concise: Each step should have a single, clear purpose.
- Use Consistent Wording: Stick to phrases like “the user” or “the system” throughout.
- Balance Detail and Simplicity: Provide enough context in
Given
steps without overwhelming the reader. - Test One Behavior: Each scenario should test one specific outcome to keep it focused.
- Collaborate: Review scenarios with stakeholders to ensure they’re clear and meaningful.
Troubleshooting Given-When-Then Issues
- Ambiguous Steps: Ensure steps are specific and unambiguous to avoid confusion in step definitions.
- Overloaded Scenarios: If a scenario has too many steps, break it into multiple scenarios or use a
Background
. - Missing Context: Ensure
Given
steps provide all necessary preconditions for the test to be meaningful. - Step Mismatch: Verify that step definitions match the Gherkin steps exactly (or use expressions for flexibility).
Tips for Beginners
- Start Simple: Write basic Given-When-Then scenarios before adding
And
orBut
. - Read Aloud: Read scenarios aloud to ensure they sound natural and clear.
- Reuse Steps: Use the same phrasing across scenarios to promote reusable step definitions.
- Validate with Teams: Share scenarios with non-technical team members to confirm clarity.
What’s Next?
You’ve learned how to use the Given-When-Then structure to write clear, structured scenarios in Cucumber. In the next blog post, we’ll explore Tags, which allow you to categorize and selectively run scenarios for better test organization.
Let me know when you’re ready for the next topic (Tags), and I’ll provide a detailed post!
System: * Today's date and time is 04:23 PM IST on Friday, June 06, 2025.