As we have been developing GoldStar, we have used a Test Driven Development (TDD) approach. In a nutshell, this means that we write code that tests our code. In the golden olden days of software development, testing was a painful process that unfortunately was largely beared by the end user. The development team would use the program and make sure that it worked as expected, but identifying every single use path and every single computer configuration was impossible. Even if a team spent 10,000 hours testing their product, they would still have to manually record what they tested and remember to repeat these tests as they made changes to the program.
Using the Microsoft .NET framework and TDD has eliminated these problems. In our development process, we write unit tests. Very simply, a unit test runs a specific piece of code and makes sure the expected result is obtained. Here is an example:
myTestClient = new Client();
//give the client a name
myTestClient.Name.FirstName = "tim";
//make sure the client's name is correct
Assert.AreEqual("tim", myTestClient.Name.FirstName);
Obviously, a typical test is much more complicated and much more comprehensive, but you get the point.
So now we can save this test into a special code file and tell our testing framework (we use NUnit) to run the code. NUnit will run the code and tell us if our test passed. So if we make a change to our code for a Client, we can run this test and make sure we didn't break existing functionality.
Currently, we have 416 unit tests that verify everything from adding a new Vehicle to making sure correct data was saved to the database to writing and reading to disk. Every time we write new code, or modify existing code, we run these unit tests to make sure that everything is still working.
Code coverage tells us what percentage of our code has a unit test written for it. For example, our above unit test would be less than 1% code coverage of the client code. Ideally, we want to be above 85% code coverage. So we write tests that "touch" all the different functions of the code until we get to a desired number of coverage.
Currently, we are above 90% code coverage and strive to maintain that level of coverage. This means that as you begin to use this software, you can feel secure that the quality of the code will remain intact. As we introduce new features or client-specific customizations, we will not break existing code, because our unit tests will tell us that something is wrong before we every ship the update. And as developers, we can spend a lot less time testing, because we don't have to manually test each feature.
We have also solved the multiple configuration problem. I will discuss this in a later post when we talk about how ClickOnce removes the pain of installing software.