The foundation for all solid professional software development in my opinion is good craftsmanship practices and the most important of them is unit testing. It used to be great debate and controversy about weather unit testing was worth it or not but the fact is, the jury is back and the verdict is final. Unit testing is a core software development practice which can be ignored no longer, for any reason.
Unit testing is a relatively old practice and what has become the definition of a good unit test through decades of practice is the following:
- It’s automated
- It’s repeatable
- It’s easy to implement
- Once its written it sticks around
- Anyone can run it. Easily
- It runs fast
Given this definition there are many ways to produce these unit tests that are so important, but what has proven to be the most efficient way to get them done is to iteratively write a test before you write the production code which should make the test pass. Thus, using test-driven development, not only do you get unit tests written such that you can prove that the application is working as expected, but with test-driven development you get so many other benefits. It’s really about thinking through what your application should do and designing it to be testable which inherently forces you to make it more decoupled and cohesive, two of the oldest software metrics of good design.
With a suite of unit tests in which you trust, you
are much more comfortable doing can do ruthless refactoring. Without tests you can’t. Refactoring is one of the core practices of test-driven development, and it’s all about making changes to the code to keep it flexible in order to make it easier to change and maintain.
When we’re doing test-driven development properly we’re working in very short cycles of writing a little bit of test code, a little bit of production code, and then cleaning up after our selves as we go along. When you do this you want to make sure that all your old tests passes for every change you make as well as only the test case you’re working on is failing as expected. This leads to lots of overhead of clicking buttons in the IDE or pressing short cut keys over and over again. What you really want is a way to run all the tests automatically when ever anything changes. This is where continuous testing comes into play.
Continuous testing as a practice is actually what you do when you’re doing test-driven development properly, however the term has been claimed by a range of tools which was sprung out of the Ruby community. It provides tool support for automatically detecting when you save a code file and then running the entire unit test suite and report the result back to you. Consequently it somewhat changes the way you do test-driven development because you never need to think about running your tests again. You simply keep on coding, adding another test, implementing it and meanwhile the red light has lit up and switched to green again as you’ve made it pass.
It might seem like a subtle change but I’ve found that it really changes and improves the flow when I code, plus using a tool like NCrunch, as a side effect, I get so many other cool features like code coverage and pass or fail status next to every line of code (see the image at the top of the post). NCrunch takes advantage of all the cores in my machine and uses parallel execution to run the entire suite of tests every time. It optimizes the build such that only the modules that are impacted by the change are built and run first so I get immediate feedback plus the rest of the test suite is running behind the scenes for safety.
Continuous testing tools for .NET:
- Mighty Moose
Disclaimer: This is my view on how software development should be practiced in a professional environment. It is my own opinion and do not represent my employer’s view in any way.