Quick Example of TDD using NUnit

Following example develop a feature for system using TDD. The feature will count occurrences of a character in a string.
@. Now create a solution and named it FirstTDDExample.
@. Add new Class Library project and name it “FirstTDDExample”
@. Also add another Class Library project and name it “FirstTDDExample.Test”
@. Go to View -> Other Window -> Package Manager Console as follows:
1
@. In Package Manager Console Select “FirstTDDExample.Test” project as Default Project
@. Write following command in “Package Manager Console”-

PM> install-package NUnit

Or you can install a specific version of NUnit as follows:

PM>Install-package NUnit -version 2.6.4

@.After Installation of NUnit add a class inside FirstTDDExample.Test project and name it “UtilitiesTests.cs”
@. Inside this class writes following code:

using NUnit.Framework;

namespace FirstTDDExample.Test
{
    [TestFixture]
    public class UtilitiesTests
    {
        [Test]
        public void ShouldFindOneYInMysterious()
        {
            var stringToCheck = "mysterious";
            var stringToFind = "y";
            var expectedResult = 1;
            var classUnderTest = new StringUtilities();
            var actualResult =
            classUnderTest.CountOccurences(stringToCheck, stringToFind);
            Assert.AreEqual(expectedResult, actualResult);
        }
    }
}

Note: Here we used two attributes [TestFixture] and [Test]. These attribute is provided by “NUnit.Framework” namespace. By [TestFixture] attribute system identifies that the class is Test Class and by [Test] attribute system identifies that the method is Test method.

As we work with Test Driven Development so we wrote Test class and Test method first. Though there is no such class exists with the same name of “StringUtilities” so it will give us error. In order to handle this error we’ll create a class inside “FirstTDDExample” class library project with the same name i.e. StringUtilities.cs as follows:

namespace FirstTDDExample
{
    public class StringUtilities
    {
    }
}

Now write a method inside StringUtilities.cs with the name CountOccurences that will take two parameters i.e. stringToCheck and stringToFind. Inside the method we’ll just throw NotImplementedException. So our complete class definition will be as follows:

public class StringUtilities
{
    public int CountOccurences(string stringToCheck, string stringToFind)
    {
          throw new NotImplementedException();

    }

}

@. Now add the reference of FirstTDDExample project to FirstTDDExample.Test project as follows:

+. Right mouse click on References of “FirstTDDExample.Test” project -> Click on Add Reference as follows:

2

+. Then Select FirstTDDExample project -> Click OK as follows:

3

+. So the reference of “FirstTDDExample” project will be added to “FirstTDDExample.Test” project as follows:

4

Note: Due to adding this reference all public classes and methods will of production code i.e. FirstTDDExample project will available in Test code i.e. FirstTDDExample.Test project.

@. Now Build the project
@. Now we’ll open NUnit Runner. To do that browse we’ll do as follows:

+. Browse http://nunit.org/
+. Click on Download Menu. So following page will appear to you

5

+. Download highlighted .Zip file
+. Extract it.
+. Browse the folder and Go to bin folder
+. Here you will found nunit.exe as follows:

6

+. Double click on it. So NUnitRunner will run as follows:

7

@. Now click on File menu of NUnitRunner -> Open Project as follows:

8
@. Browse the folder and go to your Test Project location i.e. FirstTDDExample.Test -> Then Go to bin/Debug folder. Here you’ll find .dll files. From there select FirstTDDExample.dll as follows:
9
@. Now double click on it or click on Open button. So your test will load into runner as follows:
10
@. Select the Test method and click on Run button as follows:
11
@. After clicking the Run button it will show your Test result as follows:
12
@. Above Red progress bar indicates that your test is failed. And immediate below dialog box gives the message where this test failed. Let’s check what the error message says:
“System.NotImplementedException: The method or operation is not implemented.”
13
@. We didn’t implemented our CountOccurences() method inside StringUtilities that’s why test failed.

@. Now we’ll implement our method as with following code to pass the test:

namespace FirstTDDExample
{
    public class StringUtilities
    {
        public int CountOccurences(string stringToCheck,string stringToFind)
        {
            var stringAsCharArray = stringToCheck.ToCharArray();
            var stringToCheckForAsChar =
            stringToFind.ToCharArray()[0];
            var occuranceCount = 0;
            for (var characterIndex = 0;
            characterIndex < stringAsCharArray.GetUpperBound(0);
            characterIndex++)
            {
                if (stringAsCharArray[characterIndex] ==
                stringToCheckForAsChar)
                {
                    occuranceCount++;
                }
            }
            return occuranceCount;
        }

    }
}

