Recently I was asked about backing in unit tests into an existing project. In particular I was asked A) was possible and B) is it worth it. In short my answers to both these are Yes and Yes. However, backing in unit tests is not without its challenges. I thought today I would go express my experiences with doing exactly this and what types of hurdles I ran into.
Start off by only testing new code
When backing in tests, it is very important to accept the fact that a large percentage of your application is going to be untested. Accepting this fact will help you move forward. I would suggest that as you write new code (be it new modules, features or whatever) you write them following the TDD practice. This will be the simplest way to get the ball rolling.
Doing this is also an easy way to get other team members on board with the testing idea. I know from personal experience that when we wanted to started following TDD on a project that was 2 years in, many of the other developers thought it was a waste because we have so much that is untested. They thought it would take too much time/effort to write test for existing code. I agree with this. So only test going forward
Add tests to existing code only when changes are needed
I know I just said above to only test new code, and this is true. However, when you are making changes to existing code test those changes. Again, you don't have to try to test all the existing code, only the path ways you are adding/changing.
If you follow this, over time you will start to build a nice suite of tests that tests not only new code, but some existing code as well.
Mock as much as possible
Mocking is a great tool. I like to mock code that I don't have control over, or when I have no faith the code will work reliably. This is especially important in a project that does not have tests.
An example would be this. Lets say you are adding a new feature to an application that needs to call into some sort of calculation engine. Since this calculation engine is not tested and you have no real faith that it will work reliably, mock it. You should know that given a valid set of inputs you expect to receive a given response. By mocking this you remove all risk of the calculation engine failing thus causing your tests to fail.
*** I can hear you now, you want your test to fail when the calculation engine fails.... No you don't. Unless your test is actually testing the calculation engine, you don't care if it passes or fails. You just need to call it. ***
Take this as a learning experience
Take this time as a way to learn to write good solid tests. This will be of great benefit later in your next project. Also, you will also learn how to write better code that is more acceptable to testing (hum... sounds like another good post). Remember, in order to become good at something you must first be bad at it. But with practice you will become better and you will be a better developer because of it.
Testing is painful at first. It is a shift in your development mind set. Be patient, it gets better. This is no different then learning anything else. It will take time, but eventually you will become comfortable with TDD and it will become second nature. You never know, you may end up like me and find it odd when you are NOT writing tests.
I hope this helps.
Till next time,
10-09-2007 7:35 AM