Software development has transitioned from a waterfall to an Agile approach over the past decade. Since Agile development involves continuous change, testing has become invaluable to prevent these frequent changes from introducing new bugs, or worse, breaking the application in production.
Most developers are familiar with test-driven development, or TDD, but behavior-driven development , or BDD, is often misunderstood. The reality is that both of these approaches have benefits and drawbacks to consider.
In this article, we will look at TDD and BDD, explore the differences, and see how they can work together.
Behavior-driven development is often misunderstood, but it’s merely the evolution of test-driven development.
What Are BDD & TDD?
Test-driven development typically involves writing a test for a certain piece of functionality, running the test to see it fail and then writing the code to make the test pass. That way, developers can be confident that they’ve written code that does the job and other developers reusing components can run the test to be confident that their own code will properly function.
For example, a Ruby on Rails developer might write a test to ensure that an article object cannot be saved without a title attribute:
test "should not save without title" do
article = Article.new
expect { article.save }.to
raise_error(ActiveRecord::RecordInvalid)
end
The developer could add a simple validation to the article model and the test would pass since an error would be thrown when trying to save without a title:
class Article < ApplicationRecord
validates :title, presence: true
end
Behavior-driven development typically involves a developer, test engineer and a product manager (and potentially other stakeholders). The group meets to come up with concrete examples of acceptance criteria in a user story. These examples are described using a domain-specific language, like Gherkin, and put into a feature file. The feature file is converted into an executable specification where developers can then write an actual executable test.
For example, a feature file in Cucumber might describe a user sign in process:
Scenario: User can sign in
Given a valid user with username "hiptest"
When I login as "hiptest"
Then I should see a message "Welcome, hiptest"
The feature is then converted into an executable specification. For example, the When portion of the feature file might look like this in Ruby on Rails:
When /^I login as "(.*)"$/ do |username|
user = User.find_by_username(username)
input(name: 'username').send_keys(user.username)
input(name: 'password').send_keys(user.password)
button(name: 'sign_in').click
end
The developer uses regular expressions to translate the When clause into executable code — the word “Sign in” is assigned to the button variable in the code block and the automation framework (Watir in the example above) will handle the triggering of the web browser.
What’s the Difference?
BDD and TDD may seem very similar since they are both testing strategies for a software application. In both cases, the developer writes the test before writing the code to make the test pass. And in both cases, the tests can be used as part of an automated testing framework to prevent bugs.
[content_upgrade cu_id="4967"]Download our free Checklist of TDD & BDD Frameworks to see what options you can explore: [content_upgrade_button]Click Here[/content_upgrade_button][/content_upgrade]
What You’re Testing
BDD is designed to test an application’s behavior from the end user’s standpoint, whereas TDD is focused on testing smaller pieces of functionality in isolation. In the prior example, the TDD test asserts the result of a specific method, while the BDD test is only concerned about the result of the higher level scenario.
How You’re Testing
BDD involves product managers, developers, and test engineers who collaborate to come up with concrete examples of desirable functionality. There is a high level of communication before any implementation. By comparison, TDD can be done by a solo developer without any external input from product managers or stakeholders.
How They Work Together
It’s important to note that BDD and TDD aren’t mutually exclusive — many Agile teams use TDD without using BDD. However, BDD ensures that most use cases of the application work on a higher level and provide a greater level of confidence.
For example, a development team may use BDD to come up with higher level tests that confirm an application's behavior. When implementing the specifics, developers may create separate unit tests to ensure the robustness of the components, especially since these components may be reused elsewhere across the application.
Rspec is a great example of TDD and BDD principles combined into a single framework for Ruby applications.
The process might start with a plain-text description, similar to Gherkin:
describe Bowling do
context "with no strikes or spares"
it "sums the pin count for each roll" do
end
end
end
Developers can then add TDD elements to test specific objects:
it "sums the pin count for each roll" do
bowling = Bowling.new
20.times { bowling.hit(4) }
expect(bowling.score).to eq(80)
end
The BDD vs. TDD decision depends on the individual organization and the application. If a team is already doing TDD, they may want to experiment with BDD by using it for a small feature to see how it adds value to their process.
Implementation Differences
Test-driven development has been widely adopted by Agile development firms and there are many different tools to help teams get on the same page. Unfortunately, there are fewer tools for behavior-driven development since it involves communication between business and technical teams.
[content_upgrade cu_id="4967"]Don’t forget to download our free Checklist of TDD & BDD Frameworks to see what options you can explore: [content_upgrade_button]Click Here[/content_upgrade_button][/content_upgrade]
HipTest is a BDD test management suite that’s designed to bridge the gap and make continuous testing a lot easier. Easy-to-use scenario editors let business teams easily define and update features, while integrations with automation frameworks and CI/CD pipelines simplify writing the tests.
The plain-text language used in the features and the aggregated data from the integrations helps create a living documentation that can be referenced by technical or business teams anytime. For example, business users can ensure that a certain feature has been developed and still functions as of the latest CI run.
The good news with BDD is that it doesn’t require reworking any existing TDD practices—it only requires an investment in a little more communication that can pay off in the form of less ambiguity and greater confidence in the product.
The Bottom Line
Test-driven development has become the default approach for Agile software development over the past several years. The approach minimizes bugs reaching production and ensures that software can be continuously released without issue.
Behavior-driven development represents an evolution beyond TDD, where business goals can be better communicated to developers. By bridging the gap between business and technical teams, BDD helps reduce any confusion about acceptance criteria, identify potential problems with user stories early, and ensure that the application functions as-expected for end users.
Sign up for a free HipTest trial today if you’re interested in getting started with BDD the right way.