Visual Studio 2010 and unit testing
Unit testing has become a necessity in the world of software development. Incorporating unit testing early and often into your build process can detect new bugs introduced into source code by recent changes from you or other developers. This in turn will produce lower maintenance costs associated with your projects.
This article will explain MSTest, the integrated testing suite introduced in Visual Studio 2010. I'll cover the core attributes that you use to mark the test methods in your test classes. These attributes provide solutions to accomplish common testing tasks such as test setup and break down routines.
I'll also explain Test Driven Development or TDD which is a design methodology that when used properly can add great benefit to your software projects.
Just to be clear, I will start by discussing what a unit test is and what it's not.
A Unit Test IS
An automated unit of code that will invoke methods and change property values on your classes under test then evaluate the state of your objects to see if your code performs as you expect.
A unit of code that should be small in size.
A unit of code that should be easy to write and maintain.
A unit of code that should execute quickly.
A unit of code that who's tests are handled by an automated testing framework.
In this instance we are using MSTest inside of Visual Studio 2010 as our unit testing framework although there are other alternatives which I will list at the end of this article.
A Unit Test IS NOT
A test of the entire system by a QA technician.
Found inside of your production source project.
A piece of code that is dependent upon objects in which you have no control. Some examples include;
A Database system.
A file system.
A network resource.
A third party library in which you don't own the source code.
Test Driven Development
Test driven development is a design methodology in which you write unit tests before implementing the code that is being tested. I know, this seems strange, however, when implemented properly, TDD can greatly benefit the design of your code.
How does it work?
In this multipart series I will explain TDD and related concepts and then follow up with an example project that you can download.
Chances are, you source code is probably contained in one or more class libraries (.DLL projects). These libraries represent components which are made up of classes that define the data and logic of your application.
The idea behind TDD is to write tests that invoke the methods and properties that make up the interface or contract of your class. The contract is made up of the public members of your classes. You are only testing how the objects are intended to be used by the outside world. In this way, you are free to think about the design of your classes from a higher level of abstraction because you aren't concerned about the inner workings of your methods. This concept of information hiding is known as encapsulation. Once you've written a failing test, it's time to develop the code that implements the methods and properties tested so that you can successfully build the tests. The end goal is to have unit tests that pass.
Red, Green, Refactor!
So you have a test project and a class library in a solution and they both build. The test project should contain a reference to the class library that contains the code under test. The test class should contain a method to test some functionality of your class. The test method should be marked with the attribute [TestMethod] MSDN Documentation on [TestMethod] attribute . At this point, we are aiming for a test that fails when you try to run it. When your test fails, you will receive a red error indicator from the MSTest Visual Studio integration window. This is the "Red" in Red, Green, Refactor. Your next step is to implement the class' methods and properties until you can run the unit test and it passes. This is the "Green" state. The last step in the process is to refactor your newly written class. The definition of refactoring from wikipedia is as follows.
Code refactoring is a "disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior", undertaken in order to improve some of the nonfunctional attributes of the software. Typically, this is done by applying a series of "refactorings", each of which is a (usually) tiny change in a computer program's source code that does not modify its functional requirements. Advantages include improved codereadability and reduced complexity to improve the maintainability of the source code, as well as a more expressive internal architecture or object model to improve extensibility.
An important thing to remember when refactoring code is that you don't change the way that the world interacts with your objects, or their interfaces. Refactoring should be applied in small incremental changes to optimize the existing code found in your methods and helper routines. With each iteration, be sure to run your unit tests to make sure you have not broken the functionality of your new class.
Some examples of refactorings are as follows; Try to remove over complicated blocks of code like unnecessary nested if blocks. Try to rename variables to better suite their values. A key benefit to refactoring is your code should be easier to read.
Once you've finished refactoring, simply start the process over. Pick some functionality, write a test that fails, get the test to pass, then refactor the newly written code.
Here are some TDD related links.
MSDN Guidelines for Test-Driven Development
TDD with Visual Studio 2010
I hope I have provided you with a place to start with TDD and MSTest. In part two of this article I plan to implement a full fledged example in c#. Stay tuned.