How TDD with Visual Studio can help you improve your code.
- By Jeff Levinson
Test-Driven Development (TDD) is an agile methodology that strives to create cleaner code through short iterations based on testing first, coding new functionality second, and then refactoring to clean up the code without changing the results. Ideally, the end result is higher-quality software. TDD is used with agile dev processes such as eXtreme Programming (XP), but it can also be combined with non-agile methodologies to improve the quality of your code.
The mantra of TDD is "red, green, refactor." In plain English, this means you write a test that fails (red), make the code work doing whatever is needed to get it to work (green), and then refactor it to eliminate duplication and increase efficiency (refactor). This is a continuing cycle because as you refactor you'll more than likely introduce bugs into your code. By its nature, TDD must be automated in order to get rapid feedback so you know almost immediately if your code changes passed or failed.
While TDD can help tremendously in many coding situations, it doesn't work for all development. Examples of this include threading and user interfaces, despite some clever workarounds.
It's important to note that TDD can help you improve your code even if you don't follow a purist's view of the practice. "TDD isn't an absolute the way that XP is," observes XP creator Kent Beck, in his book, "Test-Driven Development: By Example" (Addison-Wesley Professional, 2002). Some TDD purists have issues with Visual Studio's level of support for TDD, but the IDE can be used to automate unit testing, which is at the heart of this methodology.
Writing a test case before you write production code takes a bit of a leap if you haven't done it before. It has a key purpose, though -- it forces you to create a test such that the input and output of the test correspond to an actual business requirement. And it requires you to do this before you've gone and written a bunch of spaghetti code that detracts from what the code should do. The payoff is that when you write the code, if it passes the test you know you've met a requirement and that the code does what it's supposed to do.
TDD in Visual Studio
Visual Studio Team System 2005 for Software Developers and Software Testers introduced unit testing built directly into the IDE. Up until this point you had to use the so-called "xUnit" tools. For .NET, the first tool was nUnit, an open source unit-testing framework ported from jUnit for Java. Unit
testing is such a requested feature in Visual Studio that in the 2008 IDE Microsoft is offering the tools in the Professional Edition. This is a huge win for developers.
How does all this translate into support for TDD? In a perfect implementation you'd write your test, right-click the test code and have it generate both the class and the method that you wrote the test for. Visual Studio doesn't have this level of support. Before writing your test you need to create the class that will contain the method you want to test. In addition, say you have some code which instantiates some object (SalesTaxCalc) and takes the name of a state in the constructor. And you want to test a method called CalculateTax that takes the total amount of the sale and returns the amount of tax. To compile the test you have to select the constructor, hover over the blue bar that appears below the constructor call and select Generate a Method stub (or press Shift + Alt + F10) for the constructor and the CalculateTax methods.
Visual Studio also supports data-driven unit testing that allows you to provide test values from a data store (which can be anything from a text file to SQL Server). It also includes exception-testing support (yes, you have to test for known exceptions, as well).
[click image for larger view]
|The mantra of Test-Driven Development (TDD) is "red, green, refactor."
In this area Visual Studio provides solid support. You can execute unit tests at any time through the Test View or Test Manager windows (depending on your edition of Team System). You can create lists of tests, run just a single test or more than one test. You can use the included MSTest.exe command-line tool to schedule tests or run them outside of the Visual Studio environment.
Whether you take a purist's view and try to write all of your tests first and generate method stubs, or you do it by hand, you should use unit testing. It will increase the quality of your code. TDD takes a bit of work and time
to get used to but has substantial benefits. Also, don't shy away from it because it's an agile methodology. You can use it on formal projects, as well -- it's simply a good software development practice. Give it a try.
Jeff Levinson is the Application Lifecycle Management practice lead for Northwest Cadence specializing in process and methodology. He is the co-author of "Pro Visual Studio Team System with Database Professionals" (Apress 2007), the author of "Building Client/Server Applications with VB.NET" (Apress 2003) and has written numerous articles. He is an MCAD, MCSD, MCDBA, MCT and is a Team System MVP. He has a Masters in Software Engineering from Carnegie Mellon University and is a former Solutions Design and Integration Architect for The Boeing Company. You can reach him at Jeff.Levinson@nwcadence.com.