Tuesday, July 9, 2013

Unit testing philosophies - TDD and BDD

I am sure nobody denies the benefits of unit testing. Until 2-3 years ago everybody agreed that unit testing is definitely beneficial for the project, but very few had mechanisms (or tools) in place to do the same.
With Visual studio 2010 and MS Test Unit testing framework in place, it has now become very easy to write and maintain unit test cases within the same solution as your project.
MS Test unit tests can be executed singularly or in a group and the results of the test are available in the Test results window. The test result is actually a file with .trx extension located in 'TestResults' folder inside your project folder. One can easily export the .trx file into an html file by means of a command line utility freely available from codeplex at this location, http://trxtohtml.codeplex.com/
The html file can then be sent over an email, which can be viewed in a browser.

TDD:
Test Driven Development, is a unit testing mechanism wherein a class' methods are tested. Testing philosophy is Fail, code, re-factor. It is important to note that this philosophy reduces the dead or unnecessary code from the project, which means less code and hence less maintenance.
However, TDD approach is more understandable by the developers and is mainly testing the methods of a class. For a non technical PM it is difficult to get all the information from TDD test results. Hence, there remains a disconnect between a PM and the development team.

BDD:
Behavior Driven Development aims at abstracting the testing, one level up from just class methods testing (in TDD) to testing the scenarios. These scenarios can be same as Use cases which everyone is familiar with since UML was introduced. Hence this form of testing is easily understood by BA and PM from the end-user perspective.
One of the popular BDD frameworks for .NET is NSpec which is freely available via the Nuget manager.
Lets go through a sample to understand it better.

I am interested in testing the Account class, which is as below,

class Account
    {
        public double balance { get; set; }

        public int  AccountType { get; set; }


        public Account()
        {          
        }

        public bool CanWithdraw(double withdrawAmount)
        {
            bool bReturn = false;

            if (balance > withdrawAmount)
                bReturn = true;

            return bReturn;
        }
    }

And the BDD tests can be written as follows,
class describe_contexts : nspec
    {
        private Account account;
        void describe_Account()
        {
            context["when withdrawing cash"] = () =>
                {
                    before = () => account = new Account();
                    context["account is in credit"] = () =>
                        {
                            before = () => account.balance = 500;
                            it["the account dispenses cash"] = () => account.CanWithdraw(60).should_be_true();
                        };
                    context["account is overdrawn"] = () =>
                        {
                            before = () => account.balance = -500;
                            it["the account does not dispense cash"] = () => account.CanWithdraw(60).should_be_false();
                        };

                };
        }
    }

And to run this test, type the following command in the Package Manager Console,
PM> nspecrunner <Project name>\bin\debug\<Project name>.dll

You will be surprised to see how easy it is understand the output of this test.

describe contexts
  describe Account
    when withdrawing cash
      account is in credit
        the account dispenses cash
      account is overdrawn
        the account does not dispense cash

Thats it. It is very much readable and understandable by anyone. Which means that these tests can then form the basis for your requirements document which can then be shared with all the project stakeholders.
So now we have the power of integrating the project documents in your solution that can be maintained on the fly.

Hope you'd appreciate this article and going forward, would adopt more and more of BDD in your projects.