@. Now again build the solution and run the test again by clicking on Run button of NUnit Test runner. Now the test is passed as follows:

Note: You don’t need to Open the Test project into Nunit Test Runner again. Previous opening .dll will work fine.

14

Above code passes the test i.e. works when one instance of character looking inside the target word. To verify that it finds multiple instances we’ll work with another test method as follows:

[Test]
public void ShouldFindTwoSInMysterious()
{
    var stringToCheck = "mysterious";
    var stringToFind = "s";
    var expectedResult = 2;
    var classUnderTest = new StringUtilities();
    var actualResult = classUnderTest.CountOccurences(stringToCheck, stringToFind);
    Assert.AreEqual(expectedResult, actualResult);
}
<pre>
Now if we build our solution and Run the test the second test will fail as follows:
<a href="http://www.codermojam.com/wp-content/uploads/2016/03/151.png"><img src="http://www.codermojam.com/wp-content/uploads/2016/03/151-300x193.png" alt="15" width="300" height="193" class="alignnone size-medium wp-image-1632" /></a>
This test has uncovered a bug in code. The bug is “the for loop is looping through the target string one time fewer than needed  i.e. string length - 1. After the defect has been found, we can fix the code as follows:
<pre style="padding-left: 30px;">
 for (var characterIndex = 0; characterIndex <= stringAsCharArray.GetUpperBound(0); characterIndex++)

Now build the solution and run the test again. Now the test will run as follows:
16
Now think it’s one of our real developments, where requirement changes/arises more frequently. So here also new requirement arises by the business user. They want it the search to be case-insensitive i.e. the algorithm shouldn’t care whether the letters are uppercase or lowercase. So according the rule of TDD we’ll first write the new test that will expresses this requirement. So write following test:

[Test]
public void SearchShouldBeCaseInSenstive()
{
    var stringToCheck = "mySterious";
    var stringToFind = "s";
    var expectedResult = 2;
    var classUnderTest = new StringUtilities();
    var actualResult = classUnderTest.CountOccurences(stringToCheck, stringToFind);
    Assert.AreEqual(expectedResult, actualResult);
}

Then build the solution and run the test again. It will fail as follows:
17
Above image shows that the new requirement doesn’t fulfill by the production code. So we’ll have to update our production codes method i.e. CountOccurences() that fulfill our new test. The updated code is as follows:

var stringAsCharArray = stringToCheck.ToUpper().ToCharArray();
var stringToCheckForAsChar = stringToFind.ToUpper().ToCharArray()[0];

Now build the solution and Run the test again. It will now passed as follows:
18
Now we’ll have to check if any user passes null value to search what will happen. To check null we’ll write another test method as follows:

[Test]
public void ShouldBeAbleToHandleNulls()
{
    string stringToCheck = null;
    var stringToFind = "s";
    var expectedResult = -1;
    var classUnderTest = new StringUtilities();
    var actualResult = classUnderTest.CountOccurences(stringToCheck, stringToFind);
    Assert.AreEqual(expectedResult, actualResult);
}

Now build the project and check whether the test passed or failed. The test is failed due to when user passes null value to check it throws a null reference exception as follows:
19
To avoid such type of exception we’ll apply null check inside our production method as follows:

 if (stringToCheck == null)
        return - 1;

After applying above code if find stringToCheck is null then the method will return -1 otherwise it will execute entire code.
Now build the solution and Run the test again. It passed as follows:

20

Md. Mojammel Haque
Currently working as Lead Team (Application Architecture) at Raven Systems Ltd.

Passion for software development especially agile practices such as TDD & BDD with in depth knowledge of OOP, DDD, CQRS, ES, GoF, SOLID and PoEAA.

Over 6 years of software development experience ASP.NET. Has the ability to understand and transform complex business requirements into software ensuring applications are delivered on time.

Also experience in non Microsoft .NET technologies such as Dapper.Net, Subversion, Structure Map & AngularJs.

339 Total Views 1 Views Today
Test driven Development
Others types of Tests

Leave a Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>