If you wish to boost your performance as a developer by a non-trivial factor then here are three ways to help you achieve this:
- loosely couple
- automate testing
- automate delivery
I saw people -myself included- that started applying these rules and went from being unproductive and frustrated about coding, to being productive and in control of major parts of the code.
If you already apply these three rules, you can skip this post. Or, better yet, leave a comment with your top-3!
Loose-coupling has many advantages: improved re-usability, improved extensibility and less side-effects.
Loose coupling can be achieved easily by organizing code in Modules exposing clean and lean interfaces, and then making sure the inner workings of the modules are kept unaware of each other. Device drivers are a perfect examples of Modules.
It is also a good way to make your code more easily testable!
There are many benefits to unit testing
- (if written well) you can run unit tests automatically, fast and often in order to find mistakes and regressions early.
- improves your design: since you constantly eat your own dog food, you automatically make it better.
- It makes you confident when re-factoring, since it immediately warns you when you introduce errors. You don’t have to leave cr*p code sticking in your application out of fear you might break something without knowing it.
- It helps others understand your code better: other developers can look at the unit tests to know how to use the code themselves.
Test the sunshine and the bug…
You should unit-test -at least- each public method in your code. Using Mock libraries (i.e. jMock, Moq) you can mock dependencies, and you can also test exceptional cases. For instance, you can easily create mockups that throw specific exceptions or return errors when a method is invoked. This makes it especially useful to test error handling in important cases.
Test the sunshine scenario, i.e.: does the typical method invocation work? If you want to test some edge-cases, fine. But please do not try to cover every possible value of every possible parameter (the maintenance of your tests will become a nightmare).
Also, for every bug you encounter, try to write a test to reproduce it. Then work on solving the bug until the test passes. This way you know that a) it’s gone, and b) it won’t return unnoticed.
Also write some (automated!) integration tests to see what happens when you bring all the module code together to form the application you’re constructing.
If you manually have to build, install and configure your software in order to let it execute on the target platform, then you probably will not test it often.
Make sure you do not need manual intervention, except maybe push one button to build, deploy and test. And if you can even automate pushing that button (e.g. by using check-in scripts) then also do that, you will get invaluable feedback.
I guess a lot of people already live by these three (and many more) rules. For those who don’t: I can guarantee you that it will definitely help you forward. Enjoy!