Now here is a topic that has been beaten to death in other blog posts but it needs to be on this list.

If somehow you have missed the buzz around Test Driven Development (TDD) it is a great way to drive out the design of your software by writing a consumer of your code (the test) first. This way you design very intuitive and easy to read code. I must stress that TDD is primarily a design methodology NOT primarily a testing methodology. By using TDD you design good code and get unit tests as a side effect.

The key thing is to write a test before you write the implementation:

<Test()> _
Public Sub Save_Should_Assign_Customer_Id()
     dim repository as ICustomerRepository = new CustomerRepository()
     dim customer as new Customer
     customer.FirstName="John"
     cusotmer.LastName="Smith"
     repository.Save(customer)
     Assert.IsTrue(customer.ID <> 0)
End Sub

Now we have a test that does not even compile as the CustomerRepository does not even exist. So let us write a simple implementation:

Public Class CustomerRepository
     Implements ICustomerRepository

     Public Sub Save(customer as Customer) Implements ICustomerRepository.Save()
     End Sub
End Class

Now we have code that compiles so we should run our test and ensure that the test fails. This is an important step as we want to ensure that the test will not pass if nothing happens in our code and also to ensure that our test is not improperly written.

Once the test fails we can go and add some code to make the test pass:

Public class CustomerRepository
     implements ICustomerRepository
      
     private customers as IList(of Customer) = new List(of Customer)
     Public Sub Save(customer as Customer) Implements ICustomerRepository.Save()
              dim maxId as integer
               for each customer as customer in customers
                    if customer.customerId > maxId then maxId = customer.CustomerId
              next
              customer.CustomerId=maxId+1
              customers.Add(Customer)
      End Sub
End Class

When we re-run our test we should have a passing test. We can now go and refactor the code to be a bit more simplified. In this case I am going to take the maxId logic and extract it to its own method:

Public Class CustomerRepository
     Implements ICustomerRepository
      
     Private customers as IList(of Customer) = new List(of Customer)
     Public Sub Save(customer as Customer) Implements ICustomerRepository.Save()
             customer.CustomerId = GetMaxId() + 1
             customers.Add(Customer)
     End Sub

      Private Function GetMaxId()  as integer
               dim maxId as integer
               for each customer as customer in customers
                    if customer.customerId > maxId then maxId = customer.CustomerId
               next
               return maxId
      End Function
End Class

Once this refactoring is done we run the tests again to ensure that our test still passes. This is TDD in its rawest form of Red->Green->Refactor.

Normally I would have written a test for GetMaxId() first to ensure that it behaves properly and then implemented that but I wanted to illustrate the red->green->refactor flow. We could add a test after to ensure GetMaxId() functions properly which is also fine.

There are so many sites, blogs, articles, and videos out there that I just wanted to give a quick overview of TDD. I did not believe people when they said that once you go down the TDD path that you never go back. Well they were right and it is now something I can not develop without.