Say Hello To Behavior Driven Development (BDD) - Part 1

This article describes the natural evolution of BDD from common problems of developers not following TDD properly. It also describes a bit about Domain Driven Design (DDD) and Domain Specific Language (DSL) which are naturally connected with BDD.

Introduction

This is the first part of a two part series of "Say Hello to Behavior Driven Development". This part is going to introduce you to the concept of Behavior Driven Development.

Part 2 consists of a step by step instruction to build an application following Behavior Driven Development.

A Brief History (or Story) of Almost All Developers

Almost all developers like to code more than they write test code. "Let's write the code first and meet the deadline and if time permits or if I feel OK, then I would write some test code" - is a common mindset of almost each and every developer. Interestingly, they all know the benefits of writing test code. Even a large percentage of them knows the benefits of adopting TDD (Test Driven Development) towards the software development life cycle. But still a very few can adopt TDD and continue with it.

Questions that are Raised in the Mind

The question is why developers feel uncomfortable to write test code? Is there any way to overcome this?

Problem with a Real Life Example

Let's try to find the answers to these questions.

Let's assume that Mr. X is a hardcore .NET developer and he is going to develop a web based email program. His development manager or supervisor or product owner has given the specification of the email program like this.

As a product owner, I would like to get an web based email program by which I can compose email on-line and can send email.

Pretty simple specification!

Now, Mr. X tries to follow TDD and he starts to think what could be the possible test cases.

This program should send email if To address is valid.

This program should send email if CC address is valid even if To address is not valid

This program should send email if BCC address is valid even if CC and To address is not valid.

This program should send email even if the subject line is empty.

This program should send email even if the body is empty.

Now after sorting out these 5 points, he begins to think that there might be some more test cases if the option stated in 1, 2 and 3 are altered. Even there might be more test cases if he considers the format of the body of the email (like plain text, rich text or HTML). If the body is HTML, then he needs to think about the HTML encoding things.

The more Mr. X, the hard core .NET developer gives to think to find possible test cases, the more he finds test cases and one point like all other developers he may write few test cases or not any test cases by keeping in mind that -- "I will definitely write test cases once my functionality has been implemented".

But as usual at the end of the day, almost no test cases have been written and the TDD vanishes!

Let's Find the Cure!

So far, we have got the nature of the problem and its symptoms. Now let's start digging out a possible remedy of it.

What if the requirement given by the product owner or supervisor or development manager included the possible behavior of the module. To elaborate and to be more specific, if the requirement is given in such a way that fully expresses the behavior of the module and its possible corner points, then it would be very easy to decide which test cases need to be written and which are not needed.

Researchers have spent lots of time to figure out a possible format of “requirement specification” that is easy to understand to both technical and non technical person. Experts term this type of language as Ubiquitous Language or Domain Specific Language (DSL). I am not going into details of this thing but as I have already mentioned, the purpose of this is to create a bridge between technical and non technical persons.

Nowadays, the word DDD(Domain Driven Design) is very popular and ubiquitous language or DSL is the first ladder of it. If you are interested to learn more about DDD, then please Google the term DDD and enjoy your ride in DDD world!

You must be wondering why I have brought ubiquitous language or DSL in the middle of solving a complex problem of every developer's life? Fortunately, this Common language type is going to solve our problem. You must be wondering how?

There are some good guys who actually developed such a language that can be written by any person regardless of technical background and that can be read and understood by any people on earth. Interestingly, there are some parsers for this language which can parse this plain English to compilable code of your favorite programming language.

Just one rule needs to be followed, whatever you write, use Given-When-Then steps. Confused? It's really very easy. Even I can write it, and I am writing the above requirements using this guideline.

Given that a web based email module has been developed And I am accessing it with proper authentication

When I shall write sender email address in To fieldOr write sender email address in CC filed by not keeping empty the To fieldOr write sender email address in BCC field by not keeping empty either To fieldAnd keeping the subject field non emptyAnd write something in body text area which excepts rich textAnd press or click send button

Then my email will be sent And the event will be logged in log file.

Isn't it easy to write and read and understand? Doesn't it cover and depict all possible test cases? Hey! Isn't it actually writing a documentation of email module to be developed?

I know the answers of the above three questions are all YES! There is a more exciting thing I would like to share with you, but before going into that, let's concentrate on the above specification to extract some more information that we need to know.

As you can see that along with Given-When-Then steps I have used and/or to bridge different specifications or corner points and you can actually add as many as possible of combinations and/or in order to detail your specification. And still, it is completely readable to any human.

Oh! I forgot to mention the name of this language. It is known as Gherkin. You can visit this link to dig out more information regarding this.

Such type of requirement actually depicts how the module would behave once developed and developer can concentrate more on behaviour rather than writing test cases. Such phenomenon are termed as Behaviour Driven Development (BDD) and I am pretty sure you have understood the basic concept of BDD by now.

