Every developer needs to test their code, or have it tested by someone.

I don’t know about you, but I am horrible at testing my own code. Does this mean that I do not need to test my code? Heck, no! It is always best if you do not rely on your end user to test your code. This can end up with a very frustrated user, and your user can lose faith in your ability to get their project done.

“Don’t rely on your end users to test your code. That is a good way to lose a client.”

I can think of several methods you can employ to test your code. This article will explore a few of these methods for testing and talk about the advantages and disadvantages of each.

Why You Should Test Your Code

You already know that you need to test your code prior to putting it into production. Testing is your way of ensuring that the code you have written actually works as expected. It is not enough to check that it works as expected, but also under varying circumstances, and with different inputs. For example, what if someone takes the database offline? Will your code recover gracefully from this exception? Does your code inform the user that there is a problem with the database connection in a friendly, easily understood manner? You can answer all of these questions when you test your code. You need to simulate these exceptions so you can test your exception code.

Testing often helps you improve the quality of your code. As you think about the various scenarios that can go wrong, you start to add additional code to handle these scenarios. This leads to your code being more robust and ultimately more maintainable and user friendly. You will find that taking time to test your code will make you a better programmer in the long run. Your boss and your end users will appreciate the extra effort as well.

Problems with the Develop/Test Cycle

There are a lot of disconnects between the development of code and testing of code. In many cases there is way too much code embedded in the user interface (UI), which makes testing hard because there are just not very good tools for testing user interfaces. It is also hard to determine if all of the code in the UI has actually been tested. A tester has to know all of the inputs to give the UI to have it run all of the code.

This leads to yet another disconnect - there is too much communication required between a developer and the QA person. Sometimes a developer will forget to tell the QA person about a “special” case. In other cases a QA person forgets to tell the developer about something that failed, so it does not get caught and ends up as another bug that will be found later.

Another problem is when a developer thinks they have fixed a bug, only to find out that the fix caused a bug in another part of the program. The QA department may not know to test that other part of the program, which could mean a bug gets shipped to a customer. Or, the QA department thinks it affects other areas, so they end up doing a lot more regression testing than maybe they need to.

How to Test Your Code

You can use many different methods to test your code to ensure you are writing quality code.

  • Use a Quality Assurance (QA) person or company
  • Have your end user test
  • Have a co-worker test
  • Write code to test your code

Of the above listed methods of testing, the first three approaches involve humans while the last one is a more automated approach. Let’s look at these two different approaches to testing code.

The Human Approach

Having a human test your code has a lot of advantages. First off, a human can click on different buttons and test the UI very well. Having different people test your code can be helpful because each person may think of different things to test. In addition, using a human tester will take less time up front to develop your software (since you aren’t writing automated UI testing code).

But just as there are advantages to using humans for testing, there are also disadvantages. As testers find bugs, document them, push them back to you to fix and then they have to go back and re-test, you will find more and more time taken in the long run to test code using humans. Many times prior to testing, someone has to create records in a database, and afterwards get rid of tables, records, or files on disk. This operation takes a lot of time and can have many errors. You also find that the burn-out rate for QA people is very high - this job has a high turnover rate. So there are many downsides to using humans to perform testing.

The Automated Approach

Instead of having a human do all the testing, you should start to use the great testing tools that are available in Visual Studio 2008 to create automated tests. Unit testing has become very prevalent in today’s professional software shops. Unit testing simply means you write a program, or most likely a series of programs, to test each line of code you write to ensure that it operates properly under all circumstances.

While this sounds like a lot of work, and it can be more work up front, you will more than make up that time by avoiding multiple regression tests by a human. You can automate the setup and tear down of databases, files, etc. With the correct architecture you can automate almost all the various inputs a human tester would have to enter by hand.

You will also save the time you normally eat up when you do your own testing by pressing F5 to start Visual Studio, wait for the compile process, click through a half dozen menus to finally get to the point where you want to start testing. As you know, this can sometimes take 15 seconds to a minute depending on how large your application is. Instead, you can run one or two tests in just a couple of seconds. This will add up in saving you many hours over the complete development cycle.

An automated approach has many advantages over a human approach to testing. Automated tests are repeatable as opposed to having a human who might forget to test something. You will end up with more of your code tested. Writing automation code forces you to think of how to test your code while you write it, which will make you write better code. You will also save time on the setup and the tear down of the tests since you can automate those tasks.

The automated approach has disadvantages as well. It does take more time up front to develop tests. Automated tests are only as good as the person that develops the tests. The tools to test user interfaces are not too great at this time without spending a fortune on third-party testing tools. Of course, if you use good N-Tier techniques, MVC, MVP, MVVM or similar design patterns, you shouldn’t have a lot of UI to test anyway.

Which Approach Should You Use?

Should you use automated unit tests or a QA department? I think you need a little of both. You want to create as many automated tests as you possibly can as this will save a lot of regression testing. Then the QA department can focus more on system testing, workflow and ensuring the correct data flows all the way through the application. The QA department can also focus on the UI features that are difficult to automate. A good mix of the two will go a long way toward making your applications much more robust and error free.

Architecting Your Code for Testing

As you code your application you can do a few things to prepare to take advantage of unit testing. Correctly architecting an application will do wonders for reusability, readability, upgradeability, maintainability and testability. Take advantage of the design patterns that exist today such as MVC, MVP, MVVM or derivatives thereof. All of these patterns help you remove code from the user interface layer of your application. In my opinion, removing code from the UI layer is the single best thing you can do to have a well architected, easily testable application.

“Correctly architecting an application will do wonders for reusability, readability, upgradeability, maintainability and testability.”

Your UI code should strive to just call or bind to classes. Each class you write should contain the logic for your application. By moving all application logic into classes you can take advantage of the various unit testing tools in Visual Studio 2008 and 2010. When you combine these classes into assemblies, that will aid not only in testing, but also in reusability.

You should also try to make your methods as small as possible. A method should do one thing and one thing only. This makes testing that method easy as you most likely will only need to write one method to test that method. It is better to have many smaller methods and smaller tests, than one large method with lots of tests against that one method.

You can also use code generation tools for generating your CRUD layer. Almost all business applications employ fairly standard Create, Read, Update and Delete logic. You shouldn’t hand-write this code with all of the tools available today to generate it. And, you don’t generally need to test generated code. If the code generator is good, it will generate bullet proof code every time.

Visual Studio 2008/2010 Testing Tools

Beginning with Visual Studio 2008, Microsoft added unit testing tools to the Professional edition. This means you do not need to purchase the Team System suite to be able to use unit testing. It also means you do not have to use NUnit or some other third-party application for unit testing. You can do unit testing right out of the box. Of course, Visual Studio Team System has many more features, but for basic unit testing, you will find everything you need in the Professional version.

Visual Studio 2008 Professional Edition includes unit testing tools, so there is no excuse to not use it.

Summary

Every developer should employ unit testing as a part of their software development life cycle. Not only will it help you improve the quality of your code, it will save you time and money in the long run. As you focus on architecting your applications for unit testing, you will find that your code will become reusable, maintainable and more robust. Take some time to learn about the unit testing tools built into Visual Studio and you will be on your way to better productivity.