Test-driven development (TDD) is an advanced technique of using automated unit tests to drive software design in the .NET framework and force the decoupling of dependencies. This practice results in a comprehensive suite of unit tests that can be run at any time to provide feedback that the software is still working. It is a style of programming in which three activities are tightly interwoven: coding, testing (in the form of writing unit tests), and design (in the form of refactoring). In this article, we will focus on the .NET framework to explore the realm of TDD. Let us first delve into unit testing in .NET.
How to start unit testing in .NET
The first tool we need to start unit testing is a testing framework. From Microsoft Visual Studio 2008 Professional or above, built-in Microsoft unit testing framework. We have a couple of open-source frameworks too: NUnit and xUnit.
Before we start writing our tests, we need to decide what public method we want to test, what is the specific scenario and the expected result for that scenario. We may follow the following convention for our test.
public void Method_Scenario_Expectation
Next, we will add the content of the test. A test contains three parts.
- Arrange – setup for the test
- Act – the actual invocation of the method
- Assert – verification of pass/fail condition for the test
We should make sure that we use Assert functions to specify pass/failure functionality. We should verify for method calls as well, otherwise, the test will appear to have passed.
Writing Tests in NUnit 3.0
Test Attribute
The Test Attribute is one way of marking a method inside a TestFixture class as a test.
TestCase Attribute
TestCase Attribute serves the dual purpose of marking a method with parameters as a test method and providing inline data to be used when invoking that method. Here is an example of a test being run three times, with three different sets of data:
[TestCase(12,4,3)] [TestCase(7,6,6)] [TestCase(19,5,2)] public void DivideTest(int n, int d, int q)
Repeat Attribute
Repeat attribute is used on a test method to specify that it should be executed multiple times. If any repetition fails, the remaining ones are not run and a failure is reported.
Timeout Attribute
The Timeout Attribute is used to specify a timeout value in milliseconds for a test case. If the test case runs longer than the time specified it is immediately cancelled and reported as a failure, with a message indicating that the timeout was exceeded.
Assertions
In NUnit 3.0, assertions are written primarily using the Assert. That method takes constraint objects as an argument.
Assert.AreEqual(4, 2+2); Assert.That(2+2, Is.EqualTo(4));
AssertionHelper
Some users prefer a shorter form of assertion than is given by Assert. If you derive your test fixture class from AssertionHelper, the Expect() method may be used instead.
Expect(bool condition, string message, params object[] parms); Expect(actual, EqualTo("Hello"));
Let's code for our.NET test
To make it easy, let's start by testing a component I am working on.
- We will be using Microsoft Visual Studio 2015 with the NUnit framework for unit tests in .NET. First of all, we need to install the NUnit Test Adapter from the Extensions and Updates section in Microsoft Visual Studio.
- In our test project, we will create a test class, called after our class-under-test. For example, if our class is called TaskController, the test class will be called CreateTaskTests, TaskLinkTests and so on.
- We need to add a reference of the class-under-test to our test class.
- We will write a unit test to cover a specific scenario of our application's functionality or to cover for a bug fix.
- We will see if the test fails.
- We will write the production code and will see the test now pass.
- Finally, we will refactor the code to increase clarity and remove duplication.
Skill Levels
Beginner
- Being able to write a unit test before writing the corresponding code.
- Being able to make a code sufficient to make a failing test pass.
Intermediate
- Practicing "test-driven bug fixing" when a defect is found, write a test exposing the defect before correction.
- Being able to decompose a compound program feature into a sequence of several unit tests to be written.
- Knowing and being able to name several tactics to guide the writing of tests.
Expected Benefits
- Many teams report significant reductions in defect rates, at the cost of a moderate increase in initial development efforts.
- The same teams tend to report that these overheads are more than offset by a reduction in efforts in the project's final phases.
- Developers can have peace of mind knowing that defect scenario is well covered by their code when they start working on application enhancements, new features, etc.
- Veteran practitioners report that TDD leads to improved design qualities in the code, for instance improving the metrics of cohesion and coupling.
TDD can improve productivity by minimizing time spent in debugging, reducing the need for manual checking by developers and testers, helps developers maintain focus. TDD is highly recommended if we want to improve confidence in our code and create a living, up-to-date specification. For further insight into TDD, we can read Test Driven Development by Example, by Kent Beck. If you're interested, you can read another blog written on the PHP unit testing framework.
Contributor: Mehedi Zaman, SQA Engineer, Nascenia
More to Explore
The Quest for Knowledge Continues. Fuel Your Curiosity.







