In writing my recent posts about creating a Ruby on Rails TODO application from the ground up, I felt that I should have been more descriptive in explaining BDD – Behavior Driven Development in how it differs from TDD – Test Driven Development.
Additionally, I think that there is a lot more that can be explained about the entire BDD process and the tools that I use including RSpec, Capaybara and others.
BDD vs. TDD
BDD is a concept or technique for testing that Dan North introduced to the programming community. Some would argue that BDD is a programming philosophy. What BDD did was change the perception of TDD. Focus is placed on the overall behavior of the program from the user point of view.
To fully understand BDD, we must first look at the meaning of TDD. Credit is given to Kent Black for developing TDD. Wikipedia defines TDD “as a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards.” Simply put, TDD means writing a test BEFORE writing the code and you know that the test will fail. Then you write just enough code to pass the test.
The Three Laws of TDD according to UncleBob:
- You are not allowed to write any production code unless it is to make a failing unit test pass.
- You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
- You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Benefits to TDD include:
- Less code when writing only the code needed to pass the test
- Writing tests first cause you to focus on what you want the code to do
- Assists when refactoring by telling you if changes have broken any tests
Ok, so what is the downside? I will say this if you are not doing BDD then you MUST at least use TDD. I do not think that there is a downside to TDD per se, but I feel that with TDD, you will write a lot more tests. If you are properly testing, then you will have tests for all of your methods. Is this a bad thing? Absolutely not. In the end, as long you have tested first, you will benefit. So what is the difference?
BDD is a development process that was created by Dan North to address issues that he had with the TDD process. The testing process changed to thinking about the behavior that was expected or desired and not just writing tests on everything.
With BDD, acceptance tests are written using “User Stories” which can be maintained using sites such as Pivotal Tracker. A user story is written in a couple of ways. I use ISBAT for “I should be able to” when writing my stories. An example would be; “As a User ISBAT create a new task”. Another format or way to think of writing stories is to use “As a [role] I want [feature] so that [benefit]”. Thinking this way and writing stories in this manner is that you think like the end user. This is key for your client. A good user experience will help them to achieve what they want. Think of it in the clients perspective:
As a (company owner) I want (a working e-commerce store) so that (I can make money)
So what is the difference between TDD and BDD? It is how you view setting up your tests. The best definition or description of the difference that I have see comes from a blog article on Killswitch Collective’s site:
“Test::Unit supports a Test Driven Development (TDD) approach, while RSpec implies a Behavior Driven Development (BDD) approach. In TDD, we are usually writing one test per function, leading to many small tests. In TDD, since there is one test per function, we end up writing tests at a core level that end up following the same structure as our code. With a BDD approach, we are using specs as a guide for testing. We are telling a story by describing how a set of functionality should behave, and focus less on the return value of a single method. Think of BDD as a humanized TDD; it is TDD written to use a more English like vocabulary for expressing functionality. BDD makes it easier for other developers to read and understand the code, becoming an additional form of documentation. BDD changes the way we think about testing, since it is more focused on implementing high level specs.”
For BDD, I use RSpec and Capybara which is pretty much the standard for Ruby on Rails BDD testing. RSpec was created by Steven Baker in 2005 to be a BDD testing tool. Rspec is used for testing models and is usually in the following format:
describe ‘Creating Blog Entry’ do context ‘after it is created’ do it ‘has required fields’ do blog.title.present? blog.body.present? end end end
The test reads ‘Creating Blog Entry after it is created it has required fields’ and makes sense what we are doing.
For the actual user interface we use what is called a request spec. For emulating the user experience, we use Capybara written by Jonas Nicklas for testing. From the Capybara website :
“Capybara is a library written in the Ruby programming language which makes it easy to simulate how a user interacts with your application.
Capybara can talk with many different drivers which execute your tests through the same clean and simple interface. You can seamlessly choose between Selenium, Webkit or pure Ruby drivers.”
Here is an example of how we would look at the same scenario but from the user point of view:
As a user ISBAT create a blog entry: ISBAT give it a title ISBAT give it a body
These are behaviors we expect. Underlying these ‘tasks’ in our story is the functionality that we will create, but based on the expected behavior. Lets look at the request spec:
describe ‘Creating Blog Entry’ do it ‘has required fields to fill out’ do visit new_blog_entry_path fill_in ‘Title’, with: ‘My New Post’ fill_in ‘Body’, with: ‘Here is my post content’ click_button ‘Save’ page.should have_content ‘New Blog Entry created’ page.should have_content ‘My New Post’ page.should have_content ‘Here is my post content’ page.should_not have_content ‘Error’ end end
Now you can see the test is written for the expectations a user will have to create a new blog entry. This is same as how the user will create a blog entry. Visit the new blog entry path is where you create a new blog entry. You then fill out the form and click the ’Save’ button. As this is Behavior Driven Development we also express what the expected or desired behavior is. We should see a message that the blog entry was created. We also expect that the entry will be visible after creating it so we expect to see the title and the body content. We also do not want to see an error message. Now we write the code to pass the test. We are not so concerned with all the details that we are going to code to get this resulting behavior but rather we just want to make sure that the experience and the behavior happens. And we only write enough code to pass our test.
Hope this helps clarify BDD a bit.
- TDD/BDD as Architectural Tools (codebetter.com)