Behavior Driven Development (BDD)
http://en.wikipedia.org/wiki/Behavior-driven_development
Let's say I'm going to implement the world's best calculator service
'foobar' which will talk to the super computer 'Param
Padma' to do calculations. Where should I start ?
To start with, we have to identify different features of our service and
then identify independent testable scenarios in each feature. A feature
file might look something similar to this for our awesome 'foobar',
I've been practicing this for a while and it makes development so easy. A close metaphor would be 'swimming with a life jacket on'. Ciao in another post.
~Surya
http://en.wikipedia.org/wiki/Behavior-driven_development
When I joined my team, BDD was the buzz word.
Initially it didn't make sense to me since most of the time I ended up writing
steps to test what I'm going to develop. Aren't unit tests enough to test the
functionality of classes I write ?
Well, I'll think about my design, draw a bunch of
UML diagrams in whiteboard, write my interface, write some unit tests,
implement the interface, make the unit tests pass and hand it over to QA. Now
it's someone else's headache. Then I release the service to public and oops
something is broken. I fix it, hand it over to QA, fix works, release the
patch. Oooops.. it's not even adding two numbers anymore. Customers get pissed
off and eventually your service will go down the drain. Trust me, most
developers would have gone through this vicious and error prone cycle. As a
developer I need some confidence to make code changes, fix bugs, refactor,
optimize. I need a safety net around my code. Writing functional tests is one
way to placate the above scenario. The idea of BDD is to do the development
backwards starting from writing the functional tests.
Feature: Perform arithmatic
operations
As a client of foobar
I should be able to perform
calculations on numbers
So that I can use the results to do
something awesome
Scenario: Add two numbers
Given I have two numbers 1 and 2
When I ask foobar to add the numbers
Then I should get back 3
Scenario: Divide two numbers
When I ask foobar to divide 1 by 0
Then I should get an error saying
"divide by zero"
....
....
If somebody wants to know about what our service does, feature files will
tell them a story. Essentially we enumerate the customer facing functionality
of our service as scenarios. Next, we associate step definitions for each of
the above steps using one of the BDD frameworks. I've tried cucumber. It
is simple and effective. (It is also one of the examples of how not to write
software, but that's a different story in a separate blog)
"Given I have two numbers"
public void I_have_two_numbers(int a, int b)
{
setA(a);
setB(b);
}
"When I ask foo bar to add the numbers"
public void I_ask_foo_bar_to_add_the_numbers()
{
FooBar foobar = MyAwesomeServiceInterface.getFooBarClient();
// This step will actually make calls to 'param padma' and return the sum unlike a mock service.
setSum(foobar.add(getA(), getB()));
}
"Then I should get back"
public void I_should_get_back(int expectedSum)
{
assertEquals(expectedSum, getSum());
}
When we run the test suite, for each step in feature file, the corresponding
step definition will be executed. So what have we gained out of all these?
·
We have clearly defined the functionality of
our service, so there is no room for scope creep during implementation.
·
Before even writing the service we'd know how
painful/easy it is going to be for the users to interact with our service.
· We are implementing what we test and not
testing what we've implemented.
·
The success criteria are crisp. Just make the
steps pass and our service is ready.
·
The quality of code is better since
it is easily maintainable.
~Surya
No comments:
Post a Comment