Click here to Skip to main content
15,881,757 members
Articles / Programming Languages / C#

Test Driven Development(TDD) in C#

Rate me:
Please Sign up or sign in to vote.
4.95/5 (16 votes)
29 Jan 2012CPOL5 min read 93.3K   32   7
Test Driven Development(TDD) in C#

Jan 28, 2012. 7:30 PM

There is such a great buzz about Test Driven Development(TDD) also known as Test First Development(TFD) among the geeks and in the software industry that it's being talked about in blog articles, conferences, code camps and so on and if as a developer you are not doing TDD, you feel like you are doing something wrong and which in fact in the actual sense you are just writing legacy codes, shipping application full of bugs and doing everything wrong.

TDD is very important and is one of the great inventions in programming, it is now considered as one of the best practices in the software development. Doing TDD gives you satisfaction as a developer that you are building applications that are robust and perform what they are meant to do. Obviously code written without tests will definitely generates bugs that will come back and haunt the programmer, thus precious development time will now be wasted on fixing bugs.

TDD is an iteration in which tests are written first and then code to satisfy the tests. It can basically be summarised in four steps:

  1. Designing - This involves analysis and figuring out what is to be done.
  2. Testing - Writing a test to express the design (the test is expected to fail Test Failed because no code has been written yet).
  3. Implementing - This involves writing the production code required to satisfy the test.
  4. Testing - Testing the code to ensure it passesTest Passed(if the test fails, then refactor the code until it passes the test).
To practice TDD, a unit testing framework is needed. Visual Studio 2010 contains unit testing framework known as MSTest. There are other testing frameworks such as nUnit and MbUnit. I am more comfortable with nunit because it has come of age and is more matured. To download nunit, go to the official site, the download contains the required libraries and TestRunners (both console and GUI) needed for doing TDD.
Nunit relies heavily on attributes and assertions. Attributes are used to decorate classes, methods and properties, while assertions are central to unit testing frameworks, nunit has an Assert class with various static methods for doing the real testing.

In this article, the nunit attributes that we will be using are:

  • [TestFixture] - This is used to decorate a class and it indicates that a class contains tests.
  • [Test] - This is used to decorate a method and it indicates that a method is a test.
  • [TestFixtureSetUp] - When a method is decorated with this attribute, it is first executed prior to the execution of any test, usually this method is used for initialization, but if it fails or throws an exception, any other test will not be run in the test class.
  • [TestFixtureTearDown] - is used to decorate method used for cleaning up or freeing up resources in the TestFixture and it is run after all tests have been run.

Now with these pre-requisites known, let's do some coding. Let's create a C# console application with a StringParser class, the class contains a method GetNoofWordsInString that returns the number of words in a string and accepts a string argument.

Since we are doing TDD, we are going to write the test first before writing any code just like what the tenet of TDD says. So let's create a new console project and name it TDDExample, right click the project's solution and add another new project with the name TDDExample.Test the second project will house our test. It is a good practice to always separate the Test-Project from the real Project being tested so as not to muddle up code and so that tests are not deployed as part of an application during deployment.

TDDProjects

Now, let's write our test, right click the TDDExample.Test project and select Add Reference, browse to where you downloaded the nunit framework library to and select nunit.framework.dll also add a reference to the project to be tested in this case TDDExample then now add a new class to the test project and name it SentenceParserTest. This name indicates that it is a test for class SentenceParser. The full code listing of the class is below:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using TDDExample;

namespace TDDExample.Test
{
    [TestFixture]
    public class SentenceParserTest
    {
        SentenceParser sentenceParser;

        [TestFixtureSetUp]
        public void SetupTest()
        {
            sentenceParser = new SentenceParser();
        }

        [Test]
        public void TestGetNoofWordsInString()
        {
            string sentence = "coding is fun";
            // this contains three words, we expect our code to return 3
            var noofWords = sentenceParser.GetNoofWordsInString(sentence);
            Assert.AreEqual(3, noofWords);
        }

        [TestFixtureTearDown]
        public void TearDownTest()
        {
            sentenceParser = null;
        }
    }
} 

Looking at the code, an object of the class SentenceParser was created in the class body, which was now initialized in the TestFixtureSetup, now our test is in the TestGetNoofWordsInString method, just as said earlier it is decorated with Test attribute. Note that all test methods have no return type and do not accept parameters. So we use the AreEqual static method of the Assert class, this helps us test our method's return value with the expected value.

The nunit test framework has both a console and a GUI test runners, but I prefer the GUI test runner. Open the bin folder inside the nunit framework you downloaded and click the nunit.exe application to fire open the test runner. Build the TDDExample.Test and on the file menu of the nunit runner, click open project and locate the your test project built library inside the bin folder.

nunit gui test runner

Now, let's run the test, we expect the test to fail, because we have not yet written the code to implement the GetNoofWordsInString in the TDDExample console application. Clicking the run button in the nunit test runner gives:

test failed

Now let's write code to implement the GetNoofWordsInString in the TDDExample console application:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TDDExample
{
    public class SentenceParser
    {
        public int GetNoofWordsInString(string words)
        {
            int count = 1;
            int nextspaceposition=words.IndexOf(" ") ;
            while (nextspaceposition != -1 && words.Length!=0)
            {
                words = words.Remove(0, nextspaceposition+1);
                count++;
                nextspaceposition = words.IndexOf(" ");
            }
            return count;
        }
    }
}

The code returns the total words in a string passed into the method as parameter. If we now run the test, it will pass. But if in case it does not pass, then further refactoring is done until the code passes.

test failed

The full source code of this article can be downloaded here.

Thus, if the code is changed in future, with the test in place, it is run again to determine if nothing has been broken and that the code still does what it is meant to do.

Mastering TDD takes time, it might be time consuming in the beginning, but the time spent on testing a code is worth it and is better than spending time on fixing bug on an already deployed application.

Happy TDDing !!!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Canada Canada
Software Engineer and Author

Comments and Discussions

 
QuestionYou might be interested in this Visual Studio Extension that helps with Test Driven Development Pin
Friedrich Brunzema31-Dec-14 8:01
Friedrich Brunzema31-Dec-14 8:01 
AnswerRe: You might be interested in this Visual Studio Extension that helps with Test Driven Development Pin
Ayobami Adewole11-Jan-15 22:08
professionalAyobami Adewole11-Jan-15 22:08 
GeneralRe: You might be interested in this Visual Studio Extension that helps with Test Driven Development Pin
guibirow9-Jan-16 14:52
guibirow9-Jan-16 14:52 
GeneralMy vote of 5 Pin
jeramyRR11-Jun-13 22:40
jeramyRR11-Jun-13 22:40 
Questionhaha Pin
Brad Benham2-Feb-12 9:47
Brad Benham2-Feb-12 9:47 
TDD has no ROI.

Put your efforts on sound unit testing and good QA if you are worried about catching errors. TDD will just suck up your time and resources and will show you no love in the end.
AnswerRe: haha Pin
guibirow9-Jan-16 14:58
guibirow9-Jan-16 14:58 
GeneralMy vote of 5 Pin
Hezek1ah30-Jan-12 19:03
Hezek1ah30-Jan-12 19:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.