There are some tools (free of course) available that can actually parse specification written in Gherkin and can create test cases in your favorite language and isn’t it enough to trigger 'SayWOW' event .

To implement BDD for .NET, I have found Specflow to be a cool tool that can be integrated with Visual Studio (even it supports VS 2010!). If you Google for more tools, you will definitely find more!

For Java, I have found JBehave to serve the purpose. But again, by Googling, you will get a hell of a lot of tools.

In the second part, I shall show you how you can implement BDD step by step in a .NET project.

Share

About the Author

I am truly versatile and 360 degree Engineer having wide range of development experience in .NET and Java Platform. I am also proficient in system level programming in C++. To me technology is not at all a problem, it’s the client requirement that matters! That is I am ready and comfortable to use any technology to make the business of my client a success.

In my five years of experience I have the opportunities to work for fortune 500 companies of US and many renowned clients from Europe.

Comments and Discussions

Great article for those who venture into writing detailed functional documents. Just to share with you, I've been fortunate enough to have received the functional documents with all possibilities included against every activity/function in my earlier years as a developer. Now whenever I am part of a project for which the aforementioned document does not contain those specifics, I explicitly envision the possibilities and work accordingly. - Pawan

I am not saying the article is bad... but you present the situation like programmers don't like test code because they want to finish dead-lines.
Well... that usually happens, but because someone else is not giving enough time.

On the other side, I see that many Test-Driven-Development methods don't get the real errors and tend to lose time testing things exactly as they should work (not that it is useless... but the real problem are the rare errors, not the visible ones).

I see that many Test-Driven-Development methods don't get the real errors and
tend to lose time testing things exactly as they should work (not that it is
useless... but the real problem are the rare errors, not the visible ones).

you are confusing two distinct phases of development by combining them together, which are development and debug. TDD is primarily useful for development. From this process you should expect clearer, more focused implementations, that are testable and correct solutions with a minimal implementation.

The unit tests that were created during the development phase can now be used during debug as your safety net, regression tests. Yes, there may be additional defects to correct during debug. As you change the code to account for these defects, you are back in a mini-development cycle. Therefore, add an additional test to catch this new case, then modify the code. If any if your previous tests failed, you know you have made a poor change.

without a set of working tests, finding the correct solution could be more like stumbling upon the right solution. You cannot be certain you have made the correct change unless you run through every possible test each time you make a change. TDD is simply a disciplined way to guide you to the correct implementation.

In fact, the idea of not "regressing" is really good. And that's why I am OK with the idea of doing Unit Tests for complex situations.
What I disagree in TDD is doing tests for the most obvious things. And, in fact, it is very probably that if you can write obvious code wrong, you can also write the tests wrong.

In Wikipedia, there's this shortcoming: "Unit tests created in a test-driven development environment are typically created by the developer who is writing the code being tested. The tests may therefore share the same blind spots with the code: If, for example, a developer does not realize that certain input parameters must be checked, most likely neither the test nor the code will verify these input parameters. If the developer misinterprets the requirements specification for the module being developed, both the tests and the code will be wrong, as giving a false sense of correctness." And I completely agree with this particular shortcoming.

I don't remember the name, but there's something like "Error Driver Development" where we create tests for things that went wrong. This can be done in TDD too, but TDD usually has much more tests than I think it's worth (for small cases, the tests can take up to 10x the development time [and code] than the actual development... it will be better to use such time doing something else).

I agree with your comments above and the shortcoming you mention is valid.

Therefore it should be strongly noted that no process yet exists that is fool-proof for creating correct software. Writing quality software still requires a competent engineer. TDD should be viewed as a process that can help you achieve quality software. TDD may benefit from adding other methodologies like "Error Driven Development".

I think a minimal set of trivial test cases are important to verify the base set of code is functioning properly. Just like your implementation, you don't want to add any more tests than are necessary. Because in the scenario you mention, yes, the developer will need to rework all of the tests that were based on a false assumption.

One final thought:

Paulo Zemek wrote:

Unit tests created in a test-driven development environment are typically
created by the developer who is writing the code being tested

Unit tests are a tool solely for the developers.

The test harness environment is for the developer to quickly work with their code, independent of as many dependencies as possible. When they are fairly certain their code is correct, it can be integrated and tested within the entire system.

When written with a unit-test framework that can be automated, these tests can be leveraged at release time as regression tests. But these tests alone do not prove a product is complete or correct. Therefore they should not be viewed as a replacement for a formal qualification process performed by someone other than the developers. The software qualification team may create their own set of automated tests, however, they are not performed at the unit level. They will be performed at the component and system level.

Testing seems to be a very debated topic, almost as much as what language is the best. I'm still searching for effective ways to articulate how testing can be performed. I think it's safe to say, that there is not one way that fits every environment.

Thank you for your reply. You got me interested now. When I do coding I do it the hard way. I just start and do alot of research. I'm going to learn more about it. Can't wait til you teach us more about this topic. I gave you five stars but it deserves a 10.