What is BDD?
BDD is a software development technique that has evolved from TDD (Test Driven Development). To better understand BDD we should first understand TDD.
What is Test Driven Development
Test Driven Development (TDD) is a software development practice that focuses on creating unit test cases before developing the actual code. It is an iterative approach combining programming, unit test creation, and refactoring. TDD approach originates from the Agile manifesto principles. As the name suggests, the test process drives software development through test design development. In TDD, developers create small test cases for every feature based on their initial understanding. The primary intention of this technique is to modify or write new code only if the tests fail.
E-commerce Website Example
When building an e-commerce website, a TDD approach would involve writing test cases for various features such as product listings, shopping cart functionality, and checkout process. Tests would be written to ensure the system works correctly at each process stage, from adding items to the cart to completing the purchase.
For the example above, I have mentioned Waterfall as the SDLC (Software Development Life Cycle), where we derive the requirements first and then go to the next stage. In this process, testing comes to the last stage. This means that you may catch some design issues at the last stage of your development (if you write meaningful test cases). Inherently, this becomes quite tedious as this requires changes to have been made from the very beginning. It’s also a time consuming and very expensive process.
TDD Vs. Traditional Testing
- Approach: TDD is an agile development methodology where tests are written before the code is developed. In contrast, traditional testing is performed after the code is written.
- Testing Scope: TDD focuses on testing small code units at a time, while traditional testing covers testing the system as-a-whole, including integration, functional, and acceptance testing.
- Iterative: TDD follows an iterative process, where small chunks of code are developed, tested, and refined until all test cases are passed. The code is usually tested once and then refined based on the results in traditional testing.
- Debugging: TDD aims to catch errors as early as possible in the development process, making debugging and fixing them easier and less costly. Traditional testing, on the other hand, may require more effort to debug and fix errors that are discovered later in the development process.
Benefits of Test-Driven Development (TDD)
- Fosters the creation of optimized code. This means, we create a minimal amount of dead or unused code.
- It helps developers better analyze and understand client requirements and request clarity early on when not adequately defined.
- Adding and testing new functionalities become much easier in the latter stages of development as you have a suite of tests that document a path of success.
- Test coverage under TDD is much higher compared to conventional development models. TDD focuses on creating tests for each functionality right from the beginning.
What is BDD (Behaviour Driven Development)
Now that we know what TDD, is let’s return to BDD. We now know TDD is an approach or programming practice where the developers write new code only when the automated test case fails.
BDD’s approach involves the use of a shared language that enhances communication between various tech and non-tech teams. Tests are more user-focused and based on the system’s behaviour. In BDD, “Given-When-Then” is the proposed approach for writing test cases.
Consider the following example/scenario for more understanding:
A user is trying to log into a social networking website
- Given the user has entered invalid credentials
- When the user clicks the submit button
- Then display the proper validation (error) message
Benefits of BDD
- It focuses on defining ‘behaviour’ rather than defining ‘tests’
- Enhances communication among the members of a cross-functional product team, which improves collaboration across the teams and helps create a more robust system
- All stakeholders of the system are aligned and there is no confusion or different understanding/opinions about each system requirement
- Anyone with domain knowledge, even if they don’t have technical knowledge about the system, can understand what we are trying to test with this test cases
- The improvement in the quality of code results in reduced costs of maintenance and minimizes the project’s associated risks
The image below describes a simple BDD operation in detail
What is Cucumber Framework?
Cucumber is an open-source software testing tool written in Ruby. Cucumber enables you to write test cases that anyone can easily understand regardless of their technical knowledge.
The Cucumber Framework executes automated acceptance tests written in the “Gherkin” language. Gherkin is a domain-specific language for behaviour descriptions.
Cucumber acts as a bridge between the following teams:
- Business Analysts and Software Engineers
- Manual and Automation Testers
- Manual Testers and Developers
How does Cucumber work?
Cucumber BDD framework mainly consists of three major parts:
- Feature File: Cucumber tests are written in plain text files called feature files stored with the extension – “.feature”. A Feature File can be described to make the documentation more legible. These files describe the behaviour and functionality of the software using the Gherkin syntax. Gherkin defines keywords like Given, When, and Then that are then used to define the steps of a test scenario.
- Step Definitions: Each step in a feature file is associated with a step definition implemented in the code. Step definitions define the actions or operations that must be executed for each step of the test scenario. They map the plain text steps in the feature file to the corresponding code implementation.
- Test Runner File: In Cucumber, the test runner file executes the Cucumber feature files and coordinates the steps defined in those feature files with the corresponding step definitions.
How to write Cucumber test cases:
One can write cucumber tests using the keywords below.
- Create a feature File: Feature files (.feature) are where we write test cases in plain English words, which internally use the keywords mentioned below to highlight different uses cases
- Feature: A feature is a functionality or standalone unit of a software application. Lets understand this with quite basic example of social networking website :
- User registration or delete functionality on social networking website
- User login on social networking website
- Post the video or photos on social networking website
This all are the individual feature on its own, as it represent dedicated functionality of social networking website
- Background: Explain the Background of each test-case. That means, we can have a single Background description for multiple test cases or separate descriptions for each test cases.
- Scenario/Scenario Outline: Highlights the scenario for specific test cases. There is a small difference between a Scenario and a Scenario Outline. A Scenario can be used when we have only one set of data to be tested. In cases of testing in an iterative way with multiple sets of data, we need to use a Scenario Outline. We can also rely on Data Tables, which are also used for testing in an iterative way with multiple set of data.
Each test case contains 3 events: Given, When and Then. This is used to provide inputs and specified interval of time/situation.
- Given: This is the first main event of a test case, which signifies the pre-conditions for a test case and if any externally sourced input data is required.
- When: Follows the Given keyword and its main task is to execute the test case with all required inputs and then stores the result. When thinking about When think about the actual execution of the functionality we want to test.
- Then: Followed the When keyword and its main task is to compare the actual results with expected result. To build the expected result, one needs to pass the required inputs as part of the Then statement and it will compare the actual result with the expected response.
- But: If we have any opposite scenario clubbed with the Then statement, we can use a But statement to describe it.
- And: This is used to add one more scenario inline/synergized with the Then Statement.
- Examples: This is used to provide input parameter names and values. As mentioned in Scenario/Scenario Outline, we can have one set of data or multiple sets of data. All of the input parameters used in Given, When and Then can be mentioned as part of an Examples statement followed with their values.
- Data Tables: To test scenarios with different sets of data, we can also make use of Data Tables.
To understand the above keywords easily, I have written an example where a user wants to register at a social networking website. The test case contains different valid and invalid scenarios. Please refer to it for a better understanding of the Cucumber Test Framework :
Registration.feature
Background : User wants to register on a social networking website
Scenario : User has opened “*****.com” website
Given : User enters personal details like First Name as ‘<First Name>’, Last Name as ‘<Last Name>’, Email Id as ‘<EmailId>’, Mobile Number as ‘<MobileNo>’ and then presses the next button
When : User has entered the password as ‘<password>’ and pressed the register button
Then : User should receive the message as ‘<message>’
And: Add positive condition aligned with Then
But: Opposite condition to Then
Examples:
First Name | Last Name | EmailId | MobileNo | password | message |
Roni | Salt | [email protected] | 12578 | Roni@123 | Password should contain your first or last name |
Abhijit | Chavada | [email protected] | 16790 | Chung@456 | Successfully logged in |
RegistrationStepDef.Java
// This function is linked to .feature file Given Statement. One can change the description within the below @Given statement. The only thing you must make sure you do is to use the correct number of input arguments and its data types.
@Given(“User enters person details like First Name as {string}, Last Name as {string}, Email Id as {string}, Mobile Number as {string} and then presses the next button”)
Public void enterInitialPersonalDetails(String firstName, String lastName, String emailId, String mobileNo)
{
this.firstName = firstName;
this.lastName = lastName;
this.emailId = emailId;
this.mobileNo = mobileNo;
}
// The function below is linked with the When statement from .feature file. Again, one can change the description within @When statement and make sure to match the correct number of input arguments and its data types.
@When(“User enters password as {string} and pressed the register button”)
Public void executeRegistration(String password)
{
this.password = password;
response = processRegistration(firstName, lastName, emaild, mobileNo, password);
}
// The function below is linked with the Then statement from .feature file. Again, one can change the description within @Then statement and make sure to match the correct number of input arguments and its data types.
@Then(“User should receive the message as {string}”)
Public void compareResponse(String message)
{
// if one needs to compare other attributes as well, then we need to process the actual response and then compare it with the expected response passed as arguments.
assertEquals(response.message, message);
}
// We can also add @And and @But same as above and verify the response.
Benefits of using Cucumber as Testing Tools
Involving stakeholders becomes easier regardless of their level of programming knowledge.
- Testers can write Test scripts without having in-depth knowledge of programming
- Supports various programming languages
- Code can be reused
- Simple and quick setup
- Flexible with different software platforms like Selenium, Ruby on Rails, Watir, Spring framework, and so forth
Conclusion :
BDD (Behavioural Driven Development) is a software development approach that was developed from Test Driven Development (TDD), which includes test case development on the basis of the behaviour of features. This test cases are written in plain English word, which is understandable to non-technical human-being and that’s the main pillar of making it difference and reason behind gaining the traction.