Few days ago I started a poll on www.KoffeeKoder.com where I asked which tool do you use for testing your applications. Surprisingly, most of the people are not using any tool for testing. This means that there are more and more applications being developed which are destined to be failed. In this article I will talk about test driven development hoping that more and more developers start using TDD and see how it benefits the application.

Introduction:

Few days ago I started a poll on www.highoncoding.com where I asked which tool do you use for testing your applications. Surprisingly, most of the people are not using any tool for testing. This means that there are more and more applications being developed which are destined to be failed. In this article I will talk about test driven development hoping that more and more developers start using TDD and see how it benefits the application.

What is Test Driven Development?

Test Driven Development means that you do not write a single line of code without first having a failed test. This means that you should only write the code that is necessary to pass the test. An easy way to remember test driven development is by remembering Red, Green and Refactor. Red means that your test should always fail the first time it runs. Green means that the test successfully passed. And finally refactoring is performed to optimize and organize the code.

Testing Frameworks:

It really does not matter which framework you choose since most of them are performing the same thing, testing. I prefer NUnit and MbUnit since they are free and provide good documentation (I will be using MbUnit in this article but again it does not matter which framework you choose).

Application Scenario:

In this article I will be focusing on a Shopping Cart application. We will create a very simple shopping cart and test the shopping basic functionalities.

Ok! So what is the architecture of the application? Show me some classes and stuff!

Unfortunately, we don’t have any classes or even any code yet! That is the beauty of test driven development. Our tests will drive our design.

Creating a Class Library Project for Testing:

You can add a class library project to your solution which will serve the purpose of the testing project. You will need to refer the domain objects library (The library being tested) in your testing project. After that add a reference to the testing framework library in this case that is MbUnit.Framework. If you were using NUnit then it should be NUnit.Framework.

You must also decorate your class with the TestFixture attribute which represents the testing class.

[TestFixture]
    [Author("Mohammad Azam")]
    public class ShoppingCartFixture

Writing Tests:

Before writing our test in the IDE you should always make a list of all the tests that come to your mind. Later when you are implementing the application you will find out that you need more tests then you can add those in the older list.

Let’s start by checking that is the shopping cart is empty. Here is the test that I will write. 

[Test]
        public void TestShoppingCartEmpty()
        {
            ShoppingCart cart = new ShoppingCart();

            // making sure shopping cart is empty!
            Assert.IsTrue(cart.Products.Count == 0);

            // OR

           // Assert.AreEqual(0, cart.Products.Count);
        }

Compile the application and it should fail! This is because the class ShoppingCart does not exist. You just wrote the code the most natural way you can think of right now. And that is the first step in TDD approach. The next thing you should do is to create a class named “ShoppingCart” which has a property named Products.

Here is the implementation of the ShoppingCart class:

public class ShoppingCart
    {
        private IList<Product> _products = new List<Product>();

        public IList<Product> Products
        {
            get { return new ReadOnlyCollection<Product>(_products); }
        } 

Run the test again and it will fail again. This is because the object “Product” does not exist. Now, let’s create the Product class.

public class Product
    {
       public Product() { }
    }

Now, run your test and it will pass. If you go back and check your code then you will realize that you have only written the code that is necessary to make the test pass. Isn’t this super great, you are only writing the required code. No more writing 100 lines of code in which only 5 lines does the actual work. By writing tests we are making design decisions.

This is fun right! Let’s write another test. This time we will check that if we can add an item into the ShoppingCart. So, we write the following test:

[Test]
        public void TestCanAddProductToShoppingCart()
        {
            Product product = new Product();

            ShoppingCart cart = new ShoppingCart();

            cart.AddProduct(product);

            Assert.AreEqual(1, cart.Products.Count);
        }

In the above test I am simply using the AddProduct method of the ShoppingCart to add items into the cart. When you are writing tests also think about the domain logic. The shopping cart can have items and an item will belong to a shopping cart. In the real world this is little more complicated since you have order and orderlines but let’s keep all the complexity out right now. The AddProduct method makes sure that the Item/Product has a reference to the shopping cart.

public void AddProduct(Product product)
        {
            _products.Add(product);
            product.ShoppingCart = this;
        }

Let’s write our final test for this article which is to calculate the total for the ShoppingCart. Here is the test that I would write:

[Test]
        public void TestCalculateShoppingCartTotal()
        {
            ShoppingCart cart = new ShoppingCart();
            cart.AddProduct(new Product(10));
            cart.AddProduct(new Product(15));

            Assert.AreEqual(25, cart.Total);
        }

Run the test and it will fail. First, we don’t have a parameterized constructor for the Product class and also there is no Total property on the Shopping Cart class. So, let’s redesign our application and perform the tests again.

private double _total;

        public double Total
        {
            get { return _total; }
            set { _total = value; }
        }

 public Product(double total)
        {
            _total = total;
        }

This will fix the first problem. Now let’s add a Total field in the ShoppingCart class.

public double Total
        {
            get {

                double total = 0.0;
                IEnumerator<Product> productEnumerator =  _products.GetEnumerator();

                while (productEnumerator.MoveNext())
                {
                    total += productEnumerator.Current.Total;
                }

                return total;
            }
        }

The Total property only has a getter since it calculates the total based on the price of each individual product.

Run the tests again and you will be thrilled to see that all the tests have passed. So, What Have We Learned? We learned that writing tests might be a little time consuming process but it dictates the design of the application and will benefit the application in a long run. 

Conclusion:

In this article we barely touched the tip of the iceberg. There are many different concepts in test driven developments including mock objects, database testing, web services testing, interface testing, functional integration testing etc. I hope to cover most of these subjects in my future articles.

I hope you liked the article! Happy programming!